示例#1
0
    public static bool Present(GoBangBoard.StoneSet ss)
    {
        // The pattern is .????. with "." position fixed.
        if (ss.stones[0] != 0 || ss.stones[5] != 0)
        {
            return(false);
        }

        // Now the middle three (index 2, 3, 4, 5) have to be tested, there
        // should only be two white stones.
        int countWhite = 0;
        int countHole  = 0;

        CountStones(ss, out countWhite, out countHole);
        if (countWhite != 2 || countHole != 4)
        {
            return(false);
        }

        // The "three with 3 reply moves" condition: "s_2 either minimum or
        // maximum in { s_2, s_3, s_4, s_5 }".
        //
        // This is a bit ambiguous, because it does not say anything else
        // about the other values s_3, s_4, s_5.
        //
        // This most likely means that there should not be two empty stones in
        // the middle: .o..o., but it must be either .oo..., ...oo., .o.o..,
        // ..o.o. or ..oo..
        if (ss.stones[2] == 0 && ss.stones[3] == 0)
        {
            return(false);
        }

        return(true);
    }
    private static bool IsLastOperatorDependent(GoBangBoard.StoneSet ss,
                                                GBOperator last)
    {
        // Special case for root node
        if (last == null)
        {
            return(true);
        }

        int px = ss.x, py = ss.y;

        for (int n = 0; n < ss.stones.Length; ++n)
        {
            // Now check if it could theoretically depend.  Then the
            // last operator must have touched (fAdd) stones available
            // in this stoneset.
            for (int k = 0; k < last.fAdd.GetLength(0); ++k)
            {
                if (last.fAdd[k, 0] == px && last.fAdd[k, 1] == py)
                {
                    return(true);
                }
            }
            py += ss.ay;
            px += ss.ax;
        }

        return(false);
    }
示例#3
0
    public static GBOperatorThree2[] GetOperatorsIfValid
        (GoBangBoard.StoneSet ss)
    {
        if (Present(ss) == false)
        {
            return(null);
        }

        // Operator is valid, lets produce it (only one variant)
        GBOperatorThree2 three2 = new GBOperatorThree2();

        three2.fAdd = new int[3, 3];
        for (int n = 2; n < (ss.stones.Length - 2); ++n)
        {
            if (ss.stones[n] != 0)
            {
                continue;
            }

            three2.fAdd[0, 0] = ss.x + n * ss.ax;
            three2.fAdd[0, 1] = ss.y + n * ss.ay;
            three2.fAdd[0, 2] = 1;
        }

        // Two defending moves (s_2 and s_6, index 1 and 5)
        three2.fAdd[1, 0] = ss.x + 1 * ss.ax;
        three2.fAdd[1, 1] = ss.y + 1 * ss.ay;
        three2.fAdd[1, 2] = -1;

        three2.fAdd[2, 0] = ss.x + 5 * ss.ax;
        three2.fAdd[2, 1] = ss.y + 5 * ss.ay;
        three2.fAdd[2, 2] = -1;

        return(new GBOperatorThree2[] { three2 });
    }
示例#4
0
    public static GBOperatorStraightFour[] GetOperatorsIfValid
        (GoBangBoard.StoneSet ss)
    {
        if (Present(ss) == false)
        {
            return(null);
        }

        // Operator is valid, lets produce it (only one variant)
        GBOperatorStraightFour sfour = new GBOperatorStraightFour();

        sfour.fAdd = new int[1, 3];
        for (int n = 1; n < (ss.stones.Length - 1); ++n)
        {
            if (ss.stones[n] != 0)
            {
                continue;
            }

            sfour.fAdd[0, 0] = ss.x + n * ss.ax;
            sfour.fAdd[0, 1] = ss.y + n * ss.ay;
            sfour.fAdd[0, 2] = 1;
        }

        return(new GBOperatorStraightFour[] { sfour });
    }
