// THIS PROGRAM IS A COMPLETE TIC TAC TOE CLASS #include enum Side { Human, Computer, Empty }; enum PositionVal { HumanWin, Draw, Unclear, ComputerWin }; class TicTacToe { public: TicTacToe( ) { ClearBoard( ); } // Constructor // Find optimal move int ChooseMove( Side S, int & BestRow, int & BestColumn ); // Play move, including checking legality int PlayMove( Side S, int Row, int Column ); // Value of the current position int PositionValue( ) const; // Simple supporting routines void ClearBoard( ); int GetMove(int & Row, int & Column); // get player's move int BoardIsFull( ) const; int IsAWin( Side S ) const; void Display(); private: int Board[3][3]; // Play a move, possible claering a square void Place( int Row, int Column, int Piece = Empty ) { Board[ Row ][ Column ] = Piece; } int SquareIsEmpty( int Row, int Column ) const { return Board[ Row ][ Column ] == Empty; } }; void TicTacToe::Display() { int i; for( i = 0; i < 3; i++ ) { for( int j = 0; j < 3; j++ ) { switch (Board[ i ][ j ]) { case Computer: cout << "C"; break; case Human: cout << "H"; break; default: cout << " "; } if (j<2) cout << "|"; } cout << "\n"; if (i<2) cout << "-----\n"; } cout << "\n\n"; } int TicTacToe::PlayMove ( Side S, int Row, int Column ) { Board[Row][Column] = S; } void TicTacToe::ClearBoard ( ) { for( int i = 0; i < 3; i++ ) for( int j = 0; j < 3; j++ ) Board[ i ][ j ] = Empty; } int TicTacToe:: GetMove( int & Row, int & Column ) { int Value; cout << "Enter row and column (0, 1, 2) of move: "; cin >> Row >> Column; while (Board[Row][Column] != Empty) { cout << "\nPosition occupied, try again: "; cin >> Row >> Column; } cout << "\nThank you!\n\n"; Place (Row, Column, Human); Value = PositionValue(); // evaluate the move Place (Row, Column, Empty); return Value; } int TicTacToe::BoardIsFull( ) const { int result = 1; for( int i = 0; i < 3; i++ ) for( int j = 0; j < 3; j++ ) if (Board[i][j]==Empty) result = 0; return result; } int TicTacToe::IsAWin( Side S ) const { for( int i = 0; i < 3; i++ ) if (S==Board[i][0] && S==Board[i][1] && S==Board[i][2] || S==Board[0][i] && S==Board[1][i] && S==Board[2][i]) return 1; if (S==Board[0][0] && S==Board[1][1] && S==Board[2][2] || S==Board[0][2] && S==Board[1][1] && S==Board[2][0]) return 1; return 0; } int TicTacToe::PositionValue( ) const { if ( IsAWin( Computer ) ) return ComputerWin ; else if ( IsAWin( Human ) ) return HumanWin ; else if ( BoardIsFull( ) ) return Draw ; else return Unclear; } int TicTacToe::ChooseMove( Side S, int & BestRow, int & BestColumn ) { Side Opp; // The other side int Reply; // Value of opponent's reply int Value; // Value of best move so far int Dc; // Placeholder int SimpleEval; // Result of an immediate evaluation if( ( SimpleEval = PositionValue( ) ) != Unclear ) return SimpleEval; if( S == Computer ) { Opp = Human; Value = HumanWin; } else { Opp = Computer; Value = ComputerWin; } for( int Row = 0; Row < 3; Row++ ) for( int Column = 0; Column < 3; Column++ ) if( SquareIsEmpty( Row, Column ) ) { Place( Row, Column, S ); Reply = ChooseMove( Opp, Dc, Dc); Place( Row, Column, Empty ); if( S == Computer && Reply > Value || S == Human && Reply < Value ) { Value = Reply; BestRow = Row; BestColumn = Column; } } return Value; }