Since I'm reading the Algorithms book currently, I have it right here in front of me. All the example programs are available online from here. Get either "examples.tar.gz" or "examples.zip". After untar/zipping, the minimax algorithm is "ch05/minimax".
Aw heck, I'll just post it here too :-) (code untested by me, and it looks like you'll need the TicTacToe module included in the examples tarball)
#!/usr/bin/perl
use TicTacToe;
# Usage:
# To choose the next move:
# ($moves,$score) = minimax($position,$depth)
# You provide a game position object, and a maxmimum depth
# (number of moves) to be expanded before cutting off the
# move generation and evaluating the resulting position.
# There are two return values:
# 1: a reference to a list of moves (the last element on the
# list is the position at the end of the sequence - either
# it didn't look beyond because $depth moves were found, or
# else it is a terminating position with no moves posible.
# 2: the final score
sub minimax {
my ( $position, $depth ) = @_;
# Have we gone as far as permitted or as far as possible?
if ( $depth-- and defined($position->prepare_moves) ) {
# No - keep trying additional moves from $position.
my $move;
my $best_score = -$position->best_rating;
my $best_move_seq;
while ( defined( $move = $position->next_move ) ) {
# Evaluate the next move.
my ( $this_move_seq, $this_score ) =
minimax(
$position->make_move($move),
$depth );
# Opponent's score is opposite meaning of ours.
$this_score = -$this_score;
if ( $this_score > $best_score ) {
$best_score = $this_score;
$best_move_seq = $this_move_seq;
unshift ( @$best_move_seq, $move );
}
}
# Return the best one we found.
return ( $best_move_seq, $best_score );
} else {
# Yes - evaluate current position, no move to be taken.
return ( [ $position ], -$position->evaluate );
}
}
my $game = tic_tac_toe->new( );
my ( $moves, $score ) = minimax( $game, 2 );
my $my_move = $moves->[0];
print "I move: $my_move\n";
|