public bool ChopPlayer(LogicJack chopper, LogicJack another)
    {
        if (!chopper.ValidChopRange(another.x, another.y))
        {
            return(false);
        }

        int dirx = another.x - chopper.x;
        int diry = another.y - chopper.y;

        int ac_remain    = chopper.ac;
        int priorityLock = 0;

        if (onPlayerTryChop != null)
        {
            onPlayerTryChop(chopper, ref ac_remain, ref dirx, ref diry, ref priorityLock);
        }

        if (dirx == 0 & diry == 0)
        {
            return(false);
        }

        if (ac_remain < 0)
        {
            return(false);
        }
        chopper.ac = ac_remain;
        another.BeingChop(chopper);

        if (onPlayerChopDone != null)
        {
            int zero = 0;
            onPlayerChopDone(chopper, ref zero);
        }

        return(true);
    }
    public bool ChopTree(LogicJack jack, int x, int y, out List <LogicTree> domino)
    {
        domino = null;

        if (!jack.ValidChopRange(x, y))
        {
            return(false);
        }

        if (!ValidIndex(x, y))
        {
            Debug.LogError("wtf ? x,y= " + x + "," + y);
            return(false);
        }

        int dirx = x - jack.x;
        int diry = y - jack.y;

        int ac_remain    = jack.ac - 1; // default cost = 1;
        int priorityLock = 0;

        if (onPlayerTryChop != null)
        {
            onPlayerTryChop(jack, ref ac_remain, ref dirx, ref diry, ref priorityLock);
        }

        if (dirx == 0 & diry == 0)
        {
            return(false);
        }

        if (ac_remain < 0)
        {
            return(false);
        }

        var tree = cellControl[x, y];

        if (!ChopTree2(jack, tree))
        {
            return(false);
        }

        //tree chop succeeded
        jack.ac = ac_remain;
        domino  = new List <LogicTree>();

        for (int i = x + dirx, j = y + diry; i < gridX & i >= 0 & j < gridY & j >= 0; i += dirx, j += diry)
        {
            var t = cellControl[i, j];
            if (t != null)
            {
                if (!ChopTree2(jack, t, false))
                {
                    break;
                }
                domino.Add(t);
                if (!t.PassDomino())
                {
                    break;
                }
            }
            else
            {
                break;
            }
        }

        int earned_point = jack.EstimateEarnedPoints(tree, domino);

        tree.AfterChop(jack, ref earned_point);
        foreach (var _t in domino)
        {
            _t.AfterChop(jack, ref earned_point);
        }

        if (onPlayerChopDone != null)
        {
            onPlayerChopDone(jack, ref earned_point);
        }

        jack.points += earned_point;

        return(true);
    }