home *** CD-ROM | disk | FTP | other *** search
- /*
- * 3D Tic Tac Toe.
- *
- * Original Author Unknown
- */
- #include \MC\stdio.h
-
- #define EMPTY 0
- #define PLAYER 1
- #define BEAST 5
-
- /*
- * This is a table of all winning combinations.
- * From Kilobaud, April 78.
- * You can look there to see how it is ordered.
- */
- char w[] = {
- 0, 1, 2, 3,
- 4, 5, 6, 7,
- 8, 9, 10, 11,
- 12, 13, 14, 15,
- 0, 4, 8, 12,
- 1, 5, 9, 13,
- 2, 6, 10, 14,
- 3, 7, 11, 15,
- 0, 5, 10, 15,
- 3, 6, 9, 12,
- 16, 17, 18, 19,
- 20, 21, 22, 23,
- 24, 25, 26, 27,
- 28, 29, 30, 31,
- 16, 20, 24, 28,
- 17, 21, 25, 29,
- 18, 22, 26, 30,
- 19, 23, 27, 31,
- 16, 21, 26, 31,
- 19, 22, 25, 28,
- 32, 33, 34, 35,
- 36, 37, 38, 39,
- 40, 41, 42, 43,
- 44, 45, 46, 47,
- 32, 36, 40, 44,
- 33, 37, 41, 45,
- 34, 38, 42, 46,
- 35, 39, 43, 47,
- 32, 37, 42, 47,
- 35, 38, 41, 44,
- 48, 49, 50, 51,
- 52, 53, 54, 55,
- 56, 57, 58, 59,
- 60, 61, 62, 63,
- 48, 52, 56, 60,
- 49, 53, 57, 61,
- 50, 54, 58, 62,
- 51, 55, 59, 63,
- 48, 53, 58, 63,
- 51, 54, 57, 60,
- 0, 16, 32, 48,
- 1, 17, 33, 49,
- 2, 18, 34, 50,
- 3, 19, 35, 51,
- 4, 20, 36, 52,
- 5, 21, 37, 53,
- 6, 22, 38, 54,
- 7, 23, 39, 55,
- 8, 24, 40, 56,
- 9, 25, 41, 57,
- 10, 26, 42, 58,
- 11, 27, 43, 59,
- 13, 29, 45, 61,
- 12, 28, 44, 60,
- 14, 30, 46, 62,
- 15, 31, 47, 63,
- 0, 21, 42, 63,
- 4, 21, 38, 55,
- 8, 25, 42, 59,
- 12, 25, 38, 51,
- 1, 21, 41, 61,
- 13, 25, 37, 49,
- 2, 22, 42, 62,
- 14, 26, 38, 50,
- 3, 22, 41, 60,
- 7, 22, 37, 52,
- 11, 26, 41, 56,
- 15, 26, 37, 48,
- 0, 20, 40, 60,
- 0, 17, 34, 51,
- 3, 18, 33, 48,
- 3, 23, 43, 63,
- 12, 24, 36, 48,
- 12, 29, 46, 63,
- 15, 30, 45, 60,
- 15, 27, 39, 51
- };
-
- /*
- * This is the board.
- * Starts off all empty.
- */
- char b[64] = 0;
- char sep[] = " ----------- ----------- ----------- -----------\n";
-
- /*
- * The mainline is just a driver.
- */
- main()
- {
- char buf[20];
-
- printf("Do you want the rules? ");
- fgets(buf, 20, stdin);
- if(buf[0]=='Y' || buf[0]=='y')
- rules();
- printf("Do you want to go first? ");
- fgets(buf,20,stdin);
- if(buf[0]=='Y' || buf[0]=='y')
- user();
- for(;;) {
- beast();
- user();
- }
- }
-
- /*
- * Print the rules of the game.
- */
- rules()
- {
- printf("Three dimensional tic-tac-toe is played on a 4x4x4\n");
- printf("board. To win you must get 4 in a row. Your moves\n");
- printf("are specified as a 3 digit number; the first digit\n");
- printf("is the level, the second the row and the third the\n");
- printf("column. Levels and columns go from left to right\n");
- printf("from 1 to 3. Rows go from top to bottom with 0 on\n");
- printf("the top.\n");
- }
-
- /*
- * Accept a user move. Exit if he wins.
- */
- user()
- {
- register int i, j, t;
- char buf[20];
-
- board();
- for(;;) {
- printf("Your move (L/R/C)? ");
- if(!fgets(buf,20,stdin)) {
- printf("Chicken.\n");
- exit(0);
- }
- i = 16*(buf[0]-'1') + (buf[1]-'1') + 4*(buf[2]-'1');
- if(i>=0 && i<=63 && b[i]==EMPTY)
- break;
- printf("Eh?\n");
- }
- b[i] = PLAYER;
- for(i=0; i<4*76; i+=4) {
- t = 0;
- for(j=0; j<4; ++j)
- t += b[w[i+j]];
- if(t == 4*PLAYER) {
- printf("You win.\n");
- exit(0);
- }
- }
- }
-
- /*
- * Display the board. (Not as easy as it sounds)
- */
- board()
- {
- register int i, j;
-
- for(i=1; i < 5; ++i)
- printf(" %d ", i);
- printf("\n");
- for(i=0; i<4; ++i) {
- printf(sep);
- printf("%d ", i+1);
- for(j=0; j<64; j+=4) {
- psq(i+j);
- if(j==12 || j==28 || j==44)
- printf(" ");
- else if(j >= 60)
- putc('\n', stdout);
- else
- putc('!', stdout);
- }
- }
- printf(sep);
- for(i=0; i < 4; ++i) {
- for(j=1; j < 5; ++j)
- printf(" %d", j);
- printf(" "); }
- printf("\n");
- }
-
- /*
- * Format and put out square `s' of the board.
- */
- psq(s)
- int s;
- {
- register int v;
-
- v = b[s];
- if(v == PLAYER)
- printf("PP");
- else if(v == BEAST)
- printf("CC");
- else
- printf(" ");
- }
-
- /*
- * Move for the machine. Just exit on machine wins and draws.
- */
- beast()
- {
- register int i, j, t;
- int s, bs, bt, v[76];
-
- for(i=0; i<4*76; i+=4) {
- t = 0;
- for(j=0; j<4; ++j)
- t += b[w[i+j]];
- v[i>>2] = t;
- if(t == 3*BEAST)
- break;
- }
- if(i < 4*76) {
- for(j=0; j<4; ++j)
- if(b[w[i+j]] == EMPTY) {
- b[w[i+j]] = BEAST;
- break;
- }
- board();
- printf("I win.\n");
- exit(0);
- }
- bt = 0;
- for(s=0; s<64; ++s) {
- if(b[s] != EMPTY)
- continue;
- t = 0;
- for(i=0; i<4*76; i+=4) {
- for(j=0; j<4; ++j)
- if(w[i+j] == s)
- break;
- if(j != 4) {
- if(v[i>>2] == 3*PLAYER) {
- b[s] = BEAST;
- return;
- }
- t += weight(v[i>>2]);
- }
- }
- if(t > bt) {
- bt = t;
- bs = s;
- }
- }
- if(bt != 0)
- b[bs] = BEAST;
- else {
- for(s=0; s<64; ++s)
- if(b[s] == EMPTY)
- break;
- if(s == 64) {
- printf("Draw.\n");
- exit(0);
- }
- b[s] = BEAST;
- }
- }
-
- /*
- * Given a total along a winning combination, return the weight value.
- */
- weight(at)
- int at;
- {
- register int t;
-
- t = at;
- if(t == PLAYER)
- return(1);
- if(t == 2*PLAYER)
- return(4);
- if(t == BEAST)
- return(1);
- if(t == 2*BEAST)
- return(2);
- return(0);
- }
-