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

Conas tá, mo chara Monk.(Alright Monks)

You helped me a while back(here and here) with a game I'm writing. I'm still having problems. It seems to be very hard to structure right.
Any who, the current problem is array related. The array is like so.
@array = ( 'north#library , 'south#kitchen', 'east#hallway')
You see its a fairly simple array pattern, you have you command on the left and the result on the right. I want to search through the array for the correct command and then assign the result to a variable called $location for examples sake, and if it doesn't find the command return an error message. I know that its probrably simple but I'm lost. Thanks.


P.s I've got this other problem aswell all this script does is print out the first few lines and I can't figure out why. Heres the code...
###main.pl use actions; use subs; print "Welcome to watever.\n"; print "This game will lead you through many perils and dangers that co +uld lead to your death.etc etc \n"; print "ONLY THE STRONG WILL SURVIVE"; my $data = "whatever" ; my $action; my @items= (); my $location = "hall"; my $health = "full"; &main($data, $location); sub main{ my( $data, $location ) = @_; while(<1>){ $data = &data($location); print $data; print "\n\n"; print "What do you want to do?? \n"; print "(type h for help.)\n"; print "Do what??\\: "; my $action = <>; my $noun = &action($action, $location); print $noun; } }
Thanking you in advance.
All the Best, Eoin...

If everything seems to be going well, you obviously don't know what the hell is going on.

Replies are listed 'Best First'.
Re: array games??
by gjb (Vicar) on Jan 19, 2003 at 22:36 UTC

    As to the array: why not use a hash, the command would be the key, and the location the value.

    my %hash = ('north' => 'library', 'south' => 'kitchen', 'east' => 'hallway');
    That way you can simply do a hash lookup to retrieve the location for a command, i.e. $hash{'north'} will yield 'library' as a location.

    As to your second problem:

    while(<1>){ ... }
    is not what you want. If you just want to read from stdin, simply use <> rather than <1>. If you want an infinite loop (although I don't think so since you're not reading anything in the body of the loop) just use while (1) {...}.

    Hope this helps, -gjb-

    Update: Oops, as graff points out (thanks) I missed the assignment to $action, but yes, anyway the condition for the while will always fail which is what I tried to explain.

Re: array games??
by BrowserUk (Patriarch) on Jan 19, 2003 at 22:49 UTC

    Here's one of many ways. Caveat, if any of your commands or locations contain '|', use a character they don't contain.

    my @array = ( 'north#library' , 'south#kitchen', 'east#hallway'); my $cmd = 'south'; (my $location) = join('|', @array) =~ m[$cmd\#(.*?)\|]; print $location; kitchen

    Examine what is said, not who speaks.

    The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.

Re: array games??
by graff (Chancellor) on Jan 20, 2003 at 03:55 UTC
    gjb got it basicly right -- except he seems to have missed the part where your code said:  my $action = <>;

    (But you should notice that this line "masks" (renders irrelevant) an earlier declaration of  my $action; that appears before the call to "main()" -- maybe this was intentional, but I wonder... and "perl -w" won't warn you about it, because the second "my $action" is within a subroutine.)

    Anyway, saying while (<1>) (with angle brackets inside parens), will fail, because you have not opened a file handle named "1".

Re: array games??
by JamesNC (Chaplain) on Jan 20, 2003 at 05:48 UTC
    Give this a shot... I played with this when I was first got started...
    use strict; my @items; my $move; my $treasure = "gold, gold... it's all mine!"; my @map= ( #possible moves by area # |_0|_1|_2|_3| [qw ( e swe we ws) ], # 0 |__ __ | [qw ( se new sw ns)], # 1 | __ | | [qw ( ns - ns n ) ], # 2 | T|__| |__| [qw ( ne w ne w ) ], # 3 |_____|___X_| ); my %direction = ( n=>[-1,0], s=>[1,0], e=>[0,1], w=>[0,-1], ); my %dir_names = (e=> 'East', n=>'North', w=>'West', s=>'South'); my ($new_x, $new_y, $x, $y) =(0,0,3,3); sub disp_location { my ($nx, $ny) = @_; print "You may move "; while($map[$nx][$ny]=~/([nsew])/g){ print "$dir_names{$1}"; } print "($map[$nx][$ny])\n"; } sub move_to { my ($new, $xref, $yref) = @_; $new = substr(lc($new),0,1); if ($map[$$xref][$$yref]!~/$new/){ print "Invalid direction $new.\n"; return; } $$xref += $direction{$new}[0]; $$yref += $direction{$new}[1]; } while(1){ if ($new_x == $x && $new_y == $y){ print "You died a horrible death!\n +"; exit(0); } if ( $map[$new_x][$new_y]=~ /ns/ && (! map {/gold/ig } @items )){ prin +t "You found treasure!\n"; push @items, $treasure; print "Items: @ite +ms\n"; } if( $map[$new_x][$new_y]=~ /se/ && ( map {/gold/ig } @items ) ) { print "Someone yells..\"Thief!...you will pay with your life for steal +ing my gold!\"...\n"; } disp_location($new_x, $new_y); print "Where to? "; chomp($move=<stdin>); exit if ($move =~ /q/ig); move_to($move, \$new_x, \$new_y); }
    Have fun... :) JamesNC
Re: array games??
by Pardus (Pilgrim) on Jan 20, 2003 at 03:51 UTC
    Probably you should use hashes for this kind of data structures, but if you want to use the array method you could do something like:
    my $cmd = 'south'; my @array = ( 'north#library , 'south#kitchen', 'east#hallway'); my ($location) = map {m/\#(.*?)$/; $1} grep {m/^$cmd\#/} @array || pri +nt "some error message";
    Of course this will only return the first array element matching the command.
    If the command is not unique do something like:
    my @possibilities = map {} grep {} @array || ...

    --
    Jaap Karssenberg || Pardus (Larus)? <pardus@cpan.org>
    >>>> Zoidberg: So many memories, so many strange fluids gushing out of patients' bodies.... <<<<