// For information about Breakthrough, visit // // http://en.wikipedia.org/wiki/Breakthrough_%28board_game%29 // // To get enough memory, type: // // java -mx99m Breakth37 // import java.io.*; // import java.util.*; class Move { int x11, x21, x31, x12, x22, x32, x13, x23, x33, x14, x24, x34, x15, x25, x35, x16, x26, x36, x17, x27, x37; Move prev = null; } public class Breakth37 { static byte[] x; static int[][] y, z; static char[] p3, letter; static int [] p1, p2, p4, p5, p6; static Move mv, mv2; public static String lesTekst() { String s = null; BufferedReader inn= new BufferedReader(new InputStreamReader (System.in)); try { s = inn.readLine(); } catch(IOException e){} return s;} public static int lesInt() { int tall = 0; String s = null; boolean done = false; do { s = lesTekst(); try { tall = Integer.parseInt(s); done = true; } catch(NumberFormatException e) { System.out.print("Illegal format! Enter an integer: "); System.out.flush();}} while(!done); return tall;} public static void main(String args[]) { int a00, a01, a02, a03, a04, a05, a06, a07, a08, a09, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, b, c, d, e, f, g, i, j, k, l, h00, h01, h02, h03, h04, h05, h06, h07, h08, h09, h10, h11, h12, h13, h14, h15, h16, h17, h18, h19, h20, m, n, r, s; char q; x = new byte[80621568]; y = new int[4][8]; z = new int[4][8]; letter = new char[4]; p1 = new int[200]; p2 = new int[200]; p3 = new char[200]; p4 = new int[200]; p5 = new int[200]; p6 = new int[200]; String stripe = "\n +---+---+---+"; System.out.println("\nBreakthrough 3x7 oracle by J K Haugland"); System.out.println("\nCounting positions..."); c = 0; d = 0; for (m = 0; m < 80621568; m++) { a00 = m / 40310784; a01 = (m / 20155392) % 2; a02 = (m / 10077696) % 2; a03 = (m / 5038848) % 2; a04 = (m / 2519424) % 2; a05 = (m / 1259712) % 2; a06 = (m / 419904) % 3; a07 = (m / 139968) % 3; a08 = (m / 46656) % 3; a09 = (m / 15552) % 3; a10 = (m / 5184) % 3; a11 = (m / 1728) % 3; a12 = (m / 576) % 3; a13 = (m / 192) % 3; a14 = (m / 64) % 3; a15 = (m / 32) % 2; a16 = (m / 16) % 2; a17 = (m / 8) % 2; a18 = (m / 4) % 2; a19 = (m / 2) % 2; a20 = m % 2; b = 0; if (a12 == 1 && a18 + a20 == 0) b = 3; if (a12 == 1 && a15 + a19 == 0) b = 3; if (a13 == 1 && a19 == 0) b = 3; if (a13 == 1 && a16 + a18 + a20 == 0) b = 3; if (a14 == 1 && a18 + a20 == 0) b = 3; if (a14 == 1 && a17 + a19 == 0) b = 3; if (a06 != 1 && a07 != 1 && a08 != 1 && a09 != 1 && a10 != 1 && a11 != 1 && a12 != 1 && a13 != 1 && a14 != 1 && a00 + a01 + a02 + a03 + a04 + a05 == 0) b = 2; x[m] = (byte)b; if (b == 2) c++; if (b == 3) { d++; if (d % 1000000 == 0) System.out.print("-"); } } // System.out.println ("2 "+c); System.out.println ("3 "+d); c = 4; do { j = 0; for (m = 0; m < 80621568; m++) if (x[m] == 0) // legal and not already assigned { a00 = m / 40310784; a01 = (m / 20155392) % 2; a02 = (m / 10077696) % 2; a03 = (m / 5038848) % 2; a04 = (m / 2519424) % 2; a05 = (m / 1259712) % 2; a06 = (m / 419904) % 3; a07 = (m / 139968) % 3; a08 = (m / 46656) % 3; a09 = (m / 15552) % 3; a10 = (m / 5184) % 3; a11 = (m / 1728) % 3; a12 = (m / 576) % 3; a13 = (m / 192) % 3; a14 = (m / 64) % 3; a15 = (m / 32) % 2; a16 = (m / 16) % 2; a17 = (m / 8) % 2; a18 = (m / 4) % 2; a19 = (m / 2) % 2; a20 = m % 2; stop : { y[1][1] = a00; y[2][1] = a01; y[3][1] = a02; y[1][2] = a03; y[2][2] = a04; y[3][2] = a05; y[1][3] = a06; y[2][3] = a07; y[3][3] = a08; y[1][4] = a09; y[2][4] = a10; y[3][4] = a11; y[1][5] = a12; y[2][5] = a13; y[3][5] = a14; y[1][6] = a15; y[2][6] = a16; y[3][6] = a17; y[1][7] = a18; y[2][7] = a19; y[3][7] = a20; for (d = 1; d < 4; d++) for (e = 1; e < 6; e++) if (y[d][e] == 1) for (f = 1; f < 4; f++) if (d - f < 2 && f - d < 2) if (y[f][e + 1] == 0 || (d != f && y[f][e + 1] == 2) || (d != f && e == 5 && y[f][e + 1] == 1)) { for (k = 1; k < 4; k++) for (l = 1; l < 8; l++) z[k][l] = y[k][l]; z[d][e] = 0; z[f][e + 1] = 1; if (e < 5) { h00 = z[3][7]; h01 = z[2][7]; h02 = z[1][7]; h03 = z[3][6]; h04 = z[2][6]; h05 = z[1][6]; h06 = 3 - z[3][5]; h07 = 3 - z[2][5]; h08 = 3 - z[1][5]; h09 = 3 - z[3][4]; h10 = 3 - z[2][4]; h11 = 3 - z[1][4]; h12 = 3 - z[3][3]; h13 = 3 - z[2][3]; h14 = 3 - z[1][3]; h15 = z[3][2]; h16 = z[2][2]; h17 = z[1][2]; h18 = z[3][1]; h19 = z[2][1]; h20 = z[1][1]; h06 = h06 % 3; h07 = h07 % 3; h08 = h08 % 3; h09 = h09 % 3; h10 = h10 % 3; h11 = h11 % 3; h12 = h12 % 3; h13 = h13 % 3; h14 = h14 % 3; n = h04 + 2 * (h03 + 2 * (h02 + 2 * (h01 + 2 * h00))); n = h09 + 3 * (h08 + 3 * (h07 + 3 * (h06 + 3 * (h05 + 2 * n)))); n = h14 + 3 * (h13 + 3 * (h12 + 3 * (h11 + 3 * (h10 + 3 * n)))); n = h19 + 2 * (h18 + 2 * (h17 + 2 * (h16 + 2 * (h15 + 2 * n)))); n = h20 + 2 * n; i = x[n]; if (c % 2 == 1) { if (i == c - 1) { x[m] = (byte)c; break stop; } } else { if (i < c && i > 0) x[m] = (byte)c; else { x[m] = 0; break stop; } } } else { k = 0; for (l = 1; l < 4; l++) if (z[l][7] == 1 && (l - f == 1 || f - l == 1)) { h00 = z[1][1]; h01 = z[2][1]; h02 = z[3][1]; h03 = z[1][2]; h04 = z[2][2]; h05 = z[3][2]; h06 = z[1][3]; h07 = z[2][3]; h08 = z[3][3]; h09 = z[1][4]; h10 = z[2][4]; h11 = z[3][4]; h12 = z[1][5]; h13 = z[2][5]; h14 = z[3][5]; h15 = z[1][6]; h16 = z[2][6]; h17 = z[3][6]; h18 = z[1][7]; h19 = z[2][7]; h20 = z[3][7]; if (l == 1) h18 = 0; if (l == 2) h19 = 0; if (l == 3) h20 = 0; n = h04 + 2 * (h03 + 2 * (h02 + 2 * (h01 + 2 * h00))); n = h09 + 3 * (h08 + 3 * (h07 + 3 * (h06 + 3 * (h05 + 2 * n)))); n = h14 + 3 * (h13 + 3 * (h12 + 3 * (h11 + 3 * (h10 + 3 * n)))); n = h19 + 2 * (h18 + 2 * (h17 + 2 * (h16 + 2 * (h15 + 2 * n)))); n = h20 + 2 * n; i = x[n]; if (c % 2 == 1) { if (i % 2 == 0 || i == c) k = 1; } else { if (i % 2 == 0 && i > 0 && i < c) k = 1; } } if (c % 2 == 1) { if (k == 0) { x[m] = (byte)c; break stop; } } else { if (k == 1) x[m] = (byte)c; else { x[m] = 0; break stop; } } } } } if (x[m] == c) { j++; if (j % 1000000 == 0) System.out.print("-"); n = a04 + 2 * (a05 + 2 * (a00 + 2 * (a01 + 2 * a02))); n = a11 + 3 * (a06 + 3 * (a07 + 3 * (a08 + 3 * (a03 + 2 * n)))); n = a12 + 3 * (a13 + 3 * (a14 + 3 * (a09 + 3 * (a10 + 3 * n)))); n = a19 + 2 * (a20 + 2 * (a15 + 2 * (a16 + 2 * (a17 + 2 * n)))); n = a18 + 2 * n; if (x[n] == 0) { x[n] = (byte)c; j++; if (j % 1000000 == 0) System.out.print("-"); } } } System.out.println(c+" "+j); c++; } while (j > 0); letter[1] = 'A'; letter[2] = 'B'; letter[3] = 'C'; System.out.println("\n\nDeepest positions:"); for (m = 0; m < 80621568; m++) if (x[m] > 37) { a00 = m / 40310784; a01 = (m / 20155392) % 2; a02 = (m / 10077696) % 2; a03 = (m / 5038848) % 2; a04 = (m / 2519424) % 2; a05 = (m / 1259712) % 2; a06 = (m / 419904) % 3; a07 = (m / 139968) % 3; a08 = (m / 46656) % 3; a09 = (m / 15552) % 3; a10 = (m / 5184) % 3; a11 = (m / 1728) % 3; a12 = (m / 576) % 3; a13 = (m / 192) % 3; a14 = (m / 64) % 3; a15 = (m / 32) % 2; a16 = (m / 16) % 2; a17 = (m / 8) % 2; a18 = (m / 4) % 2; a19 = (m / 2) % 2; a20 = m % 2; System.out.println(" "); System.out.println(2 * a18+" "+2 * a19+" "+2 * a20); System.out.println(2 * a15+" "+2 * a16+" "+2 * a17); System.out.println(a12+" "+a13+" "+a14); System.out.println(a09+" "+a10+" "+a11); System.out.println(a06+" "+a07+" "+a08); System.out.println(a03+" "+a04+" "+a05); System.out.println(a00+" "+a01+" "+a02); System.out.println("("+x[m]+")"); } j = 0; r = 77; s = 0; do { if (r == 77) { for (e = 1; e < 4; e++) { y[e][1] = 1; y[e][2] = 1; y[e][3] = 0; y[e][4] = 0; y[e][5] = 0; y[e][6] = 2; y[e][7] = 2; } s = 0; mv = new Move(); } else if (r == 88) { c = 1; do { c = 0; System.out.println("Enter one three-digit number for each row"); System.out.println("1 = your piece, 2 = opponent piece, 0 = empty space"); for (e = 1; e < 4; e++) for (f = 1; f < 8; f++) y[e][f] = 0; for (e = 1; e < 8; e++) { f = lesInt(); y[1][8 - e] = f / 100; y[2][8 - e] = (f / 10) % 10; y[3][8 - e] = f % 10; } for (e = 1; e < 4; e++) { if (y[e][7] != 0 && y[e][7] != 2) c = 1; if (y[e][6] != 0 && y[e][6] != 2) c = 1; if (y[e][5] < 0 || y[e][5] > 2) c = 1; if (y[e][4] < 0 || y[e][4] > 2) c = 1; if (y[e][3] < 0 || y[e][3] > 2) c = 1; if (y[e][2] < 0 || y[e][2] > 2) c = 1; if (y[e][1] < 0 || y[e][1] > 1) c = 1; } f = 0; for (e = 1; e < 4; e++) if (y[e][2] == 2) { f++; g = 0; for (i = 1; i < 4; i++) if (i - e == 1 || e - i == 1) if (y[i][1] == 1) g++; if (g == 0) c = 1; } if (f > 1) c = 1; k = 0; l = 0; for (e = 1; e < 4; e++) for (f = 1; f < 8; f++) { if (y[e][f] == 1) k++; if (y[e][f] == 2) l++; } if (k == 0 || l == 0) c = 1; if (c == 1) System.out.println("Invalid choice or too few moves left!"); } while (c == 1); s = 0; mv = new Move(); } c = 0; System.out.println(stripe); for (f = 7; f > 0; f--) { System.out.print(f+"|"); for (e = 1; e < 4; e++) { if (s == 0) g = y[e][f]; else g = y[4 - e][8 - f]; if (g == 0) System.out.print(" |"); else if (g + s == 2) System.out.print(" x |"); else System.out.print(" o |"); } System.out.println(stripe); } System.out.println(" A B C\n"); for (e = 1; e < 4; e++) for (f = 6; f < 8; f++) if (y[e][f] == 2) y[e][f] = 1; if (y[1][2] == 2 || y[2][2] == 2 || y[3][2] == 2) { for (e = 1; e < 4; e++) if (y[e][1] == 1) for (f = 1; f < 4; f++) if (y[f][2] == 2 && (e - f == 1 || f - e == 1)) { c++; p1[c] = e; p2[c] = 1; p3[c] = 'x'; p4[c] = f; p5[c] = 2; } } else { for (e = 1; e < 4; e++) for (f = 1; f < 6; f++) if (y[e][f] == 1) for (g = 1; g < 4; g++) if (e - g < 2 && g - e < 2) if (y[g][f + 1] == 0 || (e != g && y[g][f + 1] == 2) || (e != g && f == 5 && y[g][f + 1] == 1)) { c++; p1[c] = e; p2[c] = f; p4[c] = g; p5[c] = f + 1; if (y[g][f + 1] == 0) p3[c] = '-'; else p3[c] = 'x'; } } for (d = 1; d <= c; d++) { for (e = 1; e < 4; e++) for (f = 1; f < 8; f++) z[e][f] = y[e][f]; z[p1[d]][p2[d]] = 0; z[p4[d]][p5[d]] = 1; if (p2[d] < 5) { h00 = z[3][7]; h01 = z[2][7]; h02 = z[1][7]; h03 = z[3][6]; h04 = z[2][6]; h05 = z[1][6]; h06 = 3 - z[3][5]; h07 = 3 - z[2][5]; h08 = 3 - z[1][5]; h09 = 3 - z[3][4]; h10 = 3 - z[2][4]; h11 = 3 - z[1][4]; h12 = 3 - z[3][3]; h13 = 3 - z[2][3]; h14 = 3 - z[1][3]; h15 = z[3][2]; h16 = z[2][2]; h17 = z[1][2]; h18 = z[3][1]; h19 = z[2][1]; h20 = z[1][1]; h06 = h06 % 3; h07 = h07 % 3; h08 = h08 % 3; h09 = h09 % 3; h10 = h10 % 3; h11 = h11 % 3; h12 = h12 % 3; h13 = h13 % 3; h14 = h14 % 3; n = h04 + 2 * (h03 + 2 * (h02 + 2 * (h01 + 2 * h00))); n = h09 + 3 * (h08 + 3 * (h07 + 3 * (h06 + 3 * (h05 + 2 * n)))); n = h14 + 3 * (h13 + 3 * (h12 + 3 * (h11 + 3 * (h10 + 3 * n)))); n = h19 + 2 * (h18 + 2 * (h17 + 2 * (h16 + 2 * (h15 + 2 * n)))); n = h20 + 2 * n; p6[d] = 50 - (x[n] + 1); if (p6[d] % 2 == 0) p6[d] = -p6[d]; p6[d] = p6[d] + 50; } else { p6[d] = 100; e = p4[d]; for (f = 1; f < 4; f++) if (z[f][7] == 1 && (e - f == 1 || f - e == 1)) { h00 = z[1][1]; h01 = z[2][1]; h02 = z[3][1]; h03 = z[1][2]; h04 = z[2][2]; h05 = z[3][2]; h06 = z[1][3]; h07 = z[2][3]; h08 = z[3][3]; h09 = z[1][4]; h10 = z[2][4]; h11 = z[3][4]; h12 = z[1][5]; h13 = z[2][5]; h14 = z[3][5]; h15 = z[1][6]; h16 = z[2][6]; h17 = z[3][6]; h18 = z[1][7]; h19 = z[2][7]; h20 = z[3][7]; if (f == 1) h18 = 0; if (f == 2) h19 = 0; if (f == 3) h20 = 0; n = h04 + 2 * (h03 + 2 * (h02 + 2 * (h01 + 2 * h00))); n = h09 + 3 * (h08 + 3 * (h07 + 3 * (h06 + 3 * (h05 + 2 * n)))); n = h14 + 3 * (h13 + 3 * (h12 + 3 * (h11 + 3 * (h10 + 3 * n)))); n = h19 + 2 * (h18 + 2 * (h17 + 2 * (h16 + 2 * (h15 + 2 * n)))); n = h20 + 2 * n; g = 50 - (x[n] + 2); if (g % 2 == 0) g = -g; g = g + 50; if (g < p6[d]) p6[d] = g; } } } for (e = 1; e < c; e++) for (f = e + 1; f <= c; f++) if (p6[e] < p6[f]) { d = p1[e]; p1[e] = p1[f]; p1[f] = d; d = p2[e]; p2[e] = p2[f]; p2[f] = d; q = p3[e]; p3[e] = p3[f]; p3[f] = q; d = p4[e]; p4[e] = p4[f]; p4[f] = d; d = p5[e]; p5[e] = p5[f]; p5[f] = d; d = p6[e]; p6[e] = p6[f]; p6[f] = d; } for (e = 1; e < c; e++) for (f = e + 1; f <= c; f++) if (p6[e] == p6[f] && (p1[e] + 5 * p2[e] > p1[f] + 5 * p2[f] || (p1[e] + 5 * p2[e] == p1[f] + 5 * p2[f] && p4[e] + 5 * p5[e] > p4[f] + 5 * p5[f]))) { d = p1[e]; p1[e] = p1[f]; p1[f] = d; d = p2[e]; p2[e] = p2[f]; p2[f] = d; q = p3[e]; p3[e] = p3[f]; p3[f] = q; d = p4[e]; p4[e] = p4[f]; p4[f] = d; d = p5[e]; p5[e] = p5[f]; p5[f] = d; d = p6[e]; p6[e] = p6[f]; p6[f] = d; } for (d = 1; d <= c; d++) { if (s == 0) System.out.print(d+". "+letter[p1[d]]+p2[d]+p3[d]+letter[p4[d]]+p5[d]+": "); else System.out.print(d+". "+letter[4-p1[d]]+(8-p2[d])+p3[d]+letter[4-p4[d]]+(8-p5[d])+": "); if (p6[d] > 50) System.out.print("Win"); else System.out.print("Loss"); p6[d] = p6[d] - 50; if (p6[d] < 0) p6[d] = -p6[d]; p6[d] = 50 - p6[d]; System.out.println(" in "+p6[d]+" moves"); } if (p6[1] > 4) { if (mv.prev != null) System.out.println ("66. Retract last move"); System.out.println ("77. Back to start"); System.out.println ("88. Enter new position"); System.out.println ("99. Quit"); r = 0; do { System.out.print("Enter alternative: "); r = lesInt(); } while (r != 99 && r != 88 && r!= 77 && (r != 66 || mv.prev == null) && (r < 1 || r > c)); } else r = 77; if (r <= c) { for (e = 1; e < 4; e++) for (f = 6; f < 8; f++) y[e][f] = 2 * y[e][f]; mv2 = new Move(); mv2 = mv; mv = new Move(); mv.prev = mv2; mv.x11 = y[1][1]; mv.x21 = y[2][1]; mv.x31 = y[3][1]; mv.x12 = y[1][2]; mv.x22 = y[2][2]; mv.x32 = y[3][2]; mv.x13 = y[1][3]; mv.x23 = y[2][3]; mv.x33 = y[3][3]; mv.x14 = y[1][4]; mv.x24 = y[2][4]; mv.x34 = y[3][4]; mv.x15 = y[1][5]; mv.x25 = y[2][5]; mv.x35 = y[3][5]; mv.x16 = y[1][6]; mv.x26 = y[2][6]; mv.x36 = y[3][6]; mv.x17 = y[1][7]; mv.x27 = y[2][7]; mv.x37 = y[3][7]; y[p1[r]][p2[r]] = 0; y[p4[r]][p5[r]] = 1; for (e = 1; e < 4; e++) for (f = 1; f < 5; f++) if (f < 4 || e < 2) { g = y[4 - e][8 - f]; y[4 - e][8 - f] = y[e][f]; y[e][f] = g; } for (e = 1; e < 4; e++) for (f = 1; f < 8; f++) if (y[e][f] > 0) y[e][f] = 3 - y[e][f]; } if (r == 66) { y[1][1] = mv.x11; y[2][1] = mv.x21; y[3][1] = mv.x31; y[1][2] = mv.x12; y[2][2] = mv.x22; y[3][2] = mv.x32; y[1][3] = mv.x13; y[2][3] = mv.x23; y[3][3] = mv.x33; y[1][4] = mv.x14; y[2][4] = mv.x24; y[3][4] = mv.x34; y[1][5] = mv.x15; y[2][5] = mv.x25; y[3][5] = mv.x35; y[1][6] = mv.x16; y[2][6] = mv.x26; y[3][6] = mv.x36; y[1][7] = mv.x17; y[2][7] = mv.x27; y[3][7] = mv.x37; mv = mv.prev; } if (r == 99) j = 1; s = 1 - s; } while (j == 0); } }