示例#5
0
    public static bool Present(GoBangBoard.StoneSet ss)
    {
        /*Console.Write ("three ({0},{1}): ", ss.x, ss.y);
         * foreach (int a in ss.stones)
         *      Console.Write ("{0}", a == 1 ? "O" : (a == 0 ? "." : "X"));
         * Console.WriteLine ();*/

        // The pattern is ..???.., with "." position fixed, so we can
        // early-check on this now.
        if (ss.stones[0] != 0 || ss.stones[1] != 0 ||
            ss.stones[5] != 0 || ss.stones[6] != 0)
        {
            return(false);
        }

        // Now the middle three (index 2, 3, 4) have to be tested
        int countWhite = 0;
        int countHole  = 0;

        CountStones(ss, out countWhite, out countHole);
        if (countWhite != 2 || countHole != 5)
        {
            return(false);
        }

        return(true);
    }
示例#6
0
    public static GBOperatorFive[] GetOperatorsIfValid
        (GoBangBoard.StoneSet ss)
    {
        if (Present(ss) == false)
        {
            return(null);
        }

        // Operator is valid, lets apply it.
        GBOperatorFive five = new GBOperatorFive();

        five.fAdd = new int[1, 3];
        for (int n = 0; n < ss.stones.Length; ++n)
        {
            if (ss.stones[n] != 0)
            {
                continue;
            }

            five.fAdd[0, 0] = ss.x + n * ss.ax;
            five.fAdd[0, 1] = ss.y + n * ss.ay;
            five.fAdd[0, 2] = 1;
        }

        return(new GBOperatorFive[] { five });
    }
示例#7
0
    public static bool Present(GoBangBoard.StoneSet ss)
    {
        // The pattern is .????. with "." position fixed.
        if (ss.stones[0] != 0 || ss.stones[5] != 0)
        {
            return(false);
        }

        // Now the middle three (index 2, 3, 4, 5) have to be tested, there
        // should only be two white stones.
        int countWhite = 0;
        int countHole  = 0;

        CountStones(ss, out countWhite, out countHole);
        if (countWhite != 2 || countHole != 4)
        {
            return(false);
        }

        // Now, the broken three condition: "s_4 neither minimum nor maximum
        // in { s_2, s_3, s_4, s_5 }", where s_4 = s_5 = ., s_2 = s_3 = o.
        //
        // This is a bit ambiguous, because it does not say anything else
        // about the other values s_2, s_3, s_5.

        // Case 1: .o..o.
        if (ss.stones[2] == 0 && ss.stones[3] == 0)
        {
            return(true);
        }

        // Case 2: .o.o..
        if (ss.stones[2] == 0 && ss.stones[4] == 0)
        {
            return(true);
        }

        // Case 3: ..o.o.
        if (ss.stones[1] == 0 && ss.stones[3] == 0)
        {
            return(true);
        }

        // Case 4: .oo... and ...oo.
        if ((ss.stones[1] == 1 && ss.stones[2] == 1) ||
            (ss.stones[3] == 1 && ss.stones[4] == 1))
        {
            return(true);
        }

        return(false);
    }
示例#8
0
    public static bool Present(GoBangBoard.StoneSet ss)
    {
        int countWhite = 0;
        int countHole  = 0;

        CountStones(ss, out countWhite, out countHole);
        if (countWhite != 3 || countHole != 2)
        {
            return(false);
        }

        return(true);
    }
    public static void CountStones(GoBangBoard.StoneSet ss,
                                   out int white, out int hole)
    {
        white = hole = 0;

        for (int n = 0; n < ss.stones.Length; ++n)
        {
            if (ss.stones[n] == 1)
            {
                white += 1;
            }
            else if (ss.stones[n] == 0)
            {
                hole += 1;
            }
        }
    }
示例#10
0
    public static GBOperatorFour[] GetOperatorsIfValid
        (GoBangBoard.StoneSet ss)
    {
        if (Present(ss) == false)
        {
            return(null);
        }

        // Operator is valid, lets apply two variations
        GBOperatorFour four1 = new GBOperatorFour();
        GBOperatorFour four2 = new GBOperatorFour();

        four1.fAdd = new int[2, 3];
        four2.fAdd = new int[2, 3];
        int hole = 0;

        for (int n = 0; n < ss.stones.Length; ++n)
        {
            if (ss.stones[n] != 0)
            {
                continue;
            }

            four2.fAdd[hole, 0] = four1.fAdd[hole, 0] = ss.x + n * ss.ax;
            four2.fAdd[hole, 1] = four1.fAdd[hole, 1] = ss.y + n * ss.ay;

            if (hole == 0)
            {
                four1.fAdd[0, 2] = 1;
                four2.fAdd[0, 2] = -1;

                hole += 1;
            }
            else
            {
                four1.fAdd[1, 2] = -1;
                four2.fAdd[1, 2] = 1;
            }
        }

        return(new GBOperatorFour[] { four1, four2 });
    }
