// Return the operator's category that is the lowest among the applicable
    // operators for state.
    public static int LowestOperatorCategory(GoBangBoard board)
    {
        // A maximum, not important, just must be larger than any real
        // category
        int max = 99;

        // Search category 0 and 1 in G_5
        foreach (GoBangBoard.StoneSet ss in board.G5)
        {
            // There is no category below zero, so we can return early.
            if (GBOperatorFive.Present(ss))
            {
                return(0);
            }

            if (GBOperatorFour.Present(ss))
            {
                max = 1;
            }
        }

        if (max < 99)
        {
            return(max);
        }

        // Search category 1 and 2 in G_6
        foreach (GoBangBoard.StoneSet ss in board.G6)
        {
            // If there was no 0/1 before, this is certainly the minimum.
            if (GBOperatorStraightFour.Present(ss))
            {
                return(1);
            }

            if (max > 2 && GBOperatorBrokenThree.Present(ss))
            {
                max = 2;
            }
            else if (max > 2 && GBOperatorThree3.Present(ss))
            {
                max = 2;
            }
        }

        if (max < 99)
        {
            return(max);
        }

        foreach (GoBangBoard.StoneSet ss in board.G7)
        {
            if (GBOperatorThree2.Present(ss))
            {
                return(2);
            }
        }

        return(99);
    }
Exemple #2
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 });
    }
    public static GBOperator[] LegalOperators(GBSpaceState state, int maxCat)
    {
        ArrayList opersGoal   = new ArrayList();
        ArrayList opersFours  = new ArrayList();
        ArrayList opersThrees = new ArrayList();

        // Check G_5 for operators
        foreach (GoBangBoard.StoneSet ss in state.GB.G5)
        {
            if (IsLastOperatorDependent(ss, state.LastOperator) == false)
            {
                continue;
            }

            GBOperatorFive[] fives = null;
            if (maxCat >= 0)
            {
                fives = GBOperatorFive.GetOperatorsIfValid(ss);
            }

            GBOperatorFour[] fours = null;
            if (maxCat >= 1)
            {
                fours = GBOperatorFour.GetOperatorsIfValid(ss);
            }

            if (fives != null)
            {
                opersGoal.AddRange(fives);
            }
            if (fours != null)
            {
                opersFours.AddRange(fours);
            }
        }

        bool Three2Applicable = false;

        if (maxCat >= 2)
        {
            // Check G_7 for operators
            foreach (GoBangBoard.StoneSet ss in state.GB.G7)
            {
                if (IsLastOperatorDependent(ss, state.LastOperator) == false)
                {
                    continue;
                }

                /*
                 * Console.Write ("7ss: ");
                 * for (int n = 0 ; n < ss.stones.Length ; ++n)
                 *      Console.Write ("{0} ", ss.stones[n] == 1 ? "O" :
                 *              (ss.stones[n] == -1 ? "X" : "."));
                 * Console.WriteLine ();
                 */

                GBOperatorThree2[] three2 =
                    GBOperatorThree2.GetOperatorsIfValid(ss);

                if (three2 != null)
                {
                    Three2Applicable = true;
                    opersThrees.AddRange(three2);
                }
            }
        }

        // Check G_6 for operators
        if (maxCat >= 1)
        {
            foreach (GoBangBoard.StoneSet ss in state.GB.G6)
            {
                if (IsLastOperatorDependent(ss, state.LastOperator) == false)
                {
                    continue;
                }

                GBOperatorStraightFour[] sfours = null;
                if (maxCat >= 1)
                {
                    sfours = GBOperatorStraightFour.GetOperatorsIfValid(ss);
                }

                GBOperatorBrokenThree[] bthrees = null;
                GBOperatorThree3[]      three3s = null;
                if (maxCat >= 2)
                {
                    bthrees = GBOperatorBrokenThree.GetOperatorsIfValid(ss);
                }

                // Heuristic "restricted trees", page 141.
                // HEURISTIC
                // FIXME: re-enable this after testing.
                if (maxCat >= 2 /*&& Three2Applicable == false*/)
                {
                    three3s = GBOperatorThree3.GetOperatorsIfValid(ss);
                }

                if (sfours != null)
                {
                    opersGoal.AddRange(sfours);
                }
                if (bthrees != null)
                {
                    opersThrees.AddRange(bthrees);
                }
                if (three3s != null)
                {
                    opersThrees.AddRange(three3s);
                }
            }
        }

        // Order: goal, fours, threes
        opersGoal.AddRange(opersFours);
        opersGoal.AddRange(opersThrees);

        if (opersGoal.Count > 0)
        {
            return((GBOperator[])opersGoal.ToArray(typeof(GBOperator)));
        }

        return(null);
    }
