/* I couldn't get an elegant tree searcher to work. Hence this kludge. */ #include "sequences.c" short failed; short waiting_output; unsigned char output_buffer[20]; extern char tr [120]; extern struct one_square square[56]; extern void showtwist (short, short); extern struct IntuiMessage *msg, *getmsg(); extern struct Window *wnd1,*wnd2; struct IntuiMessage *flush() { unsigned char move; short layer,direc; short i; msg = NULL; while (waiting_output && ((msg = getmsg()) == NULL)) { move = output_buffer[0]; layer = --move/3; if ((direc = (move % 3)) == 0) direc = -1; showtwist (layer,direc); for (i=0; i < waiting_output; i++) output_buffer[i] = output_buffer[i+1]; --waiting_output; } return (msg); } void output (unsigned char move) { output_buffer [waiting_output++] = move; } void cornerseq (short seq) { unsigned short i; for (i=0; i<6; i++) output(corner5[seq][i]); } short checkcorner ( short offset, short a, short b, short c, short x, short y, short z ) { short corner = 0; if (square[x].colour == a) { if ( ((square[y].colour == b) && (square[z].colour == c)) || ((square[y].colour == c) && (square[z].colour == b)) ) corner = 1 + offset; } else if (square[y].colour == a) { if ( ((square[x].colour == b) && (square[z].colour == c)) || ((square[x].colour == c) && (square[z].colour == b)) ) corner = 2 + offset; } else if (square[z].colour == a) { if ( ((square[x].colour == b) && (square[y].colour == c)) || ((square[x].colour == c) && (square[y].colour == b)) ) corner = 3 + offset; } return (corner); } short findcorner (short a, short b, short c) { short corner; a = square[a].colour; b = square[b].colour; c = square[c].colour; if ( ((corner = checkcorner(0,a,b,c,0,18,36)) == 0) && ((corner = checkcorner(3,a,b,c,2,45,20)) == 0) && ((corner = checkcorner(6,a,b,c,6,42,27)) == 0) && ((corner = checkcorner(9,a,b,c,8,29,51)) == 0) && ((corner = checkcorner(12,a,b,c,9,38,24)) == 0) && ((corner = checkcorner(15,a,b,c,11,26,47)) == 0) && ((corner = checkcorner(18,a,b,c,15,33,44)) == 0) ) corner = checkcorner(21,a,b,c,17,53,35); return (corner); } void edgeseq (short seq) { unsigned short i; for (i=0; i<6; i++) output(edge4[seq][i]); } void edgeseq2 (short seq) { unsigned short i; for (i=0; i<5; i++) output(edge5[seq][i]); } short checkedge ( short offset, short a, short b, short x, short y ) { short edge = 0; if ((square[x].colour == a) && (square[y].colour == b)) edge = 1 + offset; else if ((square[x].colour == b) && (square[y].colour == a)) edge = 2 + offset; return (edge); } short findedge (short a, short b) { short edge; a = square[a].colour; b = square[b].colour; if ( ((edge = checkedge(0,a,b,1,19)) == 0) && ((edge = checkedge(2,a,b,3,39)) == 0) && ((edge = checkedge(4,a,b,5,48)) == 0) && ((edge = checkedge(6,a,b,7,28)) == 0) && ((edge = checkedge(8,a,b,10,25)) == 0) && ((edge = checkedge(10,a,b,12,41)) == 0) && ((edge = checkedge(12,a,b,14,50)) == 0) && ((edge = checkedge(14,a,b,16,34)) == 0) && ((edge = checkedge(16,a,b,21,37)) == 0) && ((edge = checkedge(18,a,b,23,46)) == 0) && ((edge = checkedge(20,a,b,30,43)) == 0) ) edge = checkedge(22,a,b,32,52); return (edge); } void edgesequence (int seq) { short i,j; unsigned char u; if (seq < 24) for (i = 1; i <= edge1[seq][0]; i++) output (edge1[seq][i]); else for (i = 1; i <= edge2[seq-24][0]; i++) { if ((u = edge2[seq-24][i]) < 19) output (u); else for (j = 1; j <= edge3[u-19][0]; j++) output (edge3[u-19][j]); } } struct IntuiMessage *edgefix(short up, short right, short down) { short i; if ((findedge(right,up) == 1) && (findedge(right,down) == 7)) return (NULL); if ((i = findedge(down,right)) == 0) { failed = 1; return (NULL); } if (i > 1) edgesequence(i-2); if (msg = flush()) return (msg); if ((i = findedge(right,up)) < 3) { failed = 1; return (0); } edgesequence(i + 21); return (flush()); } struct IntuiMessage *solve() { short i,j; if (msg = flush()) return (msg); /* get right corners correct */ if ((i = findcorner(4,22,40)-2) < -1) return (NULL); if (i >= 0) for (j=1; j<=corner1[i][0]; j++) output (corner1[i][j]); if (msg = flush()) return (msg); if ((i = findcorner(4,49,22)-5) < -1) return (NULL); if (i >= 0) for (j=1; j<=corner2[i][0]; j++) output (corner2[i][j]); if (msg = flush()) return(msg); if ((i = findcorner(4,40,31)-8) < -1) return (NULL); if (i >= 0) for (j=1; j<=corner3[i][0]; j++) output (corner3[i][j]); if (msg = flush()) return(msg); if ((i = findcorner(4,31,49)-11) < -1) return (NULL); if (i >= 0) for (j=1; j<=corner4[i][0]; j++) output (corner4[i][j]); if (msg = flush()) return(msg); /* get left corners in position */ if ((i = findcorner(13,40,22)-13) < 0) return (NULL); switch (i/3) { case 0: break; case 1: output (5); break; case 2: output (4); break; case 3: output (6); break; default: return (NULL); } if (msg = flush()) return(msg); if ((i = findcorner(13,22,49)-16) < 0) return (NULL); switch (i/3) { case 0: break; case 1: output (5); output (8); output (4); output (11); output (5); output (7); output (4); output (10); break; case 2: output (11); output (5); output (8); output (4); output (10); output (5); output (7); output (4); break; default: return (NULL); } if (msg = flush()) return(msg); if ((i = findcorner(13,31,40)-19) < 0) return (NULL); switch (i/3) { case 0: break; case 1: output (4); output (17); output (5); output (14); output (4); output (16); output (5); output (13); output (4); break; default: return (NULL); } if (msg = flush()) return(msg); /* get left corners oriented */ if ((i = findcorner(13,40,22)-13) < 0) return (NULL); switch (i) { case 0: break; case 1: cornerseq (1); if (msg = flush()) return (msg); if (findcorner(13,22,49)==18) { output (5); cornerseq (0); output (4); } else if (findcorner(13,31,40)==21) { output (4); cornerseq (0); output (5); } else { output (6); cornerseq (0); output (6); } break; case 2: cornerseq (0); if (msg = flush()) return (msg); if (findcorner(13,22,49)==17) { output (5); cornerseq (1); output (4); } else if (findcorner(13,31,40)==20) { output (4); cornerseq (1); output (5); } else { output (6); cornerseq (1); output (6); } break; default: return (NULL); } if (msg = flush()) return(msg); if ((i = findcorner(13,22,49)-16) < 0) return (NULL); switch (i) { case 0: break; case 1: cornerseq (3); if (msg = flush()) return (msg); if (findcorner(13,31,40)==21) { output (6); cornerseq (2); output (6); } else { output (5); cornerseq (2); output (4); } break; case 2: cornerseq (2); if (msg = flush()) return (msg); if (findcorner(13,31,40)==20) { output (6); cornerseq (3); output (6); } else { output (5); cornerseq (3); output (4); } break; default: return (NULL); } if (msg = flush()) return(msg); if ((i = findcorner(13,31,40)-19) < 0) return (NULL); switch (i) { case 0: break; case 1: cornerseq (5); output (4); cornerseq (4); output (5); break; case 2: cornerseq (4); output (4); cornerseq (5); output (5); break; default: return (NULL); } if (msg = flush()) return (msg); if ((i = findcorner(13,49,31)) != 22) return (NULL); /* make top and bottom edges correct */ failed = 0; if (msg = edgefix(22,4,31)) return (msg); if (failed) return (NULL); output (7); output (10); if (msg = flush()) return(msg); if (msg = edgefix(22,40,31)) return (msg); if (failed) return (NULL); output (7); output (10); if (msg = flush()) return (msg); if (msg = edgefix(22,13,31)) return (msg); if (failed) return (NULL); output (7); output (10); if (msg = flush()) return(msg); if (msg = edgefix(22,49,31)) return (msg); if (failed) return (NULL); output (7); output (10); if (msg = flush()) return(msg); /* get middle slice edges into position */ switch (findedge(4,40)) { case 3: case 4: break; case 5: case 6: edgeseq (0); break; case 11: case 12: edgeseq (1); break; case 13: case 14: edgeseq (2); break; default: return (NULL); } if (msg = flush()) return(msg); switch (findedge(13,49)) { case 5: case 6: edgeseq (3); break; case 11: case 12: edgeseq (4); break; case 13: case 14: break; default: return (NULL); } if (msg = flush()) return(msg); /* get middle edges oriented */ if (findedge(4,40) == 4) { edgeseq2 (0); if (msg = flush()) return(msg); if (findedge(4,49) == 6) { output (7); output (10); edgeseq2 (3); output (8); output (11); } else if (findedge(13,40) == 12) { output (8); output (11); edgeseq2 (4); output (7); output (10); } else { output (9); output (12); edgeseq2 (5); output (9); output (12); } } if (msg = flush()) return(msg); if (findedge(4,49) == 6) { edgeseq2 (1); if (msg = flush()) return(msg); if (findedge(13,40) == 12) { output (9); output (12); edgeseq2 (4); output (9); output (12); } else { output (7); output (10); edgeseq2 (5); output (8); output (11); } } if (msg = flush()) return(msg); if (findedge(13,40) == 12) { edgeseq2 (2); output (8); output (11); edgeseq2 (5); output (7); output (10); } if (msg = flush()) return(msg); /* if (findedge(13,49) != 13) return (NULL); */ return (NULL); }