示例#11
0
    public static bool Present(GoBangBoard.StoneSet ss)
    {
        // The pattern is .????. with "." position fixed.
        if (ss.stones[0] != 0 || ss.stones[5] != 0)
        {
            return(false);
        }

        // Now the middle three (index 2, 3, 4) have to be tested
        int countWhite = 0;
        int countHole  = 0;

        CountStones(ss, out countWhite, out countHole);
        if (countWhite != 3 || countHole != 3)
        {
            return(false);
        }

        return(true);
    }
示例#12
0
    public static GBOperatorThree3[] GetOperatorsIfValid
        (GoBangBoard.StoneSet ss)
    {
        if (Present(ss) == false)
        {
            return(null);
        }

        // Case A: ..oo..
        if (ss.stones[1] == 0 && ss.stones[4] == 0)
        {
            // Operator is valid, lets produce it (two variants)
            GBOperatorThree3 three31 = new GBOperatorThree3();
            GBOperatorThree3 three32 = new GBOperatorThree3();

            three31.fAdd = new int[4, 3];
            three32.fAdd = new int[4, 3];

            int hole = 0;
            for (int n = 1; n < (ss.stones.Length - 1); ++n)
            {
                if (ss.stones[n] != 0)
                {
                    continue;
                }

                three31.fAdd[hole, 0] = three32.fAdd[hole, 0] = ss.x + n * ss.ax;
                three31.fAdd[hole, 1] = three32.fAdd[hole, 1] = ss.y + n * ss.ay;

                if (hole == 0)
                {
                    three31.fAdd[0, 2] = 1;
                    three32.fAdd[0, 2] = -1;

                    hole += 1;
                }
                else
                {
                    three31.fAdd[1, 2] = -1;
                    three32.fAdd[1, 2] = 1;
                }
            }

            // Two defending moves (s_1 and s_6, index 0 and 5)
            three31.fAdd[2, 0] = three32.fAdd[2, 0] = ss.x;
            three31.fAdd[2, 1] = three32.fAdd[2, 1] = ss.y;
            three31.fAdd[2, 2] = three32.fAdd[2, 2] = -1;

            three31.fAdd[3, 0] = three32.fAdd[3, 0] = ss.x + 5 * ss.ax;
            three31.fAdd[3, 1] = three32.fAdd[3, 1] = ss.y + 5 * ss.ay;
            three31.fAdd[3, 2] = three32.fAdd[3, 2] = -1;

            return(new GBOperatorThree3[] { three31, three32 });
        }
        else if ((ss.stones[2] == 0 && ss.stones[4] == 0) ||
                 (ss.stones[1] == 0 && ss.stones[3] == 0))
        {
            // Case B & C: .o.o.. and ..o.o.
            // TODO
            GBOperatorThree3 three3 = new GBOperatorThree3();

            three3.fAdd = new int[4, 3];

            int stoneCount = 0;
            int pCell      = 0;
            for (int n = 1; n < (ss.stones.Length - 1); ++n)
            {
                if (ss.stones[n] != 0)
                {
                    stoneCount += 1;

                    continue;
                }

                three3.fAdd[pCell, 0] = ss.x + n * ss.ax;
                three3.fAdd[pCell, 1] = ss.y + n * ss.ay;

                if (stoneCount == 1)
                {
                    three3.fAdd[pCell, 2] = 1;
                }
                else
                {
                    three3.fAdd[pCell, 2] = -1;
                }

                pCell += 1;
            }

            // Two defending moves (s_1 and s_6, index 0 and 5)
            three3.fAdd[2, 0] = ss.x;
            three3.fAdd[2, 1] = ss.y;
            three3.fAdd[2, 2] = -1;

            three3.fAdd[3, 0] = ss.x + 5 * ss.ax;
            three3.fAdd[3, 1] = ss.y + 5 * ss.ay;
            three3.fAdd[3, 2] = -1;

            return(new GBOperatorThree3[] { three3, });
        }
        else if (ss.stones[3] == 0 && ss.stones[4] == 0)
        {
            // Case D: .oo...
            GBOperatorThree3 three3 = new GBOperatorThree3();

            three3.fAdd = new int[4, 3];

            three3.fAdd[0, 0] = ss.x + 3 * ss.ax;
            three3.fAdd[0, 1] = ss.y + 3 * ss.ay;
            three3.fAdd[0, 2] = 1;

            three3.fAdd[1, 0] = ss.x + 4 * ss.ax;
            three3.fAdd[1, 1] = ss.y + 4 * ss.ay;
            three3.fAdd[1, 2] = -1;

            // Two defending moves (s_1 and s_6, index 0 and 5)
            three3.fAdd[2, 0] = ss.x;
            three3.fAdd[2, 1] = ss.y;
            three3.fAdd[2, 2] = -1;

            three3.fAdd[3, 0] = ss.x + 5 * ss.ax;
            three3.fAdd[3, 1] = ss.y + 5 * ss.ay;
            three3.fAdd[3, 2] = -1;

            return(new GBOperatorThree3[] { three3, });
        }
        else if (ss.stones[1] == 0 && ss.stones[2] == 0)
        {
            // Case E: ...oo.
            GBOperatorThree3 three3 = new GBOperatorThree3();

            three3.fAdd = new int[4, 3];

            three3.fAdd[0, 0] = ss.x + 2 * ss.ax;
            three3.fAdd[0, 1] = ss.y + 2 * ss.ay;
            three3.fAdd[0, 2] = 1;

            three3.fAdd[1, 0] = ss.x + 1 * ss.ax;
            three3.fAdd[1, 1] = ss.y + 1 * ss.ay;
            three3.fAdd[1, 2] = -1;

            // Two defending moves (s_1 and s_6, index 0 and 5)
            three3.fAdd[2, 0] = ss.x;
            three3.fAdd[2, 1] = ss.y;
            three3.fAdd[2, 2] = -1;

            three3.fAdd[3, 0] = ss.x + 5 * ss.ax;
            three3.fAdd[3, 1] = ss.y + 5 * ss.ay;
            three3.fAdd[3, 2] = -1;

            return(new GBOperatorThree3[] { three3, });
        }
        else
        {
            throw (new ApplicationException("BUG in Three3, uncatched case"));
        }
    }
示例#13
0
    public static GBOperatorBrokenThree[] GetOperatorsIfValid
        (GoBangBoard.StoneSet ss)
    {
        if (Present(ss) == false)
        {
            return(null);
        }

        // Case 1
        if (ss.stones[2] == 0 && ss.stones[3] == 0)
        {
            // Operator is valid, lets produce it (two variants)
            GBOperatorBrokenThree bthree1 = new GBOperatorBrokenThree();
            GBOperatorBrokenThree bthree2 = new GBOperatorBrokenThree();

            bthree1.fAdd = new int[4, 3];
            bthree2.fAdd = new int[4, 3];

            int hole = 0;
            for (int n = 1; n < (ss.stones.Length - 1); ++n)
            {
                if (ss.stones[n] != 0)
                {
                    continue;
                }

                bthree1.fAdd[hole, 0] = bthree2.fAdd[hole, 0] = ss.x + n * ss.ax;
                bthree1.fAdd[hole, 1] = bthree2.fAdd[hole, 1] = ss.y + n * ss.ay;

                if (hole == 0)
                {
                    bthree1.fAdd[0, 2] = 1;
                    bthree2.fAdd[0, 2] = -1;

                    hole += 1;
                }
                else
                {
                    bthree1.fAdd[1, 2] = -1;
                    bthree2.fAdd[1, 2] = 1;
                }
            }

            // Two defending moves (s_1 and s_6, index 0 and 5)
            bthree1.fAdd[2, 0] = bthree2.fAdd[2, 0] = ss.x;
            bthree1.fAdd[2, 1] = bthree2.fAdd[2, 1] = ss.y;
            bthree1.fAdd[2, 2] = bthree2.fAdd[2, 2] = -1;

            bthree1.fAdd[3, 0] = bthree2.fAdd[3, 0] = ss.x + 5 * ss.ax;
            bthree1.fAdd[3, 1] = bthree2.fAdd[3, 1] = ss.y + 5 * ss.ay;
            bthree1.fAdd[3, 2] = bthree2.fAdd[3, 2] = -1;

            return(new GBOperatorBrokenThree[] { bthree1, bthree2 });
        }

        // Case 4:
        // .oo...
        if (ss.stones[1] == 1 && ss.stones[2] == 1)
        {
            GBOperatorBrokenThree bthree = new GBOperatorBrokenThree();

            bthree.fAdd = new int[4, 3];

            bthree.fAdd[0, 0] = ss.x + 0 * ss.ax;
            bthree.fAdd[0, 1] = ss.y + 0 * ss.ay;
            bthree.fAdd[0, 2] = -1;

            bthree.fAdd[1, 0] = ss.x + 5 * ss.ax;
            bthree.fAdd[1, 1] = ss.y + 5 * ss.ay;
            bthree.fAdd[1, 2] = -1;

            bthree.fAdd[2, 0] = ss.x + 3 * ss.ax;
            bthree.fAdd[2, 1] = ss.y + 3 * ss.ay;
            bthree.fAdd[2, 2] = -1;

            bthree.fAdd[3, 0] = ss.x + 4 * ss.ax;
            bthree.fAdd[3, 1] = ss.y + 4 * ss.ay;
            bthree.fAdd[3, 2] = 1;

            return(new GBOperatorBrokenThree[] { bthree });
        }
        else if (ss.stones[3] == 1 && ss.stones[4] == 1)
        {
            // and ...oo.
            GBOperatorBrokenThree bthree = new GBOperatorBrokenThree();

            bthree.fAdd = new int[4, 3];

            bthree.fAdd[0, 0] = ss.x + 0 * ss.ax;
            bthree.fAdd[0, 1] = ss.y + 0 * ss.ay;
            bthree.fAdd[0, 2] = -1;

            bthree.fAdd[1, 0] = ss.x + 5 * ss.ax;
            bthree.fAdd[1, 1] = ss.y + 5 * ss.ay;
            bthree.fAdd[1, 2] = -1;

            bthree.fAdd[2, 0] = ss.x + 2 * ss.ax;
            bthree.fAdd[2, 1] = ss.y + 2 * ss.ay;
            bthree.fAdd[2, 2] = -1;

            bthree.fAdd[3, 0] = ss.x + 1 * ss.ax;
            bthree.fAdd[3, 1] = ss.y + 1 * ss.ay;
            bthree.fAdd[3, 2] = 1;

            return(new GBOperatorBrokenThree[] { bthree });
        }

        // Case 2 and 3
        //
        // Only one variation exist:
        // .o.o.. or ..o.o.
        // xoxoox    xooxox
        if ((ss.stones[1] == 1 && ss.stones[3] == 1) ||
            (ss.stones[2] == 1 && ss.stones[4] == 1))
        {
            GBOperatorBrokenThree bthree = new GBOperatorBrokenThree();
            bthree.fAdd = new int[4, 3];

            int posCount = 0;
            int pFillC   = 0;
            for (int n = 1; n < (ss.stones.Length - 1); ++n)
            {
                if (ss.stones[n] == 1)
                {
                    posCount += 1;

                    continue;
                }

                // Free stone
                // Case A: middle, fill with oponent
                if (posCount == 1)
                {
                    bthree.fAdd[pFillC, 0] = ss.x + n * ss.ax;
                    bthree.fAdd[pFillC, 1] = ss.y + n * ss.ay;
                    bthree.fAdd[pFillC, 2] = -1;

                    pFillC += 1;
                }
                else
                {
                    // Case B: not the middle, fill with our own
                    bthree.fAdd[pFillC, 0] = ss.x + n * ss.ax;
                    bthree.fAdd[pFillC, 1] = ss.y + n * ss.ay;
                    bthree.fAdd[pFillC, 2] = 1;

                    pFillC += 1;
                }
            }

            // The two corner stones: x....x
            bthree.fAdd[2, 0] = ss.x;
            bthree.fAdd[2, 1] = ss.y;
            bthree.fAdd[2, 2] = -1;

            bthree.fAdd[3, 0] = ss.x + 5 * ss.ax;
            bthree.fAdd[3, 1] = ss.y + 5 * ss.ay;
            bthree.fAdd[3, 2] = -1;

            return(new GBOperatorBrokenThree[] { bthree, });
        }

        throw (new ApplicationException("Broken three: impossible case"));
    }