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); }
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 }); }
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 }); }
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); }
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 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); }
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; } } }
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 }); }
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); }
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")); } }
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")); }