home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 125_01 / vttt.c < prev    next >
Text File  |  1985-03-10  |  7KB  |  342 lines

  1. /*   DISK CATALOG : HEADERS.DOC
  2.     
  3. C Users Group Volume Number 125 - VIDEO TERMINAL LIRARIES
  4. Cataloged By Ben Rockefeller 5/15/85    
  5.  
  6. */
  7.  
  8. /*           HEADER: CUG125.19; 
  9.  
  10.           TITLE: VIDEO TERMINAL LIBRARIES;
  11.             VERSION: 1.0;
  12.                   DATE: 5/15/85;              
  13.         DESCRIPTION: "Video Tic Tac Toe game";
  14.        KEYWORDS: game, video terminal routines;
  15.              SYSTEM: Osborne 1, DEC vt52;
  16.            FILENAME: VTTT.C;
  17.        WARNINGS: "Requires video terminal routines linked;
  18.              runs only on Osborne 1 and DEC vt52";
  19.        SEE-ALSO: VTTT.NRO;
  20.             AUTHORS: Stephen L. Browning;
  21.           COMPILERS: BDC C;
  22. */
  23.  
  24.  
  25. /*
  26.  *    Video Tic Tac Toe
  27.  *
  28.  *    A rewrite of Tic Tac Toe by Leor Zolman
  29.  *    using the cursor addressing capabilities of a CRT.
  30.  *
  31.  *    Stephen L. Browning
  32.  *    5723 North Parker Avenue
  33.  *    Indianapolis, Indiana 46220
  34.  */
  35.  
  36. #define TRUE    1
  37. #define FALSE    0
  38.  
  39. /*
  40.  *    To implement on a 52 X 24 display such as the Osborne,
  41.  *    reduce each of the horizontal reference points by 10
  42.  *    (ie subtract 10 from XR, WINX, LOSSX, and TIEX).
  43.  */
  44.  
  45. #define XR    20        /* reference coordinate for play grid */
  46. #define YR    0
  47. #define CHW    8        /* width and height of x's and o's */
  48. #define CHH    4
  49. #define BLKW    (CHW+2)        /* size of spaces for x's and o's */
  50. #define BLKH    (CHH+2)
  51.  
  52. #define WINX    15        /* positioning data for messages */
  53. #define WINY    21
  54. #define LOSSX    30
  55. #define LOSSY    21
  56. #define TIEX    50
  57. #define TIEY    21
  58. #define QRYX    0
  59. #define QRYY    23
  60.  
  61. #define X    1
  62. #define O    5
  63. #define EMPTY    0
  64.  
  65. int wins;        /* number of times player has won */
  66. int losses;        /* number of times player has lost */
  67. int ties;        /* number of tie games */
  68. char board[9];        /* playing board */
  69. char xchar[CHH][CHW];    /* pattern definition for 'x' */
  70. char ochar[CHH][CHW];    /* pattern definition for 'o' */
  71. int playchar;        /* player's character - either X or O */
  72. int compchar;        /* computer's character */
  73. int winner[8][3];    /* definition of winning combinations */
  74.  
  75. main()
  76. {
  77.     int i;
  78.     int newgame;
  79.     int playfirst;
  80.  
  81.     wins = losses = ties = 0;
  82.     initb(&xchar[0][0],"32,32,88,32,32,88,32,32");
  83.     initb(&xchar[1][0],"32,32,32,88,88,32,32,32");
  84.     initb(&xchar[2][0],"32,32,32,88,88,32,32,32");
  85.     initb(&xchar[3][0],"32,32,88,32,32,88,32,32");
  86.     initb(&ochar[0][0],"32,32,79,79,79,79,32,32");
  87.     initb(&ochar[1][0],"32,32,79,32,32,79,32,32");
  88.     initb(&ochar[2][0],"32,32,79,32,32,79,32,32");
  89.     initb(&ochar[3][0],"32,32,79,79,79,79,32,32");
  90.     initw(winner,"0,1,2,3,4,5,6,7,8,0,3,6,1,4,7,2,5,8,0,4,8,2,4,6");
  91.     newgame = TRUE;
  92.     playfirst = TRUE;
  93.     srand(0);
  94.     while (newgame) {
  95.         initbrd();
  96.         if (playfirst) {
  97.             playchar = X;
  98.             compchar = O;
  99.         }
  100.         else {
  101.             playchar = O;
  102.             compchar = X;
  103.         }
  104.         play(playfirst);
  105.         score();
  106.         newgame = query();
  107.         playfirst = !playfirst;
  108.     }
  109.     clrscrn();
  110. }
  111.  
  112. /*
  113.  *    Initialize display and parameters
  114.  */
  115.  
  116. initbrd()
  117. {
  118.     int i;
  119.  
  120.     clrscrn();
  121.     for (i=0; i<(3*BLKW+2); ++i) {
  122.         setcur(XR+i,YR+BLKH);
  123.         putchar('-');
  124.         setcur(XR+i,YR+2*BLKH+1);
  125.         putchar('-');
  126.     }
  127.     for (i=0; i<(3*BLKH+2); ++i) {
  128.         setcur(XR+BLKW,YR+i);
  129.         putchar('|');
  130.         setcur(XR+2*BLKW+1,YR+i);
  131.         putchar('|');
  132.     }
  133.     setcur(XR+BLKW,YR+BLKH);
  134.     putchar('+');
  135.     setcur(XR+2*BLKW+1,YR+BLKH);
  136.     putchar('+');
  137.     setcur(XR+BLKW,YR+2*BLKH+1);
  138.     putchar('+');
  139.     setcur(XR+2*BLKW+1,YR+2*BLKH+1);
  140.     putchar('+');
  141.     setcur(XR+BLKW-1,YR+2*BLKH+2);
  142.     putchar('1');
  143.     setcur(XR+BLKW+1,YR+2*BLKH+2);
  144.     putchar('2');
  145.     setcur(XR+2*BLKW+2,YR+2*BLKH+2);
  146.     putchar('3');
  147.     setcur(XR+BLKW-1,YR+BLKH+1);
  148.     putchar('4');
  149.     setcur(XR+BLKW+1,YR+BLKH+1);
  150.     putchar('5');
  151.     setcur(XR+2*BLKW+2,YR+BLKH+1);
  152.     putchar('6');
  153.     setcur(XR+BLKW-1,YR+BLKH-1);
  154.     putchar('7');
  155.     setcur(XR+BLKW+1,YR+BLKH-1);
  156.     putchar('8');
  157.     setcur(XR+2*BLKW+2,YR+BLKH-1);
  158.     putchar('9');
  159.     for (i=0; i<9; ++i) board[i] = EMPTY;
  160. }
  161.  
  162.  
  163. /*
  164.  *    Play one game
  165.  */
  166.  
  167. play(playturn)
  168. int playturn;
  169. {
  170.     int i;
  171.     int bestmove;
  172.     int round;
  173.  
  174.     round = 0;
  175.     while (round < 9) {
  176.         if (playturn) {
  177.             eralin(QRYY);
  178.             setcur(QRYX,QRYY);
  179.             puts("Your move (1-9)? ");
  180.             i = getchar() - '0';
  181.             if (i < 1 || i > 9 || board[i-1] != EMPTY) {
  182.                 eralin(QRYY);
  183.                 setcur(QRYX,QRYY);
  184.                 puts("Illegal move");
  185.                 for (i=0; i<7000; ++i) ;
  186.                 continue;
  187.             }
  188.             board[i-1] = playchar;
  189.             put(playchar,i);
  190.             if (won(playchar)) {
  191.                 ++wins;
  192.                 break;
  193.             }
  194.             playturn = !playturn;
  195.         }
  196.         else {
  197.             if (round == 0) bestmove = rand() % 9;
  198.             else if (round == 1) {
  199.                 if (board[4] != EMPTY) {
  200.                     bestmove = rand()%2*6 + rand()%2*2;
  201.                 }
  202.                 else bestmove = 4;
  203.             }
  204.             else ttteval(compchar,playchar,&bestmove);
  205.             board[bestmove] = compchar;
  206.             put(compchar,bestmove+1);
  207.             if (won(compchar)) {
  208.                 ++losses;
  209.                 break;
  210.             }
  211.             playturn = !playturn;
  212.         }
  213.         ++round;
  214.     }
  215.     if (tied()) ++ties;
  216. }
  217.  
  218.  
  219. /*
  220.  *    Put the appropriate character pattern in the
  221.  *    designated block
  222.  */
  223.  
  224. put(c,blk)
  225. char c;
  226. int blk;
  227. {
  228.     char *p;
  229.     int xref, yref;
  230.     int x, y;
  231.  
  232.     xref = XR + (((blk-1)%3)*BLKW) + ((blk-1)%3) + 1;
  233.     yref = YR + (((9-blk)/3)*BLKH) + ((9-blk)/3) + 1;
  234.     p = c == X ? xchar : ochar;
  235.     for (y=0; y<CHH; ++y) {
  236.         setcur(xref,yref+y);
  237.         for (x=0; x<CHW; ++x) putchar(*p++);
  238.     }
  239. }
  240.  
  241.  
  242. /*
  243.  *    Ask about another game
  244.  */
  245.  
  246. query()
  247. {
  248.     int c;
  249.  
  250.     do {
  251.         eralin(QRYY);
  252.         setcur(QRYX,QRYY);
  253.         puts("Another game (y or n)? ");
  254.     } while ((c=toupper(getchar())) != 'Y' && c != 'N');
  255.     if (c == 'Y') return(TRUE);
  256.     return(FALSE);
  257. }
  258.  
  259.  
  260. /*
  261.  *    Display the current score
  262.  */
  263.  
  264. score()
  265. {
  266.     eralin(WINY);
  267.     setcur(WINX,WINY);
  268.     printf("Wins = %03d",wins);
  269.     setcur(LOSSX,LOSSY);
  270.     printf("Losses = %03d",losses);
  271.     setcur(TIEX,TIEY);
  272.     printf("Ties = %03d",ties);
  273. }
  274.  
  275. /*
  276.  *    Test for tie game
  277.  */
  278.  
  279. tied()
  280. {
  281.     int i;
  282.  
  283.     for (i=0; i<9; ++i) {
  284.         if (board[i] == EMPTY) return(FALSE);
  285.     }
  286.     return(TRUE);
  287. }
  288.  
  289.  
  290. /*
  291.  *    Evaluate possible future moves
  292.  */
  293.  
  294. ttteval(cc,pc,pbest)
  295. int cc;        /* computer's character */
  296. int pc;        /* player's character */
  297. int *pbest;    /* pointer to bestmove */
  298. {
  299.     int i;
  300.     int safemove;
  301.     int status;
  302.     int loseflag;
  303.  
  304.     if (won(cc)) return(1);
  305.     if (won(pc)) return(-1);
  306.     if (tied()) return(0);
  307.     loseflag = 1;
  308.     for (i=0; i<9; ++i) {
  309.         if (board[i] != EMPTY) continue;
  310.         board[i] = cc;        /* try the move */
  311.         status = ttteval(pc,cc,pbest);
  312.         board[i] = 0;        /* restore empty space */
  313.         if (status == -1) {
  314.             *pbest = i;
  315.             return(1);
  316.         }
  317.         if (status == 1) continue;
  318.         loseflag = 0;
  319.         safemove = i;
  320.     }
  321.     *pbest = safemove;
  322.     return(-loseflag);
  323. }
  324.  
  325.  
  326. /*
  327.  *    Test for game won
  328.  */
  329.  
  330. won(c)
  331. int c;
  332. {
  333.     int i;
  334.  
  335.     for (i=0; i<8; ++i) {
  336.         if (board[winner[i][0]] == c &&
  337.             board[winner[i][1]] == c &&
  338.             board[winner[i][2]] == c) return(TRUE);
  339.     }
  340.     return(FALSE);
  341. }
  342.