Strategy
久々のエントリ。もう一つは時間の都合で移し変えず、同じstrategyで勝負しています。
use strict; use warnings; { package Hand; use strict; use warnings; my $GUU = 0; my $CHO = 1; my $PAA = 2; my $hand = [ Hand->new($GUU), Hand->new($CHO), Hand->new($PAA), ]; sub new { my ($class, $hand) = @_; my $self = { hand => $hand, }; return bless $self, $class; } sub getHand { my ($class, $value) = @_; return $hand->[$value]; } sub isStrongerThan { my ($self, $enemy) = @_; return $self->fight($enemy) == 1; } sub isWeakerThan { my ($self, $enemy) = @_; return $self->fight($enemy) == -1; } sub fight { my ($self, $enemy) = @_; if($self->{hand} == $enemy->{hand}){ return 0; } elsif(($self->{hand} + 1) % 3 == $enemy->{hand}){ return 1; } else { return -1; } } } { package Strategy; use strict; use warnings; sub study { die; } sub nextHand { die; } } { package WinningStrategy; use strict; use warnings; our @ISA = qw/Strategy/; sub new { my($class, $seed) = @_; my $self = { random => int(rand($seed)), won => 0, prevHand => '', }; return bless $self, $class; } sub nextHand { my $self = shift; if(!$self->{won}){ $self->{prevHand} = Hand->getHand(int(rand(3))); } return $self->{prevHand}; } sub study { my ($self, $result) = @_; $self->{won} = $result; } } { package Player; use strict; use warnings; sub new { my ($class, $name, $strategy) = @_; my $self = { name => $name, strategy => $strategy, wincount => 0, losecount => 0, gamecount => 0, }; return bless $self, $class; } sub nextHand { my $self = shift; return $self->{strategy}->nextHand(); } sub win { my $self = shift; $self->{strategy}->study(1); $self->{wincount}++; $self->{gamecount}++; } sub lose { my $self = shift; $self->{strategy}->study(0); $self->{gamecount}++; } sub even { my $self = shift; $self->{gamecount}++; } sub toString { my $self = shift; return "[".$self->{name}.":". $self->{gamecount}." games, ". $self->{wincount}." win, ". $self->{losecount}." lose]"; } } my @foo = qw/GOO CHO PAA/; my $player01 = Player->new("Taro", WinningStrategy->new(0)); my $player02 = Player->new("Jiro", WinningStrategy->new(0)); for(1..1000){ my $nextHand01 = $player01->nextHand(); my $nextHand02 = $player02->nextHand(); print $foo[$nextHand01->{hand}],"\n"; print $foo[$nextHand02->{hand}],"\n"; if($nextHand01->isStrongerThan($nextHand02)){ print "Winner --> ".$player01->{name}."\n"; $player01->win(); $player02->lose(); } elsif($nextHand01->isWeakerThan($nextHand02)){ print "Winner --> ".$player02->{name}."\n"; $player01->lose(); $player02->win(); } else { print "Even..\n"; $player01->even(); $player02->even(); } } print "\n"; print $player01->toString(),"\n"; print $player02->toString(),"\n";