# $Id: Board.pm,v 1.1.1.1 2008/10/12 04:05:34 alamos Exp $ # The state is in an array package TicTacToe::Board; use strict; use TicTacToe::Position; use TicTacToe::Move; use base qw(Exporter); use vars qw($VERSION); $VERSION='1.0'; # Mapping to the opponent my($opponent) = { x =>'o', o => 'x'}; # Constructor sub new () { return bless { position => TicTacToe::Position->new(), player => 'o', ply => 0 }; } ## Accessors sub position($) { my $self = shift; return $self->{position}; } sub player($) { my $self = shift; return $self->{player}; } sub ply($) { my $self = shift; return $self->{ply}; } sub result { my $self = shift; if(@_) { $self->{result} = shift } return $self->{result}; } ## Subs sub apply_move($$) { my $self = shift; my $move = shift; my($value); my($result) = undef; my($new_game) = bless { position => $self->position()->child($move->square(), $self->player()), player => $opponent->{$self->player()}, ply => $self->{ply} + 1 }; if($new_game->position()->won($self->player())) { $move->value(100 - $new_game->ply()) ; $new_game->result('won'); } else { # Number of occupied squares is the value my(@blanks) = grep /^ $/, @{$new_game->position()}; if($new_game->ply() == 9) { $new_game->result('stalemate'); } $move->value($new_game->ply()); } return bless $new_game; } sub generate_moves($) { my($game)=@_; my(@squares) = $game->position()->unoccupied_squares(); $game->result('stalemate') unless(@squares); map { TicTacToe::Move->new($_) } @squares; } sub display($$) { my $self = shift; $self->position()->display(); print "Ply:", $self->ply(), "\n"; print $self->player(), " to move\n"; } 1;