// File: game.cxx
#include <cassert> // Provides assert
#include <climits> // Provides INT_MAX and INT_MIN
#include <iostream> // Provides cin, cout
#include <queue> // Provides queue<string>
#include <string> // Provides string
#include "game.h" // Provides definition of game class
using namespace std;
namespace main_savitch_14
{
const int game::SEARCH_LEVELS;
//i have only the functions i needed for the first assignment
//i'll put the rest in when i need them
game::who game::play( )
{
restart( );
while (!is_game_over( ))
{
display_status( );
if (last_mover( ) == COMPUTER)
make_human_move( );
else
make_computer_move( );
}
display_status( );
return last_mover();
}
void game::display_message(const string& message) const
{
cout << message;
}
string game::get_user_move( ) const
{
string answer;
display_message("Your move, please: ");
getline(cin, answer);
return answer;
}
game::who game::winning( ) const
{
int value = evaluate( ); // Evaluate based on move that was just made.
if (value > 0)
return last_mover( );
else if (value < 0)
return next_mover( );
else
return NEUTRAL;
}
int game::eval_with_lookahead(int look_ahead, int beat_this)
{
queue<string> moves; // All possible opponent moves
int value; // Value of a board position after opponent moves
int best_value; // Evaluation of best opponent move
game* future; // Pointer to a future version of this game
if (look_ahead == 0 || is_game_over( ))
{
if (last_mover( ) == COMPUTER)
return evaluate( );
else
return -evaluate( );
}
compute_moves(moves);
best_value = INT_MIN;
while (!moves.empty( ))
{
future = clone( );
future->make_move(moves.front( ));
value = future->eval_with_lookahead(look_ahead-1, best_value);
delete future;
if (value > best_value)
{
if (-value <= beat_this)
return INT_MIN + 1; // Alpha-beta pruning
best_value = value;
}
moves.pop( );
}
return -best_value;
}
void game::make_computer_move( )
{
queue<string> moves;
int value;
int best_value;
string best_move;
game* future;
// Compute all legal moves that the computer could make.
compute_moves(moves);
assert(!moves.empty( ));
// Evaluate each possible legal move, saving the index of the best
// in best_index and saving its value in best_value.
best_value = INT_MIN;
while (!moves.empty( ))
{
future = clone( );
future->make_move(moves.front( ));
value = future->eval_with_lookahead(SEARCH_LEVELS, best_value);
delete future;
if (value >= best_value)
{
best_value = value;
best_move = moves.front( );
}
moves.pop( );
}
// Make the best move.
make_move(best_move);
}
void game::make_human_move( )
{
string move;
move = get_user_move( );
while (!is_legal(move))
{
display_message("Illegal move.\n");
move = get_user_move( );
}
make_move(move);
}
} //end of namespace main_savitch_14