http://www.perlmonks.org?node_id=66499

Sprad has asked for the wisdom of the Perl Monks concerning the following question:

I need some help getting started with a program I'd like to write. My question has little to do directly with Perl, (aside from the fact that I'll be using Perl to write the program) but I hope you'll find the question interesting and permit me this small indulgence.

I'd like to write a program that will play Rock-Paper-Scissors with the user. Simple enough on its own, but I'd also like it to, over the course of several games, watch for patterns in the user's choices and try to guess what they'll pick next. Similar to the AI board games that get better each time you play them, but on a smaller scale.

My question is, how would you approach the problem? I've never written anything like this before, and I don't really know where to begin. Any information would be greatly appreciated.

Replies are listed 'Best First'.
Re: Rock, Paper, Scissors
by Albannach (Monsignor) on Mar 23, 2001 at 02:57 UTC
    Here's a very interesting paper by Jon Orwant (thereby giving this response adequate Perlness ;-) on the automatic generation of game programs (in Perl of course) given a formal description, and it goes into a discussion of rock, paper, scissors among others. Not surprisingly his EGGG (Extensible Graphical Game Generator) system is also written in Perl.

    --
    I'd like to be able to assign to an luser

      I've been searching the web for this programme for hours. I would accept to pay money for it. But: where is it available ? I'd like to write a few reflexion games in this language and play against the computer. Thanks, jb.rouquier@exite.com
Re: Rock, Paper, Scissors
by japhy (Canon) on Mar 23, 2001 at 03:20 UTC
    From a totally raw point of view, I would keep track of "x previous moves" and "current move".

    Warning: Spoiler Code Ahead

    #!/usr/bin/perl -w # roshambo # usage: roshambo [look-behind] # look-behind number of previous turns AI examines use strict; my $look_behind = shift || 10; my @beat = (1, 2, 0); my @names = qw( Rock Paper Scissors ); my @chars = qw( R P S ); my (%freq,@last,$uw,$cw,$t); while (1) { my $rps; ### UPDATE ### FIXED SELECTION for my $i (0 .. $#last) { if (my $c = $freq{"@last[$i .. $#last]"}) { $rps = $beat[ weighted(@$c) ]; last; } } $rps = int rand 3 if not defined $rps; print "Rock (1), Paper (2), Scissors (3): "; chomp(my $user = <STDIN>); last if !$user or $user > 3; ### UPDATE ### FIXED WEIGHTING $user--; for (0 .. $#last) { $freq{"@last[0 .. $_]"}[$user]++; } shift @last if @last == $look_behind; push @last, $user; print "$names[$user] vs. $names[$rps] => "; if ($rps == $user) { $t++; print "tied\n" } elsif ($rps == $beat[$user]) { $cw++; print "AI wins\n" } else { $uw++; print "you win\n" } } sub weighted { my ($choice,$sum); for my $i (0 .. $#_) { $_[$i] ||= 0; $choice = $i if rand($sum += $_[$i]) < $_[$i]; } return $choice; } print "You won: $uw\n"; print "AI won: $cw\n"; print "Ties: $t\n\n"; for (sort { length($a) <=> length($b) } keys %freq) { for (split ' ') { print $chars[$_] } print " => ( "; for my $i (0 .. 2) { print "$chars[$i] = ", $freq{$_}[$i] || 0, ", "; } print ")\n"; }
    All that code does is remember what move you made when you'd made a certain list of previous moves. It selects a weighted choice. The bottom section is output to show how well the AI did.

    japhy -- Perl and Regex Hacker
Re: Rock, Paper, Scissors
by a (Friar) on Mar 23, 2001 at 10:31 UTC
    There was a post (in Code, I believe, but I can't find it; why can't supersearch be limited to code? Update: found it! a simple game AI that learns (answer, 'cause code is so well catogorized)) a while back of a learning system for ... tictactoe? or some but it was to be applied to general 'simple' games. Sorry, not much more than a hint but it was out there.

    a

Re: Rock, Paper, Scissors
by Boldra (Deacon) on Mar 23, 2001 at 18:32 UTC
    I remeber implementing a version of this in basic about ten years ago. What I remember being really fun was telling the program to play itself.

    Intitially the two robots played randomly, but then a trend would start to emerge. However, as soon as it did, the feedback would cause the opponent to change his strategy, and the trend would shift or disappear. Gradually the robots learned that there was no 'winning move' and each assigned an equal probability to each move.

    I'm sure I was inspired by WOPR's tic-tac-toe game in the classic movie 'Wargames'. Unfortunately, my robots weren't as smart as WOPR, they never realised the sisyphean futility of their game ;)