home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / OP2DEV.ZIP / TTT2.C < prev    next >
C/C++ Source or Header  |  1990-11-17  |  10KB  |  382 lines

  1.  
  2. /*
  3.  * 3D Tic Tac Toe.
  4.  */
  5. #include <stdio.h>
  6. #include <stdarg.h>
  7.  
  8. #define INCL_DOS
  9. #include <os2.h>
  10.  
  11. #include "bbsexpan.h"
  12.  
  13.  
  14. #define     EMPTY     0
  15. #define     PLAYER    1
  16. #define     BEAST     5
  17.  
  18. /*
  19.  * This is a table of all winning
  20.  * combinations.
  21.  * I stole it out of Kilobaud, April
  22.  * 78.
  23.  * You can look there to see how it
  24.  * is ordered.
  25.  */
  26. char     w[] = {
  27.      0,     1,     2,     3,
  28.      4,     5,     6,     7,
  29.      8,     9,     10,     11,
  30.      12,     13,     14,     15,
  31.      0,     4,     8,     12,
  32.      1,     5,     9,     13,
  33.      2,     6,     10,     14,
  34.      3,     7,     11,     15,
  35.      0,     5,     10,     15,
  36.      3,     6,     9,     12,
  37.      16,     17,     18,     19,
  38.      20,     21,     22,     23,
  39.      24,     25,     26,     27,
  40.      28,     29,     30,     31,
  41.      16,     20,     24,     28,
  42.      17,     21,     25,     29,
  43.      18,     22,     26,     30,
  44.      19,     23,     27,     31,
  45.      16,     21,     26,     31,
  46.      19,     22,     25,     28,
  47.      32,     33,     34,     35,
  48.      36,     37,     38,     39,
  49.      40,     41,     42,     43,
  50.      44,     45,     46,     47,
  51.      32,     36,     40,     44,
  52.      33,     37,     41,     45,
  53.      34,     38,     42,     46,
  54.      35,     39,     43,     47,
  55.      32,     37,     42,     47,
  56.      35,     38,     41,     44,
  57.      48,     49,     50,     51,
  58.      52,     53,     54,     55,
  59.      56,     57,     58,     59,
  60.      60,     61,     62,     63,
  61.      48,     52,     56,     60,
  62.      49,     53,     57,     61,
  63.      50,     54,     58,     62,
  64.      51,     55,     59,     63,
  65.      48,     53,     58,     63,
  66.      51,     54,     57,     60,
  67.      0,     16,     32,     48,
  68.      1,     17,     33,     49,
  69.      2,     18,     34,     50,
  70.      3,     19,     35,     51,
  71.      4,     20,     36,     52,
  72.      5,     21,     37,     53,
  73.      6,     22,     38,     54,
  74.      7,     23,     39,     55,
  75.      8,     24,     40,     56,
  76.      9,     25,     41,     57,
  77.      10,     26,     42,     58,
  78.      11,     27,     43,     59,
  79.      13,     29,     45,     61,
  80.      12,     28,     44,     60,
  81.      14,     30,     46,     62,
  82.      15,     31,     47,     63,
  83.      0,     21,     42,     63,
  84.      4,     21,     38,     55,
  85.      8,     25,     42,     59,
  86.      12,     25,     38,     51,
  87.      1,     21,     41,     61,
  88.      13,     25,     37,     49,
  89.      2,     22,     42,     62,
  90.      14,     26,     38,     50,
  91.      3,     22,     41,     60,
  92.      7,     22,     37,     52,
  93.      11,     26,     41,     56,
  94.      15,     26,     37,     48,
  95.      0,     20,     40,     60,
  96.      0,     17,     34,     51,
  97.      3,     18,     33,     48,
  98.      3,     23,     43,     63,
  99.      12,     24,     36,     48,
  100.      12,     29,     46,     63,
  101.      15,     30,     45,     60,
  102.      15,     27,     39,     51
  103. };
  104.  
  105.  
  106. int rules(PORT_REC *);
  107. int user(PORT_REC *);
  108. int board(PORT_REC *);
  109. int psq(int, PORT_REC *);
  110. int beast(PORT_REC *);
  111. int weight(int);
  112.  
  113.  
  114. /*
  115.  * This is the board.
  116.  * Starts off all empty.
  117.  */
  118.  
  119. char     b[64];
  120. char     *top      = "       0            1           2           3\n\r";
  121. char     *top2     = "   0  1  2  3  0  1  2  3  0  1  2  3  0  1  2  3\n\r";
  122. char     *sep      = "   ----------- ----------- ----------- -----------\n\r";
  123.  
  124.  
  125. /*
  126.  * The mainline is just
  127.  * a driver.
  128.  */
  129.  
  130. main(int argc, char *argv[])
  131. {
  132.    int rc;
  133.    char buf[20];
  134.  
  135.    rc = UseChildAppInit(argv[1],argv[0],&anchor,&unhand,&semhand,&usernum,&instance);
  136.    if( rc != 0 ) {
  137.       printf("\nCould not initialize application (%d)\n",rc);
  138.       return(1);
  139.    }
  140.  
  141.    COLOR(BRMAGENTA);
  142.    SerWritef(unhand,"\n\r3-D Tic-Tac-Toe... an Omega Point exclusive presentation!\n\r\n\r");
  143.  
  144.    while( LoggedIn() ) {
  145.  
  146.       for(rc=0;rc<64;rc++)
  147.          b[rc] = EMPTY;
  148.  
  149.       SerColorWrite("\n\rDo you want the rules? ",BRYELLOW,unhand);
  150.       COLOR(BRCYAN);
  151.       if( SerGetCmd(buf,2,unhand) < 0 )
  152.          continue;
  153.       if(buf[0]=='Y')
  154.          rules(unhand);
  155.  
  156.       SerColorWrite("\n\rDo you want to go first? ",BRYELLOW,unhand);
  157.       COLOR(BRCYAN);
  158.       if( SerGetCmd(buf,2,unhand) < 0 ) break;
  159.       SerWritef(unhand,"\n\r");
  160.       if(buf[0]=='Y')
  161.            if( user(unhand) == -1 ) break;
  162.       SerWritef(unhand,"\n\r");
  163.       while( (USENUM==0 || SerConnected(unhand)) && UseTm(unhand) && V_USRON ) {
  164.            if( beast(unhand) == -1 ) break;
  165.            if( user(unhand) == -1 ) break;
  166.       }
  167.       COLOR(BRYELLOW);
  168.       SerWritef(unhand,"\n\rPlay again? ");
  169.       COLOR(BRCYAN);
  170.       if( SerGetCmd(buf,2,unhand) < 0 ) break;
  171.       if( buf[0]=='Y' ) continue;
  172.       break;
  173.    }
  174.  
  175.    exit(1);
  176. }
  177.  
  178. /*
  179.  * Print the rules of the
  180.  * game.
  181.  */
  182. rules(PORT_REC *unhand)
  183. {
  184.      COLOR(BRWHITE);
  185.      SerWritef(unhand,"\n\rThree dimensional tic-tac-toe is played on a 4x4x4\n\r");
  186.      SerWritef(unhand,"board. To win you must get 4 in a row.  Your moves\n\r");
  187.      SerWritef(unhand,"are specified as a 3 digit number; the first digit\n\r");
  188.      SerWritef(unhand,"is the level, the second the row and the third the\n\r");
  189.      SerWritef(unhand,"column. Levels and columns  go  from left to right\n\r");
  190.      SerWritef(unhand,"from 0 to 3. Rows go from top to bottom with  0 on\n\r");
  191.      SerWritef(unhand,"the top.\n\r\n\r");
  192. }
  193.  
  194. /*
  195.  * Accept a user move.
  196.  * Exit if he wins.
  197.  */
  198. user(PORT_REC *unhand)
  199. {
  200.      int i, j, t;
  201.      int rc;
  202.      char buf[20];
  203.  
  204.      board(unhand);
  205.      while( (USENUM==0 || SerConnected(unhand)) && UseTm(unhand) && V_USRON ) {
  206.           COLOR(BRYELLOW);
  207.           SerWritef(unhand,"\n\rYour move (Q to quit)? ");
  208.           COLOR(BRCYAN);
  209.           rc = SerGetCmd(buf,4,unhand);
  210.           if( rc < 1 ) continue;
  211.           SerWritef(unhand,"\n\r");
  212.           if( buf[0] == 'Q' ) {
  213.                COLOR(BRWHITE);
  214.                SerWritef(unhand,"\n\rChicken.\n\r");
  215.                return(-1);
  216.           }
  217.           i = 16*(buf[0]-'0') + (buf[1]-'0') + 4*(buf[2]-'0');
  218.           if(i>=0 && i<=63 && b[i]==EMPTY)
  219.                break;
  220.           COLOR(BRRED);
  221.           SerWritef(unhand,"\n\rEh?\n\r");
  222.      }
  223.      if(i<0 || i>63) return(-1);
  224.      b[i] = PLAYER;
  225.      for(i=0; i<4*76; i+=4) {
  226.           t = 0;
  227.           for(j=0; j<4; ++j)
  228.                t += b[w[i+j]];
  229.           if(t == 4*PLAYER) {
  230.                COLOR(BRWHITE);
  231.                SerWritef(unhand,"\n\rYou win!\n\r");
  232.                return(-1);
  233.           }
  234.      }
  235. }
  236.  
  237. /*
  238.  * Display the board.
  239.  * Not as easy as it sounds.
  240.  */
  241. board(PORT_REC *unhand)
  242. {
  243.      register int i, j;
  244.  
  245.      COLOR(WHITE);
  246.      SerWritef(unhand,"%s",top);
  247.      SerWritef(unhand,"%s\n\r",top2);
  248.      for(i=0; i<4; ++i) {
  249.           if(i != 0) {
  250.              COLOR(BLUE);
  251.              SerWritef(unhand,"%s",sep);
  252.              COLOR(WHITE);
  253.              SerWritef(unhand," %d ",i);
  254.           }   
  255.           else {
  256.              COLOR(WHITE);
  257.              SerWritef(unhand," %d ",i);
  258.           }   
  259.           for(j=0; j<64; j+=4) {
  260.                psq(i+j, unhand);
  261.                if(j==12 || j==28 || j==44)
  262.                     SerWritef(unhand," ");
  263.                else if(j >= 60)
  264.                     SerWritef(unhand,"\n\r");
  265.                else {
  266.                     COLOR(BLUE);
  267.                     SerWritef(unhand,"|");
  268.                }     
  269.           }
  270.      }
  271. }
  272.  
  273. /*
  274.  * Format and put out square
  275.  * `s' of the board.
  276.  */
  277. psq(int s,PORT_REC *unhand)
  278. {
  279.      register int v;
  280.  
  281.      v = b[s];
  282.      if(v == PLAYER) {
  283.           COLOR(BRGREEN);
  284.           SerWritef(unhand,"UU");
  285.      }     
  286.      else if(v == BEAST) {
  287.           COLOR(BRMAGENTA);
  288.           SerWritef(unhand,"CC");
  289.      }     
  290.      else
  291.           SerWritef(unhand,"  ");
  292. }
  293.  
  294. /*
  295.  * Move for the machine.
  296.  * Just exit on machine wins
  297.  * and draws.
  298.  */
  299. beast(PORT_REC *unhand)
  300. {
  301.      register int i, j, t;
  302.      int s, bs, bt, v[76];
  303.  
  304.      for(i=0; i<4*76; i+=4) {
  305.           t = 0;
  306.           for(j=0; j<4; ++j)
  307.                t += b[w[i+j]];
  308.           v[i>>2] = t;
  309.           if(t == 3*BEAST)
  310.                break;
  311.      }
  312.      if(i < 4*76) {
  313.           for(j=0; j<4; ++j)
  314.                if(b[w[i+j]] == EMPTY) {
  315.                     b[w[i+j]] = BEAST;
  316.                     break;
  317.                }
  318.           board(unhand);
  319.           COLOR(BRWHITE);
  320.           SerWritef(unhand,"\n\rI win!!\n\r");
  321.           return(-1);
  322.      }
  323.      bt = 0;
  324.      for(s=0; s<64; ++s) {
  325.           if(b[s] != EMPTY)
  326.                continue;
  327.           t = 0;
  328.           for(i=0; i<4*76; i+=4) {
  329.                for(j=0; j<4; ++j)
  330.                     if(w[i+j] == s)
  331.                          break;
  332.                if(j != 4) {
  333.                     if(v[i>>2] == 3*PLAYER) {
  334.                          b[s] = BEAST;
  335.                          return(1);
  336.                     }
  337.                     t += weight(v[i>>2]);
  338.                }
  339.           }
  340.           if(t > bt) {
  341.                bt = t;
  342.                bs = s;
  343.           }
  344.      }
  345.      if(bt != 0)
  346.           b[bs] = BEAST;
  347.      else {
  348.           for(s=0; s<64; ++s)
  349.                if(b[s] == EMPTY)
  350.                     break;
  351.           if(s == 64) {
  352.                COLOR(BRWHITE);
  353.                SerWritef(unhand,"\n\rDraw.\n\r");
  354.                return(-1);
  355.           }
  356.           b[s] = BEAST;
  357.      }
  358.      return(1);
  359. }
  360.  
  361. /*
  362.  * Given a total along a winning
  363.  * combination, return the weight
  364.  * value.
  365.  */
  366. weight(int at)
  367. {
  368.      register int t;
  369.  
  370.      t = at;
  371.      if(t == PLAYER)
  372.           return(1);
  373.      if(t == 2*PLAYER)
  374.           return(4);
  375.      if(t == BEAST)
  376.           return(1);
  377.      if(t == 2*BEAST)
  378.           return(2);
  379.      return(0);
  380. }
  381.  
  382.