#! /usr/bin/perl -w # Hunt the Wumpus. # A quick and dirty port by L. Ross Raszewski http://www.trenchcoatsoft.com # Hunt the Wumpus is (c) 1973 by Gregory Coresun # This port is based on a description of the game by Jason Dyer: # https://bluerenga.blog/2019/04/03/before-adventure-part-4-hunt-the-wumpus-1973/ # # This code is public domain. use List::Util qw/shuffle/; no if $] >= 5.017011, warnings => 'experimental::smartmatch'; use constant { BAT => 1, PIT => 2, }; my @map = ( 1, 4, 7, 0, 2, 9, 1, 3, 11, 2, 4, 13, 0, 3, 5, 4, 6, 14, 5, 7, 16, 0, 6, 8, 7, 9, 17, 1, 8, 10, 9, 11, 18, 2, 10, 12, 11, 13, 19, 3, 12, 14, 5, 13, 15, 14, 16, 19, 6, 15, 17, 8, 16, 18, 10, 17, 19, 12, 15, 18 ); my $nbats = 2; my $npits = 2; my $narrows = 6; my @deck; my %hazards; my $wumpus; my $location; my $arrows; sub initializeGame { @deck = ( 0..((scalar @map)/3)-1); @deck = shuffle(@deck); %hazards = (); $arrows = $narrows; $hazards{shift @deck} = BAT foreach (1..$nbats); $hazards{shift @deck} = PIT foreach (1..$npits); $wumpus = shift @deck; $location = @deck[int(rand(scalar @deck))]; print <"; $location = getNumber($a, $b, $c); } sub shootArrow { print "Shoot through how many rooms? [1-5] >"; my $input = getNumber(1..5); my @path = (); print "Which room? >"; my $ix = $location*3; push @path, getNumber(@map[$ix..($ix+2)]); foreach (2..$input) { print "Then which room? >"; push @path, getNumber(0..((scalar @map)/3)); } my $aloc = $location; foreach (@path) { $ix = $aloc*3; unless ($_==$map[$ix] || $_==$map[$ix+1] || $_==$map[$ix+2]) { print "You hear your arrow strike the cave wall and deflect!\n"; $_ = $map[$ix+int(rand(3))]; } if ($_==$location) { print "You hear the briefest \"thwip!\" and ". "feel a sudden shock of pain. It has rebounded back ". "into your chest! You have died.\n"; return 1; } elsif ($_==$wumpus) { print "The beast lets out a mighty howl and is slain! ". "Congratulations! You have killed the Wumpus!\n"; return 1; } $aloc = $_; } print "You hear the arrow clatter to the ground in the distance. ". "The Wumpus heard it as well, and you hear a scurrying as it moves ". "to a new hiding place.\n"; $arrows--; if ($arrows <= 0) { print "That was your last arrow. Your hunt has ended in defeat."; return 1; } return 0; } sub mainLoop { initializeGame(); while(showRoom()==0) { print "[S]hoot, [M]ove or [Q]uit? > "; my $input = getInput('SMQ'); if ($input eq 'S') { return if shootArrow(); } elsif ($input eq'M') { moveRooms(); } else { return; } } } sub getInput { my $str = shift; while(1) { my $input = ; chomp $input; if ($input =~ m/^[$str]$/i) { return uc($input); } print "Please enter one of [$str] >"; } } sub getNumber { while(1) { my $input = ; chomp $input; if ($input =~ m/^\d+$/ && grep { $input == $_ } @_) { return $input; } print "Please enter a valid number >"; } } do { mainLoop(); print "Play again? [Y/N] > "; } while(getInput('yn') eq 'Y'); print "Goodbye!\n";