Skip to content

Instantly share code, notes, and snippets.

@KorbenC
Last active December 19, 2015 06:28
Show Gist options
  • Save KorbenC/5911281 to your computer and use it in GitHub Desktop.
Save KorbenC/5911281 to your computer and use it in GitHub Desktop.
#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