online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code   
Language
#include "ai_player.h" #include "board.h" #include "global_data.h" #include "player.h" #include <cassert> #include <vector> GameModes get_game_mode(); void handle_move(Player* player, Board& board); void check_game_state(const Board& board, const Player* player_one, const Player* player_two, bool& is_game_running, bool& can_play); void play(bool& is_game_running, Player* player_one, Player* player_two, Board& board); int main() { enum Players { player_one, player_two, computer_one, computer_two, }; std::vector<Player*> list_of_players(4); bool is_player_vs_player{ false }; GameModes game_mode{ get_game_mode() }; if (game_mode == GameModes::player_vs_player) { is_player_vs_player = true; list_of_players[player_one] = new Player{ "Player 1", BoardState::x }; list_of_players[player_two] = new Player{ "Player 2", BoardState::o }; } bool is_player_vs_computer{ false }; if (game_mode == GameModes::player_vs_computer) { is_player_vs_computer = true; list_of_players[player_one] = new Player{ "Player 1", BoardState::x }; list_of_players[computer_one] = new AIPlayer{ "Computer", BoardState::o }; } bool is_computer_vs_computer{ false }; if (game_mode == GameModes::computer_vs_computer) { is_computer_vs_computer = true; list_of_players[computer_one] = new AIPlayer{ "Computer 1", BoardState::x }; list_of_players[computer_two] = new AIPlayer{ "Computer 2", BoardState::o }; } Board board{}; board.display(); bool is_game_running{ true }; while (is_game_running) { if (is_player_vs_player) play(is_game_running, list_of_players[player_one], list_of_players[player_two], board); if (is_player_vs_computer) play(is_game_running, list_of_players[player_one], list_of_players[computer_one], board); if (is_computer_vs_computer) play(is_game_running, list_of_players[computer_one], list_of_players[computer_two], board); } for (std::size_t index{ 0 }; index < list_of_players.size(); ++index) delete list_of_players[index]; return 0; } GameModes get_game_mode() { while (true) { print_text("TIC TAC TOE\n"); print_text("0. Player vs Player"); print_text("1. Player vs Computer"); print_text("2. Computer vs Computer"); print_text("\nSelect a game mode: ", false); int input{}; std::cin >> input; if (std::cin.fail()) { input_failed(); continue; } if (input >= player_vs_player && input <= computer_vs_computer) { ignore_line(); return list_of_game_modes[input]; } print_text("Invalid."); } } void handle_move(Player* player, Board& board) { assert(player != nullptr && "A player deosn't exist"); board.update(player->get_board_position(board), player->place_marker()); } void check_game_state(const Board& board, const Player* player_one, const Player* player_two, bool& is_game_running, bool& can_play) { assert(player_one != nullptr && player_two != nullptr && "The player's don't exist"); // Draw if (board.is_board_filled() && !board.is_game_won(player_one->place_marker()) && !board.is_game_won(player_two->place_marker())) { print_text("The game is a draw."); can_play = false; is_game_running = false; } // Player 1 won if (board.is_game_won(player_one->place_marker())) { player_one->display_winner(); can_play = false; is_game_running = false; } // Player 2 won if (board.is_game_won(player_two->place_marker())) { player_two->display_winner(); can_play = false; is_game_running = false; } } void play(bool& is_game_running, Player* player_one, Player* player_two, Board& board) { assert(player_one != nullptr && player_two != nullptr && "The player's don't exist"); bool can_player_one_play{ true }; bool can_player_two_play{ true }; if (can_player_one_play) { handle_move(player_one, board); check_game_state(board, player_one, player_two, is_game_running, can_player_two_play); board.display(); } if (can_player_two_play) { handle_move(player_two, board); check_game_state(board, player_one, player_two, is_game_running, can_player_one_play); board.display(); } }
#pragma once #include <array> #include <iostream> #include <string_view> enum class BoardState { empty, x, o, }; enum class GameModes { player_vs_player, player_vs_computer, computer_vs_computer }; inline constexpr std::array list_of_game_modes{ GameModes::player_vs_player, GameModes::player_vs_computer, GameModes::computer_vs_computer }; inline constexpr int player_vs_player{ 0 }; inline constexpr int player_vs_computer{ 1 }; inline constexpr int computer_vs_computer{ 2 }; inline constexpr int min_board_position{ 0 }; inline constexpr int max_board_position{ 8 }; inline constexpr std::size_t board_size{ 9 }; inline void ignore_line() { std::cin.ignore(100, '\n'); } inline void input_failed() { std::cin.clear(); ignore_line(); } inline void print_text(std::string_view prompt, bool print_newline = true) { if (print_newline) { std::cout << prompt << "\n"; } else { std::cout << prompt; } }
#pragma once #include "global_data.h" #include <array> #include <string> class Board { public: Board(); void display() const; bool is_board_position_empty(std::size_t& board_position) const; bool is_board_filled() const; bool is_game_won(BoardState marker) const; void update(std::size_t board_position, BoardState marker); private: std::string board_state_to_string(BoardState state) const; private: std::array<BoardState, board_size> data_{ BoardState::empty, BoardState::empty, BoardState::empty, BoardState::empty, BoardState::empty, BoardState::empty, BoardState::empty, BoardState::empty, BoardState::empty }; };
#include "board.h" #include "global_data.h" #include <cassert> #include <iostream> #include <string> Board::Board() { assert(data_.size() == board_size && "board size must equal 9"); } void Board::display() const { for (std::size_t index{ 0 }; index < data_.size(); ++index) { if (index % 3 == 0) std::cout << "\n"; std::cout << "[ " << board_state_to_string(data_[index]) << " ]" << " "; } std::cout << "\n\n"; } bool Board::is_board_position_empty(std::size_t& board_position) const { assert(board_position >= min_board_position && board_position <= max_board_position && "out of bounds board position"); if (data_[board_position] == BoardState::empty) return true; return false; } bool Board::is_board_filled() const { for (std::size_t index{ 0 }; index < data_.size(); ++index) { if (data_[index] == BoardState::empty) return false; } return true; } bool Board::is_game_won(BoardState marker) const { enum BoardPositions { zero, one, two, three, four, five, six, seven, eight, nine, }; // [0] [1] [2] // [ ] [ ] [ ] // [ ] [ ] [ ] if (data_[zero] == marker && data_[one] == marker && data_[two] == marker) return true; // [ ] [ ] [ ] // [3] [4] [5] // [ ] [ ] [ ] if (data_[three] == marker && data_[four] == marker && data_[five] == marker) return true; // [ ] [ ] [ ] // [ ] [ ] [ ] // [6] [7] [8] if (data_[six] == marker && data_[seven] == marker && data_[eight] == marker) return true; // [0] [ ] [ ] // [3] [ ] [ ] // [6] [ ] [ ] if (data_[zero] == marker && data_[three] == marker && data_[six] == marker) return true; // [ ] [1] [ ] // [ ] [4] [ ] // [ ] [7] [ ] if (data_[one] == marker && data_[four] == marker && data_[seven] == marker) return true; // [ ] [ ] [2] // [ ] [ ] [5] // [ ] [ ] [8] if (data_[two] == marker && data_[five] == marker && data_[eight] == marker) return true; // [0] [ ] [ ] // [ ] [4] [ ] // [ ] [ ] [8] if (data_[zero] == marker && data_[four] == marker && data_[eight] == marker) return true; // [ ] [ ] [2] // [ ] [4] [ ] // [6] [ ] [ ] if (data_[two] == marker && data_[four] == marker && data_[six] == marker) return true; return false; } void Board::update(std::size_t board_position, BoardState marker) { assert(board_position >= min_board_position && board_position <= max_board_position && "out of bounds board position"); data_[board_position] = marker; } std::string Board::board_state_to_string(BoardState state) const { switch (state) { case BoardState::empty: return " "; case BoardState::x: return "X"; case BoardState::o: return "O"; default: return "ERROR"; } }
#pragma once #include "player.h" #include "board.h" #include "global_data.h" #include <string> #include <string_view> class Player { public: Player(std::string_view name, BoardState marker = BoardState::x); virtual std::size_t get_board_position(Board& board); virtual BoardState place_marker() const; virtual void display_winner() const; protected: std::string name_{ "???" }; BoardState marker_{ BoardState::empty }; };
#include "player.h" #include "board.h" #include "global_data.h" #include <cassert> #include <iostream> #include <string_view> Player::Player(std::string_view name, BoardState marker) : name_{ name }, marker_{ marker } { assert(marker_ != BoardState::empty && "marker_ must either be x or o"); } std::size_t Player::get_board_position(Board& board) { while (true) { std::cout << name_ << ": "; std::size_t board_position{}; std::cin >> board_position; if (std::cin.fail()) { input_failed(); continue; } if (!board.is_board_position_empty(board_position)) { print_text("This position is already taken."); continue; } if (board_position >= min_board_position && board_position <= max_board_position) { ignore_line(); return board_position; } print_text("Valid positions are between 0 and 8."); } } BoardState Player::place_marker() const { return marker_; } void Player::display_winner() const { print_text(name_, false); print_text(" has won.", false); }
#pragma once #include "board.h" #include "player.h" #include "global_data.h" #include <string_view> class AIPlayer : public Player { public: AIPlayer(std::string_view name = "Computer", BoardState marker = BoardState::o); std::size_t get_board_position(Board& board) override; private: int mini_max(Board& board, bool is_maximizer); };
#include "ai_player.h" #include "board.h" #include "player.h" #include "global_data.h" #include <algorithm> #include <random> #include <string_view> AIPlayer::AIPlayer(std::string_view name, BoardState marker) : Player{ name, marker } { } std::size_t AIPlayer::get_board_position(Board& board) { int best_score{ -1000 }; std::size_t best_move{}; for (std::size_t index{ 0 }; index < board_size; ++index) { if (board.is_board_position_empty(index)) { board.update(index, marker_); int score = mini_max(board, false); board.update(index, BoardState::empty); if (score > best_score) { best_score = score; best_move = index; } } } return best_move; } int AIPlayer::mini_max(Board& board, bool is_maximizer) { BoardState opponent = (marker_ == BoardState::x) ? BoardState::o : BoardState::x; // First check game state if (board.is_game_won(marker_)) return 1; if (board.is_game_won(opponent)) return -1; if (board.is_board_filled()) return 0; if (is_maximizer) { int best_score = -1000; for (std::size_t index = 0; index < board_size; ++index) { if (board.is_board_position_empty(index)) { board.update(index, marker_); int score = mini_max(board, false); board.update(index, BoardState::empty); best_score = std::max(best_score, score); } } return best_score; } else { int best_score = 1000; for (std::size_t index = 0; index < board_size; ++index) { if (board.is_board_position_empty(index)) { board.update(index, opponent); int score = mini_max(board, true); board.update(index, BoardState::empty); best_score = std::min(best_score, score); } } return best_score; } }

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text
×

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue