Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- using namespace std;
- // constants for rows and columns of tic-tac-toe board
- const int ROWS = 3;
- const int COLS = 3;
- enum eGameState { TIE = -1, PLAY, WON }; // make things easier to read
- // function headers
- void outputBoard(char board[ROWS][COLS]);
- bool processPlayerInput(char player, char board[ROWS][COLS], int* gameState, int numTurnsbool);
- int hasPlayerWon(int userRow, int userColumn, int numTurns, char board[ROWS][COLS]);
- void gameHasEnded(int gameState, char player);
- int main()
- {
- int gameState = PLAY; // flag for game has been won
- int numTurns = 0; // initialize turn counter
- char player = 'X'; // player X starts
- char board[ROWS][COLS]; // initialize our tic-tac-toe board
- memset(board, '*', sizeof(board)); // assign * to every element in the array without an ugly array initialization list
- outputBoard(board); // output board initially
- do
- {
- if ( processPlayerInput(player, board, &gameState, numTurns) ) // was the last turn valid?
- {
- numTurns++; // increment number of turns
- player = ( player == 'X' ) ? 'O' : 'X'; // swap player after the turn
- }
- system("cls"); // redraw screen
- outputBoard(board); // output updated board
- } while (gameState == PLAY); // repeat while the game hasn't won
- gameHasEnded(gameState, player); // game is done! handle it
- system("pause"); // wait for user exit (assuming the user did not launch this via "Start without debugging...", they can see the final result)
- return 0; // obligatory return after the game has ended
- }
- void outputBoard(char board[ROWS][COLS])
- {
- cout << "\n\n\n\n\tCol: 1 2 3" << endl; // label columns
- cout << "\tRow:" << endl; //create row under it
- for(int row = 0; row < 3; row++) // output rows
- {
- cout << "\t" << (row+1) << " "; // label rows
- for(int col = 0; col < 3; col++) // output columns
- {
- cout << board[row][col] << " "; // output board
- }
- cout << endl << endl; // new line for input line
- }
- }
- bool processPlayerInput(char player, char board[ROWS][COLS], int* gameState, int numTurns)
- {
- // initialize user row & column selection variables
- int userRow = 0;
- int userColumn = 0;
- // ask user for input and store
- cout << "\tIt's " << player << "'s turn." << endl;
- cout << "\tEnter row and column:" << endl << endl;
- cout << "\tRow: ";
- cin >> userRow;
- cout << "\tColumn: ";
- cin >> userColumn;
- userRow--; // decrement by 1 for proper use
- userColumn--; // decrement by 1 for proper use
- // check that input is valid (both row and column are between 0 and 2) and that the user isn't trying to overwrite an already played spot on the board
- if (userRow >= 0 && userRow <= 2 && userColumn >=0 && userColumn <=2 && board[userRow][userColumn] == '*')
- {
- board[userRow][userColumn] = player; // fill in user's choice
- *gameState = hasPlayerWon(userRow, userColumn, numTurns, board); // check if player has won
- return true; // turn is valid
- }
- cout << "Invalid option.\n";
- system("pause"); // pause program and wait for user acknowledgement, since screen is redrawn after each turn and without this pause, the user wouldn't see the "Invalid option." text
- return false; // turn is invalid
- }
- int hasPlayerWon(int userRow, int userColumn, int numTurns, char board[ROWS][COLS])
- {
- if (board [0][userColumn] == board [1][userColumn] && board [0][userColumn] == board [2][userColumn]) // check if one columns are equal (check if they are in a row)
- {
- return WON;
- }
- else if (board [userRow][0] == board [userRow][1] && board[userRow][0] == board [userRow][2]) // check if one row is equal
- {
- return WON;
- }
- else if (board [0][0] == board [1][1] && board [0][0] == board [2][2] && board [0][0] != '*') // check top left -> bottom right
- {
- return WON;
- }
- else if (board [0][2] == board [1][1] && board [0][2] == board [2][0] && board [0][2] != '*') // check bottom left -> top right
- {
- return WON;
- }
- else if (numTurns >= ROWS*COLS - 1) // turns start at 0, end at 8 - check if we have gone 9 turns; if so, there is a tie
- {
- return TIE;
- }
- return PLAY; // return PLAY in case something breaks
- }
- void gameHasEnded(int gameState, char player)
- {
- int asked;
- player = ((player == 'X' ) ? 'O' : 'X'); // swap the player again since processPlayerInput always returns the next player
- switch (gameState)
- {
- case TIE:
- cout << "Tie! Thanks for playing, better luck next time." << endl;
- break;
- case WON:
- cout << player << " has won! Congratulations." << endl;
- break;
- }
- cout << "Would you like to play again?" << endl;
- cout << "Enter 1 for yes and 0 for no" << endl;
- cin >> asked;
- if (asked==1)
- {
- main();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement