Last active
December 19, 2015 06:28
-
-
Save KorbenC/5911281 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <iostream> | |
| #include <string> | |
| #include <vector> | |
| #include <algorithm> | |
| using namespace std; | |
| //global constants | |
| const char X = 'X'; | |
| const char O = 'O'; | |
| const char EMPTY = ' '; | |
| const char TIE = 'T'; | |
| const char NO_ONE = 'N'; | |
| //function definitions | |
| void instructions(); | |
| char askYesNo(string question); | |
| int askNumber(string question, int high, int low = 0); | |
| char humanPiece(); | |
| char opponent(char piece); | |
| void displayBoard(const vector<char>* const pBoard); | |
| char winner(const vector<char>* const pBoard); | |
| bool isLegal(const vector<char>* const pBoard, int move); | |
| int humanMove(const vector<char>* const pBoard, char human); | |
| int computerMove(vector<char> board, char computer); | |
| void announceWinner(char winner, char computer, char human); | |
| int main() | |
| { | |
| int move; | |
| char play_again = ' '; | |
| do{ | |
| const int NUM_SQUARES = 9; | |
| vector<char> board(NUM_SQUARES, EMPTY); | |
| instructions(); | |
| char human = humanPiece(); | |
| char computer = opponent(human); | |
| char turn = X; | |
| displayBoard(&board); | |
| while(winner(&board) == NO_ONE) | |
| { | |
| if(turn == human) | |
| { | |
| move = humanMove(&board, human); | |
| board[move] = human; | |
| } | |
| else | |
| { | |
| move = computerMove(board, computer); | |
| board[move] = computer; | |
| } | |
| displayBoard(&board); | |
| turn = opponent(turn); | |
| } | |
| announceWinner(winner(&board), computer, human); | |
| play_again = askYesNo("Do you want to play again?"); | |
| }while(play_again == 'y'); | |
| cout << "Thank you for playing."; | |
| return 0; | |
| } | |
| //functions | |
| void instructions() | |
| { | |
| cout << "Welcome to TicTacToe.\n"; | |
| cout << "make your move known by enter a number, 0-8. The number\n"; | |
| cout << "corresponds to the desired board position, as illustrated:\n\n"; | |
| cout << " 0 | 1 | 2\n"; | |
| cout << " ---------\n"; | |
| cout << " 3 | 4 | 5\n"; | |
| cout << " ---------\n"; | |
| cout << " 6 | 7 | 8\n"; | |
| } | |
| char askYesNo(string question) | |
| { | |
| char response; | |
| do{ | |
| cout << question << "(y/n)"; | |
| cin >> response; | |
| }while(response != 'y' && response != 'n'); | |
| return response; | |
| } | |
| int askNumber(string question, int high, int low) | |
| { | |
| int number; | |
| do{ | |
| cout << question << " (" << low << " - " << high << "): "; | |
| cin >> number; | |
| }while(number > high || number < low); | |
| return number; | |
| } | |
| char humanPiece() | |
| { | |
| char go_first = askYesNo("Do you want to go first?"); | |
| if( go_first == 'y') | |
| { | |
| cout << "\nMake your first move."; | |
| return X; | |
| } | |
| else | |
| { | |
| cout << "\nThe computer will make the first move."; | |
| return O; | |
| } | |
| } | |
| char opponent(char piece) | |
| { | |
| if (piece == X) | |
| return O; | |
| else | |
| return X; | |
| } | |
| void displayBoard(const vector<char>* const pBoard) | |
| { | |
| cout << "\n\t" << (*pBoard)[0] << " | " << (*pBoard)[1] << " | " << (*pBoard)[2]; | |
| cout << "\n\t" << "---------"; | |
| cout << "\n\t" << (*pBoard)[3] << " | " << (*pBoard)[4] << " | " << (*pBoard)[5]; | |
| cout << "\n\t" << "---------"; | |
| cout << "\n\t" << (*pBoard)[6] << " | " << (*pBoard)[7] << " | " << (*pBoard)[8]; | |
| cout << "\n\t"; | |
| } | |
| char winner(const vector<char>* const pBoard) | |
| { | |
| const int WINNING_ROWS[8][3] = { {0, 1, 2}, | |
| {3, 4, 5}, | |
| {6, 7, 8}, | |
| {0, 3, 6}, | |
| {1, 4, 7}, | |
| {2, 5, 8}, | |
| {0, 4, 8}, | |
| {2, 4, 6} }; | |
| const int TOTAL_ROWS = 8; | |
| for (int row = 0; row < TOTAL_ROWS; ++row) | |
| { | |
| if( ((*pBoard)[WINNING_ROWS[row][0]] != EMPTY) && | |
| ((*pBoard)[WINNING_ROWS[row][0]] == (*pBoard)[WINNING_ROWS[row][1]]) && | |
| ((*pBoard)[WINNING_ROWS[row][1]] == (*pBoard)[WINNING_ROWS[row][2]]) ) | |
| { | |
| return (*pBoard)[WINNING_ROWS[row][0]]; | |
| } | |
| } | |
| if (count(pBoard->begin(), pBoard->end(), EMPTY) == 0) | |
| return TIE; | |
| return NO_ONE; | |
| } | |
| inline bool isLegal(int move, const vector<char>* pBoard) | |
| { | |
| return ((*pBoard)[move] == EMPTY); | |
| } | |
| int humanMove(const vector<char>* const pBoard, char human) | |
| { | |
| int move = askNumber("Where will you move?", (pBoard->size() - 1)); | |
| while(!isLegal(move, pBoard)) | |
| { | |
| cout << "\nThat is not a valid move.\n"; | |
| move = askNumber("Where will you move?", (pBoard->size() - 1)); | |
| } | |
| cout << "Fine...\n"; | |
| return move; | |
| } | |
| int computerMove(vector<char> board, char computer) | |
| { | |
| cout << "I shall take square number "; | |
| for(int move = 0; move < board.size(); ++move) | |
| { | |
| if(isLegal(move, &board)) | |
| { | |
| board[move] = computer; | |
| if (winner(&board) == computer) | |
| { | |
| cout << move << endl; | |
| return move; | |
| } | |
| board[move] = EMPTY; | |
| } | |
| } | |
| char human = opponent(computer); | |
| for(int move = 0; move < board.size(); ++move) | |
| { | |
| if (isLegal(move, &board)) | |
| { | |
| board[move] = human; | |
| if (winner(&board) == human) | |
| { | |
| cout << move << endl; | |
| return move; | |
| } | |
| board[move] = EMPTY; | |
| } | |
| } | |
| const int BEST_MOVES[] = {4, 0, 2, 6, 8, 1, 3, 5, 7}; | |
| for(int i = 0; i < board.size(); ++i) | |
| { | |
| int move = BEST_MOVES[i]; | |
| if(isLegal(move, &board)) | |
| { | |
| cout << move << endl; | |
| return move; | |
| } | |
| } | |
| } | |
| void announceWinner(char winner, char computer, char human) | |
| { | |
| if (winner == computer) | |
| { | |
| cout << winner << " 's won!\n"; | |
| } | |
| else if ( winner == human) | |
| { | |
| cout << winner << " 's won!\n"; | |
| } | |
| else | |
| { | |
| cout << "It's a tie.\n"; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment