hsweet has asked for the wisdom of the Perl Monks concerning the following question:
Last year I wrote a sketchy version of a simple text game. I want to turn the thing into an object so my students can use it without having to deal with the innards and to have a (hopefully) fun way to introduce the ideas and syntax.
The game is built of three files, the code, a room map and a room description file. They are detailed at the end of the code. The whole game runs in a while loop and keystrokes that match a command get passed to an appropriate sub.
I've never written anything more than simple objects and this one is confusing me.
Some of my questions right now are;
#!/usr/bin/perl -w use strict; my @things=qw(); my %things; my %things_to_take; my $points=0; my %directions=( e => 'East', n => 'North', w =>'West', s => 'South'); my($r, $c)=(0,0); #row, column on map my @gamemap; #my $room; #current room #**************************Get the rooms****************** #uses a hash of arrays structure, room=>[description, exits, objects, +points] @ARGV=("rooms.txt"); #file to read, or rea +d from stdin #file structure; room name: description; directions; objects; points my %rooms; #$room is room name, @fields is all the rest of the things in the line # while ( my $line = <> ) { (my $room, my $rest) = split /:\s*/, $line, 2; #split at : follo +wed by whitespace. 2 is limit my @fields = split ';', $rest; #delimiter for v +alues $rooms{$room} = [ @fields ]; } #*********************************** Get the Map **** #gamemap and room hash above gotta match so if you end up in a room li +sted in #gamemap you have the key to the room hash which will get you the desc +ription #and the ways out. @ARGV=("map.txt"); # read map from file while ( <> ) { push @gamemap, [ split ]; } my $play=1; #flag to end game my $room; #might not need this one if I use the syntax on +the next line showroom($gamemap[$r]->[$c]); #0,0 on map row, column #*************************** Main Loop ************* while ($play ==1){ print "\n? "; chomp (my $command = <STDIN>); #for starters l(ook), t(ake), i(nventory), nsew, q(uit), p(oints) if ($command=~/(^[nsew])/){ #send n, s, e, or w to +sub using &changeroom($1); }elsif ($command eq "i"){ &inventory; }elsif ($command eq "t"){ print "Take what?"; chomp(my $item=<STDIN>); take($item); }elsif ($command eq "l"){ showroom($gamemap[$r]->[$c]); }elsif ($command eq "q"){ $play = 0; }elsif ($command =~/p|poi\w+/ ){ #p or points or print "You have $points points\n" }else{print"I don't know what you are talking about."} } #********************* subroutines ************************ sub changeroom{ #change the value of $r(ow) and $c(olumn). $gamemap[$r]->[$c] is t +he room # Also checks for legal directions which are in $room{[whichever]} +->[1] #print "Coming from $gamemap[$r]->[$c]\n"; my ($oldr, $oldc)=($r, $c); #change room coordinates if ($_[0] eq "n"){ $r--; }elsif($_[0] eq "s"){ $r++; }elsif($_[0] eq "e"){ $c--; }elsif($_[0] eq "w"){ $c++ } #check if legal move; if (! defined $gamemap[$r]->[$c] ||$gamemap[$r]->[$c] eq "-" ){ print "You can't go that way!\n"; ($r, $c)=($oldr, $oldc); #Stay where you were if you ca +n't go there } #print "Going to $gamemap[$r]->[$c]\n"; showroom($gamemap[$r]->[$c]); } sub inventory{ if ($things[0]){ #if you have anything at all #if (exists $things{'dish'}){ print "you have a "; print join ",",@things; print"\n"; }else{print"You're busted, Jack\n"} print "You have $points points\n"; } sub things_to_take{ #hash of things that can be taken. #key = object, value=points $things_to_take{$_[0]}=$rooms{$gamemap[$r]->[$c]}->[3]; } sub take{ foreach my $key(keys %things_to_take){ if ($key eq $_[0]){ #$things{$_[0]}=1; #figure out hash push @things, $_[0]; #adds object if it matches + list of things in game. $points += $things_to_take{$key}; }else{print" There is no $_[0] here.\n" } } #print @things;print $points; #you still can take a +n item more than once. hash is better } sub showroom { print "You are in a $_[0]. "; #room name print $rooms{$_[0]}->[0]; #description my @directions=split(//,$rooms{$_[0]}->[1]); #ways out print "\nThere are exits to the "; foreach my $way (@directions) { # n=>North, + etc. Uses %directions hash $way=~/([nsew])/g; print "$directions{$1} "; # the ways ou +t. } if($rooms{$_[0]}->[2]){ #things to take chomp $rooms{$_[0]}->[2]; print "\nThere is a " . ($rooms{$_[0]}->[2]) . " here.\n"; things_to_take ($rooms{$_[0]}->[2]); } } =cut =HEAD1 Name A sketch of a single person text adventure game. =HEAD1 Description maps.txt is the game map file and rooms.txt describes the room. Room names in the maps file are entered in rows separated by space(s) The "-" character is an empty room. These map to an array of arrays +inside the code. example: dark_hall - steep_hill windy_plateau river - forest The rooms file is a delimited list of name: Description;Exits;Object to take;Points steep_hill: A hard scramble up to the top.;nes;grass;10 The first delimiter is a colon: followed by a space, the rest are semi +colons. =end
Time flies like an arrow, fruit flies like banannas
Edit by tye, add READMORE
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Adventure Game ->object
by bigj (Monk) on May 14, 2003 at 06:49 UTC | |
|
Re: Adventure Game ->object
by chaoticset (Chaplain) on May 14, 2003 at 13:11 UTC |