Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

The object of Tic Tac Toe is to get three in a row. You play on a three by three

ID: 3603152 • Letter: T

Question

The object of Tic Tac Toe is to get three in a row. You play on a three by three game board. The first player is known as X and the second is O. Players alternate placing Xs and Os on the game board until either oppent has three in a row or all nine squares are filled. X always goes first, and in the event that no one has three in a row, the stalemate is called a cat game.

Create UML sequence diagrams (one per use case) and a single class diagram with all the objects from your sequence diagrams.  

Diagrams For:

Start Game

Initialize Board

Explanation / Answer

#include typedef std::array tictactoe_status; tictactoe_status const strategy_x[] = { {1,0,0,0,0,0,0,0,0}, {1,2,0,0,1,0,0,0,0}, {1,2,2,0,1,0,0,0,1}, {1,2,0,2,1,0,0,0,1}, // ... }; tictactoe_status const strategy_o[] = { {2,0,0,0,1,0,0,0,0}, {2,2,1,0,1,0,0,0,0}, {2,2,1,2,1,0,1,0,0}, {2,2,1,0,1,2,1,0,0}, // ... }; tictactoe_status const strategy_x[] = { #include "strategy_x.h" }; tictactoe_status const strategy_o[] = { #include "strategy_o.h" }; std::vector strategy_o = { {2, 0, 0, 0, 1, 0, 0, 0, 0}, {2, 2, 1, 0, 1, 0, 0, 0, 0}, {2, 2, 1, 2, 1, 0, 1, 0, 0}, {2, 2, 1, 0, 1, 2, 1, 0, 0}, {2, 2, 1, 1, 1, 0, 2, 0, 0}, }; enum class tictactoe_player : char { none = 0, computer = 1, user = 2, }; class tictactoe_game { bool started; tictactoe_status status; std::set strategy; // ... }; bool is_started() const {return started;} bool is_victory(tictactoe_player const player) const {return is_winning(status, player);} bool is_finished() const { return is_full(status) || is_victory(tictactoe_player::user) || is_victory(tictactoe_player::computer); } bool is_winning(tictactoe_status const & status, tictactoe_player const player) const { auto mark = static_cast(player); return (status[0] == mark && status[1] == mark && status[2] == mark) || (status[3] == mark && status[4] == mark && status[5] == mark) || (status[6] == mark && status[7] == mark && status[8] == mark) || (status[0] == mark && status[4] == mark && status[8] == mark) || (status[2] == mark && status[4] == mark && status[6] == mark) || (status[0] == mark && status[3] == mark && status[6] == mark) || (status[1] == mark && status[4] == mark && status[7] == mark) || (status[2] == mark && status[5] == mark && status[8] == mark); } bool is_full(tictactoe_status const & status) const { return 0 == std::count_if(std::begin(status), std::end(status), [](int const mark){return mark == 0;}); } struct tictactoe_cell { int row; int col; tictactoe_cell(int r = INT_MAX, int c = INT_MAX):row(r), col(c) {} bool is_valid() const {return row != INT_MAX && col != INT_MAX;} }; std::pair const get_winning_line() const { auto mark = static_cast(tictactoe_player::none); if(is_victory(tictactoe_player::computer)) mark = static_cast(tictactoe_player::computer); else if(is_victory(tictactoe_player::user)) mark = static_cast(tictactoe_player::user); if(mark != 0) { if(status[0] == mark && status[1] == mark && status[2] == mark) return std::make_pair(tictactoe_cell(0,0), tictactoe_cell(0,2)); if(status[3] == mark && status[4] == mark && status[5] == mark) return std::make_pair(tictactoe_cell(1,0), tictactoe_cell(1,2)); if(status[6] == mark && status[7] == mark && status[8] == mark) return std::make_pair(tictactoe_cell(2,0), tictactoe_cell(2,2)); if(status[0] == mark && status[4] == mark && status[8] == mark) return std::make_pair(tictactoe_cell(0,0), tictactoe_cell(2,2)); if(status[2] == mark && status[4] == mark && status[6] == mark) return std::make_pair(tictactoe_cell(0,2), tictactoe_cell(2,0)); if(status[0] == mark && status[3] == mark && status[6] == mark) return std::make_pair(tictactoe_cell(0,0), tictactoe_cell(2,0)); if(status[1] == mark && status[4] == mark && status[7] == mark) return std::make_pair(tictactoe_cell(0,1), tictactoe_cell(2,1)); if(status[2] == mark && status[5] == mark && status[8] == mark) return std::make_pair(tictactoe_cell(0,2), tictactoe_cell(2,2)); } return std::make_pair(tictactoe_cell(), tictactoe_cell()); } void start(tictactoe_player const player) { strategy.clear(); if(player == tictactoe_player::computer) std::copy(std::begin(strategy_x), std::end(strategy_x), std::inserter(strategy, std::begin(strategy))); else if(player == tictactoe_player::user) std::copy(std::begin(strategy_o), std::end(strategy_o), std::inserter(strategy, std::begin(strategy))); status.assign(0); started = true; } ool move(tictactoe_cell const cell, tictactoe_player const player) { if(status[cell.row*3 + cell.col] == 0) { status[cell.row*3 + cell.col] = static_cast(player); if(is_victory(player)) { started = false; } return true; } return false; } tictactoe_cell move(tictactoe_player const player) { tictactoe_cell cell; strategy = lookup_strategy(); if(!strategy.empty()) { auto newstatus = lookup_move(); for(int i = 0; i < 9; ++i) { if(status[i] == 0 && newstatus[i]==static_cast(player)) { cell.row = i/3; cell.col = i%3; break; } } status = newstatus; if(is_victory(player)) { started = false; } } return cell; } std::set tictactoe_game::lookup_strategy() const { std::set nextsubstrategy; for(auto const & s : strategy) { bool match = true; for(int i = 0; i < 9 && match; ++i) { if(s[i] status[i]) diff++; } if(diff == 1) { newbest = s; if(is_winning(newbest, tictactoe_player::computer)) { break; } } } assert(newbest != empty_board); return newbest; }