This game is played on a 3 times 3 grid, which is initially empty. Each of two p
ID: 3849652 • Letter: T
Question
This game is played on a 3 times 3 grid, which is initially empty. Each of two players goes in turn. The first to start uses a cross in a blank square: the second places a nought in a blank square. The winner is the person who gets a line of three noughts or three crosses. Thus, a win for noughts can be as shown in Figure 2: Games can end in a draw, where neither side has obtained a line. Write a program to play the game. One player is the computer, which decides where to play on a random basis. Meaning you don't need to worry about the computer being smart enough to block your moves You are supposed to generate a random number (either 0 or 1). If the number was 0, then the computer begins playing. Else the human begins playing. Use an array of 9 variables to keep track of player positions. Print the grid after each move. You should use functions in the program. You don't need to worry about the computer being smart enough to block your moves.Explanation / Answer
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;
#define GRID_SIZE 3
#define INVALID -2
#define TIE -1
#define O_MARK 0
#define X_MARK 1
#define ROW_MIN 0
#define ROW_MAX 7
bool not_valid();
bool play();
int extract_column(int row, int column);
void print_grid(int grid[][GRID_SIZE]);
int same_row(int grid[][GRID_SIZE], int row);
int same_column(int grid[][GRID_SIZE], int col);
int same_diagonal1(int grid[][GRID_SIZE]);
int same_diagonal2(int grid[][GRID_SIZE]);
int count(int grid[][GRID_SIZE], int mark);
/* Main function, it starts the program */
int main(int argc, char* argv[])
{
bool play_more = true;
while (play_more)
play_more = play(); // Play until user decides to not continue.
return 0;
}
/* Shows that the game was not valid and return true.
*/
bool not_valid()
{
cout << "Not a valid Tic-Tac-Toe game!" << endl;
cout << "Play again." << endl << endl;
return true;
}
/* One round of a play.
*/
bool play()
{
int grid[GRID_SIZE][GRID_SIZE];
// Take inputs:
for (int row = 1; row <= GRID_SIZE; row++)
{
int input = -1;
while (input < ROW_MIN || input > ROW_MAX)
{
cout << "Input Row #" << row << " (Values between 0-7): ";
cin >> input;
}
// Fill the row with marks:
for (int column = 1; column <= GRID_SIZE; column++)
grid[row - 1][column - 1] = extract_column(input, column);
}
// Output the grid with marks:
cout << endl << "The following 3x3 Tic-Tac-Toe was given:" << endl << endl;
print_grid(grid);
cout << endl;
// Validy the game play:
if (count(grid, X_MARK) < (GRID_SIZE * GRID_SIZE / 2) || count(grid, O_MARK) < (GRID_SIZE * GRID_SIZE / 2))
return not_valid(); // Play once more
string output;
int won = TIE;
// Checks rows
int res = same_row(grid, 1); // 1st Row
if (res != TIE)
{
won = res;
output = "First Row Same";
}
res = same_row(grid, 2); // 2nd Row
if (res != TIE)
{
if (won != res)
return not_valid();
won = res;
output = "Second Row Same";
}
res = same_row(grid, 3); // 3rd Row
if (res != TIE)
{
if (won != TIE && won != res)
return not_valid();
won = res;
output = "Third Row Same";
}
// Check columns
res = same_column(grid, 1); // 1st Column
if (res != TIE)
{
if (won != TIE && won != res)
return not_valid();
won = res;
if (output == "")
output = "First Column Same";
}
res = same_column(grid, 2); // 2nd Column
if (res != TIE)
{
if (won != TIE && won != res)
return not_valid();
won = res;
if (output == "")
output = "Second Column Same";
}
res = same_column(grid, 3); // 3rd Column
if (res != TIE)
{
if (won != TIE && won != res)
return not_valid();
won = res;
if (output == "")
output = "Third Column Same";
}
// Check diagonals
res = same_diagonal1(grid); // 1st Diagonal
if (res != TIE)
{
if (won != TIE && won != res)
return not_valid();
won = res;
if (output == "")
output = "Diagonal left up corner to right bottom corner Same";
}
res = same_diagonal2(grid); // 2nd Diagonal
if (res != TIE)
{
if (won != TIE && won != res)
return not_valid();
won = res;
if (output == "")
output = "Diagonal right up corner to left bottom corner Same";
}
// Output result:
if (won == TIE)
cout << "It's a tie!" << endl << endl;
else
{
cout << endl << output << endl;
cout << "Who won?: " << (won == X_MARK ? "X" : "O") << endl << endl;
}
// Ask if want to play once more:
cout << "Would You like to play again? (Y/N): ";
cin >> output;
if (output == "Y" || output == "y")
return true;
return false;
}
/* Extracts mark (X or O) from the row input.
* Arguments:
* row - Input, integer from 0 to 7 inclusively.
* column - Column number, either 1 or 2 or 3.
* Returns:
* Mark in column specified, X or O.
*/
int extract_column(int row, int column)
{
return ((row >> (GRID_SIZE - column)) & 1);
}
/* Prints Tic Tac Toe board with marks.
* Arguments:
* grid - Board.
*/
void print_grid(int grid[][GRID_SIZE])
{
cout << " C1 C2 C3" << endl;
cout << " +---+---+---+" << endl;
for (int row = 1; row <= GRID_SIZE; row++)
{
cout << "R" << row << " |";
for (int column = 1; column <= GRID_SIZE; column++)
{
if (grid[row-1][column-1] == O_MARK)
cout << " O |";
else cout << " X |";
}
cout << endl << " +---+---+---+" << endl;
}
return;
}
/* Checks if the row specified in the grid is the same.
* Arguments:
* grid - The board.
* row - The row number, integer either 1 or 2 or 3.
* Returns:
* O if three Os in a row, X if three Xs in a row, -1 otherwise.
*/
int same_row(int grid[][GRID_SIZE], int row)
{
if (grid[row - 1][0] == grid[row - 1][1] && grid[row - 1][0] == grid[row - 1][2])
return grid[row - 1][0];
return TIE;
}
/* Checks if the column specified in the grid is the same.
* Arguments:
* grid - The board.
* col - The column number, integer either 1 or 2 or 3.
* Returns:
* O if three Os in a column, X if three Xs in a column, -1 otherwise.
*/
int same_column(int grid[][GRID_SIZE], int col)
{
if (grid[0][col - 1] == grid[1][col - 1] && grid[0][col - 1] == grid[2][col - 1])
return grid[0][col - 1];
return TIE;
}
/* Checks if the diagonal from left upper conner is the same.
* Arguments:
* grid - The board.
* Returns:
* O if three Os in a diagonal, X if three Xs in a diagonal, -1 otherwise.
*/
int same_diagonal1(int grid[][GRID_SIZE])
{
if (grid[0][0] == grid[1][1] && grid[0][0] == grid[2][2])
return grid[1][1];
return TIE;
}
The oder code is
#include <iostream>
#include <string>
using namespace std;
struct Board
{
unsigned short row1;
unsigned short row2;
unsigned short row3;
};
void get_rows(Board *b1);
void display_board(Board *b1);
string return_row(unsigned short row);
bool check_validity(Board *b1);
int num_ones(unsigned short row);
int main()
{
bool isInValid{};
char playAgain{};
Board *b1 = new Board{};
do
{
get_rows(b1);
display_board(b1);
isInValid = check_validity(b1);
if (isInValid)
cerr << "Not a valid Tic-Tac-Toe game! Play again. " << endl;
else
{
cout << "Would you like to play again? (Y / N): ";
cin >> playAgain;
}
}
while ( isInValid || playAgain == 'Y' || playAgain == 'y' );
return 0;
}
/**
* Gets the input from user and saves data to the board.
*/
void get_rows(Board *b1)
{
unsigned short row1, row2, row3;
// ROW1
// ====
do
{
cout << "Input Row #1 (Values between 0-7): ";
cin >> row1;
}
while (row1 < 0 || row1 > 7);
b1->row1 = row1;
// ROW2
// ====
do
{
cout << "Input Row #2 (Values between 0-7): ";
cin >> row2;
}
while (row2 < 0 || row2 > 7);
b1->row2 = row2;
// ROW3
// ====
do
{
cout << "Input Row #3 (Values between 0-7): ";
cin >> row3;
}
while (row3 < 0 || row3 > 7);
b1->row3 = row3;
};
void display_board(Board *b1)
{
cout << " C1 C2 C3 " << endl;
cout << " +---+---+---+" << endl;
cout << " R1 " << return_row(b1->row1) << endl;
cout << " +---+---+---+" << endl;
cout << " R2 " << return_row(b1->row2) << endl;
cout << " +---+---+---+" << endl;
cout << " R3 " << return_row(b1->row3) << endl;
cout << " +---+---+---+" << endl;
};
/**
* Returns a string respective to the given input.
*/
string return_row(unsigned short row)
{
switch(row)
{
case 0:
return "| O | O | O |";
case 1:
return "| O | O | X |";
case 2:
return "| O | X | 0 |";
case 3:
return "| O | X | X |";
case 4:
return "| X | O | 0 |";
case 5:
return "| X | O | X |";
case 6:
return "| X | X | 0 |";
case 7:
return "| X | X | X |";
};
};
bool check_validity(Board *b1)
{
int tot = num_ones(b1->row1) + num_ones(b1->row2) + num_ones(b1->row3);
return tot != 5 && tot != 4;
};
int num_ones(unsigned short row)
{
switch (row) {
case 0:
return 0;
case 1:
return 1;
case 2:
return 1;
case 3:
return 2;
case 4:
return 1;
case 5:
return 2;
case 6:
return 2;
case 7:
return 3;
}
};
/* Checks if the diagonal from right upper conner is the same.
* Arguments:
* grid - The board.
* Returns:
* O if three Os in a diagonal, X if three Xs in a diagonal, -1 otherwise.
*/
int same_diagonal2(int grid[][GRID_SIZE])
{
if (grid[0][2] == grid[1][1] && grid[0][2] == grid[2][0])
return grid[1][1];
return TIE;
}
/* Counts number of marks in the grid.
* Arguments:
* grid - The board.
* mark - The mark, either X (1) or O (0).
* Returns:
* The number of that mark in the grid.
*/
int count(int grid[][GRID_SIZE], int mark)
{
int i = 0;
for (int row = 0; row < GRID_SIZE; row++)
for (int col = 0; col < GRID_SIZE; col++)
if (grid[row][col] == mark)
i++;
return i;
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.