/* * Two player game utilizing threads. * * Players alternate taking turns adding their * symbol to a board. The players with the most * 3-in-a-rows, vertical or horizontal, wins. * * In the board shown to +----+ * the right: |XOOO| * X has 3 3-in-a-rows, and |OXXO| * O has 3 3-in-a-rows. |XXXO| * That game is a draw. |OXXO| * +----+ * * Your job is to modify the program below so that the * computer is always working in the background, trying * to find the best move in response to each of the * moves that the human might make at that step. * * For example, suppse that * the board shown to the +----+ * right is the position |O X | * after 10 moves, and the |OXX | * computer is waiting for |O OX| * the human (X) to make his |X O| * move. There are 6 poss- +----+ * ible moves that the human * could make, and for each of them, the computer should * be descending the game tree deciding which move would * be best for the computer, in each case. * * As soon as the human makes a move, the computer must * immediately cease game computation and make its move. * * The computer should spawn one thread for each move that * the human might make. These threads need to communicate * so that no thread descends to level n+1 in the tree * before every thread has completed its computation down * to level n. */ #include #include #include "game.h" using namespace std; int main(int argc, char* argv[]){ char board[SIZE][SIZE]; initialize(board); play(board); terminate(board); } void initialize(char board[SIZE][SIZE]){ for(int i = 0; i < SIZE; i++) for(int j = 0; j < SIZE; j++) board[i][j] = ' '; srand(time(NULL)); } void play(char board[SIZE][SIZE]){ int numMoves = 0; string input; Player turn; // enum Player {HUMAN, COMPUTER} cout << "\nPlaying on a " << SIZE << "x" << SIZE << " board" << endl; printBoard(board); cout << "Who first? Human (X) or Computer (O)? "; cin >> input; turn = (tolower(input[0]) == 'x' || tolower(input[0]) == 'h') ? HUMAN : COMPUTER; while(numMoves < SIZE*SIZE){ if(turn == HUMAN){ makeHumanMove(board); turn = COMPUTER; } else{ makeComputerMove(board); turn = HUMAN; } numMoves++; printBoard(board); } } void makeHumanMove(char board[SIZE][SIZE]){ string move; int r, c; // row and column cout << "Your move (in form 'a1')? "; cin >> move; r = (int)(tolower(move[0])) - 96; c = (int)move[1] - '1' + 1; while(board[r - 1][c - 1] != ' '){ cout << " Occupied already!" << endl; cout << "Your move (in form 'a1')? "; cin >> move; r = (int)(tolower(move[0])) - 96; c = (int)move[1] - '1' + 1; } board[r - 1][c - 1] = 'X'; } void makeComputerMove(char board[SIZE][SIZE]){ int openr[SIZE*SIZE]; // Available spaces int openc[SIZE*SIZE]; // Available spaces int found = 0; // counts available spaces int r, c; // row and column int computerMove; for(r = 0; r < SIZE; r++) for(c = 0; c < SIZE; c++) if(board[r][c] == ' '){ openr[found] = r; openc[found] = c; found++; } computerMove = rand() % found; cout << "My move: "; cout << (char)(openr[computerMove] + 97); cout << openc[computerMove] + 1 << endl; board[openr[computerMove]][openc[computerMove]] = 'O'; } void printBoard(char board[SIZE][SIZE]){ int r, c; // row and column counters cout << " "; for(c = 0; c < SIZE; c++) cout << c+1; cout << endl << " +"; for(c = 0; c < SIZE; c++) cout << "-"; cout << "+" << endl; for(r = 0; r < SIZE; r++){ cout << (char) (r + 97) << "|"; for(c = 0; c < SIZE; c++) cout << board[r][c]; cout << "|" << endl; } cout << " +"; for(c = 0; c < SIZE; c++) cout << "-"; cout << "+" << endl; } void terminate(char board[SIZE][SIZE]){ int r, c; // row and column int numH = 0, numC = 0; // number of 3-in-a-rows // Count horizontal winners for(r = 0; r < SIZE; r++) for(c = 0; c < SIZE - 2; c++){ if(board[r][c] == 'X' && board[r][c+1] == 'X' && board[r][c+2] == 'X') numH++; if(board[r][c] == 'O' && board[r][c+1] == 'O' && board[r][c+2] == 'O') numC++; } // Count vertical winners for(c = 0; c < SIZE; c++) for(r = 0; r < SIZE - 2; r++){ if(board[r][c] == 'X' && board[r+1][c] == 'X' && board[r+2][c] == 'X') numH++; if(board[r][c] == 'O' && board[r+1][c] == 'O' && board[r+2][c] == 'O') numC++; } cout << "*** You had " << numH << " points, I had " << numC << " points." << endl; if(numH > numC) cout << "*** HUMAN WINS ***" << endl; else if(numC > numH) cout << "*** COMPUTER WINS ***" << endl; else cout << "*** DRAW ***" << endl; }