#!/usr/ug/bin/perl5 -w # # by Wei-Hwa Huang (whuang@ugcs.caltech.edu) $catandir = '/mnt/whuang/ufs/whuang/whuang/prog/gale/catan/data/'; @commands = ( 'ROLL', 'PLACEROBBER', 'STEALFROM', 'TAKE', 'GIVE', 'TRADE', 'SEATRADE', 'BUILDAT', 'MONOPOLIZE', 'PLAY', 'ENDTURN', 'SHOWMAP', 'INVENTORY', 'VALIDMOVES', 'STATUSGAME', 'ALLGAMES', 'NEWGAME', 'STARTGAME', 'JOINGAME', 'ALIAS', 'LEAVEGAME', 'HELP' ); require '/mnt/whuang/ufs/whuang/whuang/prog/gale/catan/gamestatus.lib'; print "Hello, $ARGV[0]\n"; my $cmd; foreach $cmd () { chomp($cmd); my @terms = split(' ',$cmd); my @possible; @possible = grep(/^$terms[0]/i, @commands); if ($#possible < 0) { print "Unknown command: $cmd\n"; } elsif ($#possible != 0) { print "Ambiguous command: $cmd\n"; } else { $_ = $possible[0]; BLOCK: { /NEWGAME/ && do { &newgame(@terms); last BLOCK; }; /ALLGAMES/ && do { &allgames(@terms); last BLOCK; }; /STATUSGAME/ && do { &statusgame(@terms); last BLOCK; }; /JOINGAME/ && do { &joingame(@terms); last BLOCK; }; /LEAVEGAME/ && do { &leavegame(@terms); last BLOCK; }; /HELP/ && do { &help(@terms); last BLOCK; }; print "Sorry, $_ is not implemented yet.\n"; } } } ##################################################### sub help { $_ = $_[0]; HELPTERM: { # /ROLL/ && do { print <<"End of Help"; #End of Help # last HELPTERM; }; print <<"End of Help"; Commands may be abbreviated. Valid commands are: Game commands: ROLL PLACEROBBER STEALFROM TAKE [FROM] GIVE [TO] [SEA]TRADE [] [[IN]TO]|[FOR] BUILDAT MONOPOLIZE PLAY [] VALIDMOVES ENDTURN SHOWMAP [] INVENTORY Meta-game commands: NEWGAME JOINGAME LEAVEGAME STATUSGAME STARTGAME ALIAS ALLGAMES HELP End of Help } } ##################################################### sub allgames { if (!-e "$catandir/players") { print 'There are no games in progress.'; } else { open (FHAND, "$catandir/players"); my $line; my %hash; foreach $line () { chomp($line); my ($key, $gamename) = split(' ',$line); $hash{$gamename} .= " $key\n"; } my $key; print "Listing all games and players...\n"; foreach $key (keys %hash) { print "Playing in game $key:\n"; print $hash{$key}; } close (FHAND); } } ##################################################### sub findgame { $playername = $_[0]; my $found = '!invalid'; if (-e "$catandir/players") { open (FHAND, "$catandir/players"); my $line; my %hash; foreach $line () { chomp($line); my ($key, $gamename) = split(' ',$line); $found = $gamename if ($key eq $playername); } close (FHAND); } return $found; } ##################################################### sub joingame { my $gamename = $_[1]; if (&findgame($ARGV[0]) eq "!invalid") { print "You are already in a game. Please use LEAVEGAME first.\n"; return; } my $status = &gamestatus($gamename); $_ = $status; GAMESTATE: { /^INVALID/ && do { print " Error -- Usage: JOINGAME \n"; last GAMESTATE; }; /^NOGAME/ && do { print " Error -- No game named '$gamename'.\n"; last GAMESTATE; }; /^STARTED/ && do { print " Sorry, '$gamename' has already started.\n"; last GAMESTATE; }; /^ENDED/ && do { print " Sorry, '$gamename' has already ended. Use NEWGAME first.\n"; last GAMESTATE; }; /^WAITING/ && do { local %info = %{&gamestatushash($gamename)}; if ($info{'PLAYERS'} == 4) { print " Sorry, this game already has four players. (Why aren't ". "they starting? Ya got me.)\n"; last GAMESTATE; } $info{'PLAYERS'}++; $info{'P'.$info{'PLAYERS'}} = $ARGV[0]; my @message; $message[0] = $gamename; $message[1] = "$ARGV[0] has joined the game!\n"; $message[2] = "The player list is now:\n"; print " You joined the game '$gamename'!\n"; foreach (1..$info{'PLAYERS'}) { push(@message," ".$info{"P$_"}."\n"); } open (FHAND, ">>$catandir/players"); print FHAND "$ARGV[0] $gamename\n"; close FHAND; open (FHAND, ">>$catandir/$gamename.log"); print FHAND ×tring, " Added player '$ARGV[0]' to game '$gamename'.\n"; close (FHAND); &announce (@message); &writestatus($gamename,\%info); last GAMESTATE; }; } } ##################################################### sub leavegame { my $gamename = &findgame($ARGV[0]); if ($gamename ne "!invalid") { print "You are not in any games!\n"; return; } open (FHAND, "<$catandir/players"); my @lines = ; foreach (@lines) { $_ = '' if /^$ARGV[0]/; } close FHAND; open (FHAND, ">$catandir/players"); print FHAND @lines; close FHAND; my $status = &gamestatus($gamename); $_ = $status; GAMESTATE: { /^INVALID/ && do { print " Error -- cannot find your game\n"; last GAMESTATE; }; /^NOGAME/ && do { print " Error -- cannot find your game\n"; last GAMESTATE; }; /^STARTED/ && do { print " Sorry, '$gamename' has already started.\n"; last GAMESTATE; }; (/^ENDED/ || /^WAITING/) && do { local %info = %{&gamestatushash($gamename)}; if ($info{'PLAYERS'} == 0) { print " Error -- you do not appear to be in the game\n"; last GAMESTATE; } my @playerlist = (); foreach ('1'..$info{'PLAYERS'}) { push(@playerlist,$info{'P'.$_}) if ($info{'P'.$_} ne $ARGV[0]); } undefine ($info{'P'.$info{'PLAYERS'}}); $info{'PLAYERS'} --; foreach ('1'..$info{'PLAYERS'}) { $info{'P'.$info{'PLAYERS'}} = $playerlist[$_ - '1'];; } my @message; $message[0] = $gamename; $message[1] = "$ARGV[0] has left the game!\n"; $message[2] = "The player list is now:\n"; print " You left the game '$gamename'!\n"; foreach (1..$info{'PLAYERS'}) { push(@message," ".$info{"P$_"}."\n"); } open (FHAND, ">>$catandir/$gamename.log"); print FHAND ×tring, " Removed player '$ARGV[0]' from game '$gamename'.\n"; close (FHAND); &announce (@message); &writestatus($gamename,\%info); last GAMESTATE; }; } } ##################################################### sub statusgame { my $gamename = $_[1]; my $status = &gamestatus($gamename); $_ = $status; GAMESTATE: { /^INVALID/ && do { print " Error -- Usage: STATUSGAME \n"; last GAMESTATE; }; /^NOGAME/ && do { print " Error -- No game named '$gamename'"; last GAMESTATE; }; local %info; %info = %{&gamestatushash($gamename)}; $_ = $status; /^ENDED/ && do { print "The game '$gamename' has ended.\n"; last GAMESTATE; }; /^WAITING/ && do { print "The game '$gamename' is waiting for players.\n"; print " There are currently $info{'PLAYERS'} player(s):\n"; foreach (1..$info{'PLAYERS'}) { print " ".$info{"P$_"}."\n"; } last GAMESTATE; }; /^STARTED/ && do { print "The game '$gamename' is in progress.\n"; print " There are currently $info{'PLAYERS'} player(s):\n"; foreach (1..$info{'PLAYERS'}) { print " ".$info{"P$_"}."\n"; } print "It is turn $info{'TURN'} of the game.\n"; my %phasetext = ( 'ROLL' => 'roll the dice', 'TRADE' => 'trade', 'BUILD' => 'build', 'END' => 'end the turn.' ); print "The next turn action is to $phasetext{$info{'PHASE'}}."; my %specialtext = ( 'NO' => 'nothing at all', 'DISCARD' => 'discard resources to the robber', 'MOVE' => 'move the robber...', 'STEAL' => 'steal a card from someone...', 'MONOPOLY' => 'decide on a Monopoly action...', 'ROAD' => 'consummate their Road Building card...', 'PLENTY' => 'consummate their Year of Plenty card...', 'START' => 'finish their starting build...' ); print " Waiting for people to $specialtext{$info{'SPECIAL'}}..." unless ($info{'SPECIAL'} eq 'NO'); last GAMESTATE; }; } } ##################################################### sub timestring { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $mon++; return ("$year-$mon-$mday $hour:$min:$sec"); } ##################################################### sub newgame { my $gamename = $_[1]; my $status = &gamestatus($gamename); $_ = $status; GAMESTATE: { /^INVALID/ && do { print " Error -- Usage: NEWGAME \n"; last GAMESTATE; }; (/^STARTED/ || /^WAITING/) && do { print "Sorry, $gamename is already in progress.\n"; last GAMESTATE; }; (/^NOGAME/ || /^ENDED/) && do { system ("cp $catandir/defaultgrid $catandir/$gamename.grid"); system ("cp $catandir/defaultcards $catandir/$gamename.cards"); #system ("cp $catandir/defaultdice $catandir/$gamename.dice"); open (FHAND, ">$catandir/$gamename.status"); print FHAND "WAITING\n"; print FHAND "PLAYERS 0\n"; close (FHAND); open (FHAND, ">>$catandir/$gamename.log"); print FHAND ×tring, " Started new game '$gamename' with 0 players.\n"; close (FHAND); my @msg; $msg[0] = $gamename; $msg[1] = "A new game '$gamename' has been created!\n"; $msg[2] = "Now looking for players!\n"; &announce (@msg); print "The game '$gamename' has been created.\n"; last GAMESTATE; }; } } ######################################################## sub announce { my $gamename = $_[0]; shift(@_); open (FHAND, "| /usr/contrib/bin/gsend -c bot/catan/$gamename"); print FHAND @_; close (FHAND); }