home *** CD-ROM | disk | FTP | other *** search
/ C++ Games Programming / CPPGAMES.ISO / thx / demos / ttt / build / ttt.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  3.7 KB  |  182 lines

  1. // --------- ttt.cpp
  2. #include "ttt.h"
  3.  
  4. CURSORLIST(TicTacToe)
  5.     MOUSE_CURSOR(  70,  18, 128,  75, UPCURSOR, position1)
  6.     MOUSE_CURSOR( 136,  18, 200,  75, UPCURSOR, position2)
  7.     MOUSE_CURSOR( 208,  18, 266,  75, UPCURSOR, position3)
  8.     MOUSE_CURSOR(  70,  82, 128, 146, UPCURSOR, position4)
  9.     MOUSE_CURSOR( 136,  82, 200, 146, UPCURSOR, position5)
  10.     MOUSE_CURSOR( 208,  82, 266, 146, UPCURSOR, position6)
  11.     MOUSE_CURSOR(  70, 154, 128, 210, UPCURSOR, position7)
  12.     MOUSE_CURSOR( 136, 154, 200, 210, UPCURSOR, position8)
  13.     MOUSE_CURSOR( 208, 154, 266, 210, UPCURSOR, position9)
  14. ENDCURSORLIST
  15.  
  16. // --- the playing board
  17. char TicTacToe::board[9];
  18.  
  19. // --- winning combinations
  20. int TicTacToe::wins [8][3] = {
  21.     {1,2,3}, {4,5,6}, {7,8,9},    // winning rows      
  22.     {1,4,7}, {2,5,8}, {3,6,9},  // winning columns   
  23.     {1,5,9}, {3,5,7}            // winning diagonals 
  24. };
  25.  
  26. // ---- construct the board game
  27. TicTacToe::TicTacToe() : SceneryDirector("ttt.pcx")
  28. {
  29.     piece = new Piece(this);
  30.     voice = new Voice(this);
  31.     initialize_play();
  32. }
  33. TicTacToe::~TicTacToe()
  34. {
  35.     delete piece;
  36. }
  37. void TicTacToe::display()
  38. {
  39.     SceneryDirector::display();
  40.     mouse_visible();
  41. }
  42. void TicTacToe::hide()
  43. {
  44.     mouse_invisible();
  45.     SceneryDirector::hide();
  46. }
  47. void TicTacToe::initialize_play()
  48. {
  49.     play = 0;
  50.     isover = 0;
  51.     for (int i = 0; i < 9; i ++)
  52.         board[i] = 0;
  53. }
  54. // ---- computer says "hmm"
  55. void TicTacToe::say(soundclip clip)
  56. {
  57.     voice->play_sound_clip(clip);
  58.     while (voice->sound_clip_is_playing())
  59.         ;
  60. }
  61. // ---- player selects a move
  62. void TicTacToe::position(int pos)
  63. {
  64.     if (isover)    {
  65.         initialize_play();
  66.         display_original_scenery();
  67.         return;
  68.     }
  69.     if (board[pos-1] != 0)    {
  70.         say(notthere);
  71.         return;
  72.     }
  73.     piece->placemarker(pos, player);
  74.     if (play == 0)    {
  75.         say(hmm);
  76.         if (pos != 5)
  77.             piece->placemarker(5, computer);
  78.         else 
  79.             piece->placemarker(1, computer);
  80.         play = 2;
  81.         return;
  82.     }
  83.     play++;
  84.     if (won())    {
  85.         say(youwin);
  86.         return;
  87.     }
  88.     if (play == 9)    {
  89.         isover = 1;
  90.         say(tie);
  91.         return;
  92.     }
  93.     // ---- compute computer's next move
  94.     int mv;
  95.     if ((mv = canwin(computer)) != 0)
  96.         // --- win if possible
  97.         piece->placemarker(mv, computer);
  98.     else    {
  99.         if ((mv = canwin(player)) != 0)    {
  100.             // --- block player's win potential
  101.             say(ohno);
  102.             piece->placemarker(mv, computer);
  103.         }
  104.         else    {
  105.             say(nowwhat);
  106.             nextmove();
  107.         }
  108.     }
  109.     if (won())    {
  110.         say(iwin);
  111.         return;
  112.     }
  113.     play++;
  114. }
  115. // --- find next available open space for a dumb move
  116. void TicTacToe::nextmove()
  117. {
  118.     int lmv = -1;
  119.     for (int i = 0; i < 9; i++)
  120.         if (board[i] == 0) {
  121.             lmv = i+1;
  122.             board[lmv-1] = computer;
  123.             if (canwin(computer))    {
  124.                 board[lmv-1] = 0;
  125.                 piece->placemarker(lmv, computer);
  126.                 return;
  127.             }
  128.             board[lmv-1] = 0;
  129.         }
  130.     if (lmv != -1)
  131.         piece->placemarker(lmv, computer);
  132. }
  133. // --- test to see if a player (n) can win this time
  134. int TicTacToe::canwin(int n)
  135. {
  136.     int i, w;
  137.  
  138.     for (i = 0; i < 8; i++)
  139.         if ((w = trywin(n, wins[i])) != 0)
  140.             return w;
  141.     return 0;
  142. }
  143. // ---- test a row, column, or diagonal for a win
  144. int TicTacToe::trywin(int n,int *wn)
  145. {
  146.     int nct = 0, zct = 0, i;
  147.  
  148.     for (i = 0; i < 3; i++)
  149.         if (board[*(wn + i)-1] == 0)
  150.             zct = i+1;
  151.         else if (board[*(wn + i)-1] == n)
  152.             nct++;
  153.     if (nct == 2 && zct)
  154.         return *(wn + zct - 1);
  155.     return 0;
  156. }
  157. // ------ update the board with a move
  158. void TicTacToe::update(int square, int piece)
  159. {
  160.     if (square)
  161.         board[square-1] = piece;
  162.     refresh_display();
  163. }
  164. // ------ test to see if the game has been won
  165. int TicTacToe::won()
  166. {
  167.     int i, k;
  168.     for (i = 0; i < 8; i++) {
  169.         if (board[wins[i][0]-1] == 0)
  170.             continue;
  171.         for (k = 1; k < 3; k++)
  172.             if (board[wins[i][0]-1] != board[wins[i][k]-1])
  173.                 break;
  174.         if (k == 3)    {
  175.             piece->drawline(i);
  176.             isover = 1;
  177.             return 1;
  178.         }
  179.     }
  180.     return 0;
  181. }
  182.