Exemple #4
0
    public void CombineCheck(ArrayList[,] affect)
    {
        int         patternG5 = 0;
        GoBangBoard board     = new GoBangBoard();

        ArrayList[] affecting = new ArrayList[5];

        foreach (GoBangBoard.StoneSet ss in board.G5)
        {
            for (int n = 0; n < ss.stones.Length; ++n)
            {
                affecting[n] = affect[ss.y + n * ss.ay, ss.x + n * ss.ax];
            }

            // Now in positions we have 'oneBits' number of positions.
            CheckC2(affecting);
#if false
            // Do a pre-filtering of sensible patterns in this G_5
            bool[] fivePatterns = new bool[1 << 5];

            for (int p = 0; p < fivePatterns.Length; ++p)
            {
                fivePatterns[p] = false;

                for (int n = 0; n < 5; ++n)
                {
                    ss.stones[n] = (p & (1 << n)) == 0 ? 0 : 1;

                    if (ss.stones[n] == 1 && affecting[n].Count == 0)
                    {
                        goto nextPattern;
                    }
                }

                /*
                 * Console.Write ("A pattern {0}: ", p);
                 * for (int n = 0 ; n < 5 ; ++n)
                 *      Console.Write ("{0}", ss.stones[n] == 1 ? "O" : ".");
                 * Console.WriteLine ();
                 */

                GBOperatorFive[] fiveP =
                    GBOperatorFive.GetOperatorsIfValid(ss);
                GBOperatorFour[] fourP =
                    GBOperatorFour.GetOperatorsIfValid(ss);

                /*
                 * Console.WriteLine ("  pattern {0}: {1} fives, {2} fours", p,
                 *      (fiveP == null) ? "-" : String.Format ("{0}", fiveP.Length),
                 *      (fourP == null) ? "-" : String.Format ("{0}", fourP.Length));
                 */

                // Only if we trigger a pattern, we mark it for later action.
                if ((fiveP != null && fiveP.Length > 0) ||
                    (fourP != null && fourP.Length > 0))
                {
                    fivePatterns[p] = true;
                    //Console.WriteLine ("  pattern {0} OK", p);
                }
nextPattern:
                ;
            }

            for (int p = 0; p < fivePatterns.Length; ++p)
            {
                if (fivePatterns[p] == false)
                {
                    continue;
                }

                // Now examine the pattern really.
                Console.WriteLine("pattern {0} success", p);
                Console.WriteLine("    a[0 to 4]: {0}, {1}, {2}, {3}, {4}",
                                  affecting[0].Count,
                                  affecting[1].Count,
                                  affecting[2].Count,
                                  affecting[3].Count,
                                  affecting[4].Count);

                patternG5 += 1;

                // TODO
                // Now we have an array of list of affecting moves plus a
                // pattern they may trigger.  We know that those moves in the
                // same array element are conflicting, so we do not need to
                // check those.  Also, we know the new operators are
                // independent of exchange of operators (commutative), so we
                // must only check each combination once, regardless of the
                // order.
                int oneBits = 0;
                for (int n = 0; n < 5; ++n)
                {
                    if ((p & (1 << n)) != 0)
                    {
                        oneBits += 1;
                    }
                }
                int[] positions = new int[oneBits];

                int oneBitPos = 0;
                for (int n = 0; n < 5; ++n)
                {
                    if ((p & (1 << n)) == 0)
                    {
                        continue;
                    }

                    positions[oneBitPos] = n;
                    oneBitPos           += 1;
                }
            }
#endif
        }
        //Console.WriteLine ("G5 patterns: {0}", patternG5);
    }
    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 });
    }