Question

In: Computer Science

In the C++ programming language write a program capable of playing Tic-Tac-Toe against the user. Your...

In the C++ programming language write a program capable of playing Tic-Tac-Toe against the user. Your program should use OOP concepts in its design. You can use ASCII art to generate and display the 3x3 playing board. The program should randomly decide who goes first computer or user. Your program should know and inform the user if an illegal move was made (cell already occupied). The program should also announce if one of the players wins or if a draw is achieved. While it is desirable for your program to play a strong game, this is not an Artificial Intelligence course so if your program does not play at a world champion level you will not be penalized for it

Solutions

Expert Solution

#include <iostream>

#include <algorithm>

#include <vector>

#include <array>

using std::cout;

using std::cin;

using std::endl;

#define WIN 1000

#define DRAW 0

#define LOSS -1000

#define AI_MARKER 'O'

#define PLAYER_MARKER 'X'

#define EMPTY_SPACE '-'

#define START_DEPTH 0

// Print game state

void print_game_state(int state)

{

  if (WIN == state) { cout << "WIN" << endl; }

  else if (DRAW == state) { cout << "DRAW" << endl; }

  else if (LOSS == state) { cout << "LOSS" << endl; }

}

// All possible winning states

std::vector<std::vector<std::pair<int, int>>> winning_states

{

  // Every row

  { std::make_pair(0, 0), std::make_pair(0, 1), std::make_pair(0, 2) },

  { std::make_pair(1, 0), std::make_pair(1, 1), std::make_pair(1, 2) },

  { std::make_pair(2, 0), std::make_pair(2, 1), std::make_pair(2, 2) },

  // Every column

  { std::make_pair(0, 0), std::make_pair(1, 0), std::make_pair(2, 0) },

  { std::make_pair(0, 1), std::make_pair(1, 1), std::make_pair(2, 1) },

  { std::make_pair(0, 2), std::make_pair(1, 2), std::make_pair(2, 2) },

  // Every diagonal

  { std::make_pair(0, 0), std::make_pair(1, 1), std::make_pair(2, 2) },

  { std::make_pair(2, 0), std::make_pair(1, 1), std::make_pair(0, 2) }

};

// Print the current board state

void print_board(char board[3][3])

{

  cout << endl;

  cout << board[0][0] << " | " << board[0][1] << " | " << board[0][2] << endl;

  cout << "----------" << endl;

  cout << board[1][0] << " | " << board[1][1] << " | " << board[1][2] << endl;

  cout << "----------" << endl;

  cout << board[2][0] << " | " << board[2][1] << " | " << board[2][2] << endl << endl;

}

// Get all available legal moves (spaces that are not occupied)

std::vector<std::pair<int, int>> get_legal_moves(char board[3][3])

{

  std::vector<std::pair<int, int>> legal_moves;

  for (int i = 0; i < 3; i++)

  {

    for (int j = 0; j < 3; j++)

    {

      if (board[i][j] != AI_MARKER && board[i][j] != PLAYER_MARKER)

      {

        legal_moves.push_back(std::make_pair(i, j));

      }

    }

  }

  return legal_moves;

}

// Check if a position is occupied

bool position_occupied(char board[3][3], std::pair<int, int> pos)

{

  std::vector<std::pair<int, int>> legal_moves = get_legal_moves(board);

  for (int i = 0; i < legal_moves.size(); i++)

  {

    if (pos.first == legal_moves[i].first && pos.second == legal_moves[i].second)

    {

      return false;

    }

  }

  return true;

}

// Get all board positions occupied by the given marker

std::vector<std::pair<int, int>> get_occupied_positions(char board[3][3], char marker)

{

  std::vector<std::pair<int, int>> occupied_positions;

  for (int i = 0; i < 3; i++)

  {

    for (int j = 0; j < 3; j++)

    {

      if (marker == board[i][j])

      {

        occupied_positions.push_back(std::make_pair(i, j));

      }

    }

  }

  return occupied_positions;

}

// Check if the board is full

bool board_is_full(char board[3][3])

{

  std::vector<std::pair<int, int>> legal_moves = get_legal_moves(board);

  if (0 == legal_moves.size())

  {

    return true;

  }

  else

  {

    return false;

  }

}

// Check if the game has been won

bool game_is_won(std::vector<std::pair<int, int>> occupied_positions)

{

  bool game_won;

  for (int i = 0; i < winning_states.size(); i++)

  {

    game_won = true;

    std::vector<std::pair<int, int>> curr_win_state = winning_states[i];

    for (int j = 0; j < 3; j++)

    {

      if (!(std::find(std::begin(occupied_positions), std::end(occupied_positions), curr_win_state[j]) != std::end(occupied_positions)))

      {

        game_won = false;

        break;

      }

    }

    if (game_won)

    {

      break;

    }

  }

  return game_won;

}

char get_opponent_marker(char marker)

{

  char opponent_marker;

  if (marker == PLAYER_MARKER)

  {

    opponent_marker = AI_MARKER;

  }

  else

  {

    opponent_marker = PLAYER_MARKER;

  }

  return opponent_marker;

}

// Check if someone has won or lost

int get_board_state(char board[3][3], char marker)

{

  char opponent_marker = get_opponent_marker(marker);

  std::vector<std::pair<int, int>> occupied_positions = get_occupied_positions(board, marker);

  bool is_won = game_is_won(occupied_positions);

  if (is_won)

  {

    return WIN;

  }

  occupied_positions = get_occupied_positions(board, opponent_marker);

  bool is_lost = game_is_won(occupied_positions);

  if (is_lost)

  {

    return LOSS;

  }

  bool is_full = board_is_full(board);

  if (is_full)

  {

    return DRAW;

  }

  return DRAW;

}

// Apply the minimax game optimization algorithm

std::pair<int, std::pair<int, int>> minimax_optimization(char board[3][3], char marker, int depth, int alpha, int beta)

{

  // Initialize best move

  std::pair<int, int> best_move = std::make_pair(-1, -1);

  int best_score = (marker == AI_MARKER) ? LOSS : WIN;

  // If we hit a terminal state (leaf node), return the best score and move

  if (board_is_full(board) || DRAW != get_board_state(board, AI_MARKER))

  {

    best_score = get_board_state(board, AI_MARKER);

    return std::make_pair(best_score, best_move);

  }

  std::vector<std::pair<int, int>> legal_moves = get_legal_moves(board);

  for (int i = 0; i < legal_moves.size(); i++)

  {

    std::pair<int, int> curr_move = legal_moves[i];

    board[curr_move.first][curr_move.second] = marker;

    // Maximizing player's turn

    if (marker == AI_MARKER)

    {

      int score = minimax_optimization(board, PLAYER_MARKER, depth + 1, alpha, beta).first;

      // Get the best scoring move

      if (best_score < score)

      {

        best_score = score - depth * 10;

        best_move = curr_move;

        // Check if this branch's best move is worse than the best

        // option of a previously search branch. If it is, skip it

        alpha = std::max(alpha, best_score);

        board[curr_move.first][curr_move.second] = EMPTY_SPACE;

        if (beta <= alpha)

        {

          break;

        }

      }

    } // Minimizing opponent's turn

    else

    {

      int score = minimax_optimization(board, AI_MARKER, depth + 1, alpha, beta).first;

      if (best_score > score)

      {

        best_score = score + depth * 10;

        best_move = curr_move;

        // Check if this branch's best move is worse than the best

        // option of a previously search branch. If it is, skip it

        beta = std::min(beta, best_score);

        board[curr_move.first][curr_move.second] = EMPTY_SPACE;

        if (beta <= alpha)

        {

          break;

        }

      }

    }

    board[curr_move.first][curr_move.second] = EMPTY_SPACE; // Undo move

  }

  return std::make_pair(best_score, best_move);

}

// Check if the game is finished

bool game_is_done(char board[3][3])

{

  if (board_is_full(board))

  {

    return true;

  }

  if (DRAW != get_board_state(board, AI_MARKER))

  {

    return true;

  }

  return false;

}


int main()

{

  char board[3][3] = { EMPTY_SPACE };

  cout << "********************************\n\n\tTic Tac Toe AI\n\n********************************" << endl << endl;

  cout << "Player = X\t AI Computer = O" << endl << endl;

  print_board(board);

  while (!game_is_done(board))

  {

    int row, col;

    cout << "Row play: ";

    cin >> row;

    cout << "Col play: ";

    cin >> col;

    cout << endl << endl;

    if (position_occupied(board, std::make_pair(row, col)))

    {

      cout << "The position (" << row << ", " << col << ") is occupied. Try another one..." << endl;

      continue;

    }

    else

    {

      board[row][col] = PLAYER_MARKER;

    }

    std::pair<int, std::pair<int, int>> ai_move = minimax_optimization(board, AI_MARKER, START_DEPTH, LOSS, WIN);

    board[ai_move.second.first][ai_move.second.second] = AI_MARKER;

    print_board(board);

  }

  cout << "********** GAME OVER **********" << endl << endl;

  int player_state = get_board_state(board, PLAYER_MARKER);

  cout << "PLAYER "; print_game_state(player_state);

  return 0;

}


Related Solutions

Programming assignment (100 pts): In the C++ programming language write a program capable of playing Tic-Tac-Toe...
Programming assignment (100 pts): In the C++ programming language write a program capable of playing Tic-Tac-Toe against the user. Your program should use OOP concepts in its design. You can use ASCII art to generate and display the 3x3 playing board. The program should randomly decide who goes first computer or user. Your program should know and inform the user if an illegal move was made (cell already occupied). The program should also announce if one of the players wins...
Write a program that plays tic-tac-toe. The tic-tac-toe game is played on a 3 × 3...
Write a program that plays tic-tac-toe. The tic-tac-toe game is played on a 3 × 3 grid as shown below: The game is played by two players, who take turns. The first player marks moves with a circle, the second with a cross. The player who has formed a horizontal, vertical, or diagonal sequence of three marks wins. Your program should draw the game board, ask the user for the coordinates of the next mark (their move), change the players...
Write a Java program to play the game Tic-Tac-Toe. Start off with a human playing a...
Write a Java program to play the game Tic-Tac-Toe. Start off with a human playing a human, so each player makes their own moves. Follow the design below, creating the methods indicated and invoking them in the main program. Use a char array of size 9 as the board; initialize with the characters 0 to 8 so that it starts out looking something like the board on the left. 0|1|2 3|4|5 6|7|8 and then as moves are entered the board...
Using C language Problem!! <3 x 3 tic tac toe> 2 players are doing tic tac...
Using C language Problem!! <3 x 3 tic tac toe> 2 players are doing tic tac toe alternatively. Anyone could win when they first make a bingo for any line(horizontal, vertical, diagonal) [Constraints] 1. Use 2dimensional Array(3 X 3) 2. Each elements are 1 or 2 so that can show their player1, player2's mark. 3. Inputs are 1 through 9 as you can see 1 2 3 4 5 6 7 8 9 4. No inputs are duplicated 5. if...
PYTHON (Game: Tic-tac-toe): Write a program that plays the tic-tac-toe game. Two players take turns clicking...
PYTHON (Game: Tic-tac-toe): Write a program that plays the tic-tac-toe game. Two players take turns clicking an available cell in a 3 x 3 grid with their respective tokens (either X or O). When one player has placed three tokens in a horizontal, vertical, or diagonal row on the grid, the game is over and that player has won. A draw (no winner) occurs when all the cells in the grid have been filled with tokens and neither player has...
The objective of this assignment is to implement the tic-tac-toe game with a C program. The...
The objective of this assignment is to implement the tic-tac-toe game with a C program. The game is played by two players on a board defined as a 5x5 grid (array). Each board position can contain one of two possible markers, either ‘X’ or ‘O’. The first player plays with ‘X’ while the second player plays with ‘O’. Players place their markers in an empty position of the board in turns. The objective is to place 5 consecutive markers of...
I need a good pseudocode for C++ for a tic tac toe program.
I need a good pseudocode for C++ for a tic tac toe program.
Python: Write a program that plays Tic-tac-toe with a user. Each round, the game prints out...
Python: Write a program that plays Tic-tac-toe with a user. Each round, the game prints out the state of the board, asks the user where they would like to place their mark, and implements this decision. The program then places its own mark on a randomly chosen available position. Once one of the player won, the program declares the result and asks if the user would like to continue. The first player is selected at random.
In C# A Tic Tac Toe program that uses functions and arrays. The program should start...
In C# A Tic Tac Toe program that uses functions and arrays. The program should start by asking the player one for their name and then player two for their name. Then should print the board and ask the user what column and then what row they would like to put their x (or o, depending on the player) . Use the clear function to make it look as though the board is never repeating.. Thanks!
Write a LISP program to play the game Tic-Tac-Toe on a size 4x4 game board. Your...
Write a LISP program to play the game Tic-Tac-Toe on a size 4x4 game board. Your program must use min-max search and should be invoked by the function call: > (Tic-Tac-Toe) The game is single player, human vs the computer AI.
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT