X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=gh.pl;fp=gh.pl;h=0000000000000000000000000000000000000000;hb=3861ae43ef5e739e26b5803297f8cf5a960e21dc;hp=6415800ae71c67b065e8afb271fed12de8803134;hpb=724ecd13809373c2e0f93c96d55b78987a4780eb;p=grue-hunter.git diff --git a/gh.pl b/gh.pl deleted file mode 100755 index 6415800..0000000 --- a/gh.pl +++ /dev/null @@ -1,704 +0,0 @@ -#!/usr/bin/perl -# -# This file is part of Grue Hunter. -# -# Copyright (C) 2013 Jason Self -# -# Grue Hunter gives you software freedom; you can copy, modify, convey, -# and/or redistribute it under the terms of the GNU Affero General Public -# License as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License -# for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program in a file called 'AGPLv3.txt'. If not, see -# http://www.gnu.org/licenses/agpl-3.0-standalone.html or write to the: Free -# Software Foundation, Inc., 51 Franklin St, Fifth Floor Boston, MA -# 02110-1301, USA. - -use strict; -use warnings; - -my $instructions = < - -Grue Hunter gives you software freedom; you can copy, modify, convey, -and/or redistribute it under the terms of the GNU Affero General Public -License as published by the Free Software Foundation; either version 3 of -the License, or (at your option) any later version. - -You should have received a copy of the GNU Affero General Public License -along with this program in a file called 'AGPLv3.txt'. If not, see -http://www.gnu.org/licenses/ -% -\033[2J -\033[0;0H -In this game you are a brave hunter. You are going to enter an underground -cave system in search of the Grue. If you can capture the Grue and get out -alive you will win the game. -% -Once in the cave system you can move around or shoot an arrow using the -commands 'move' and 'shoot' and any of the four compass directions. You can -also shorten the commands to 'm' and 's' and the directions to 'n', 's', 'e', -and 'w' for brevity. You may enter 'quit' or 'q' to end the game at any time. -% -But... There are other things in this cave system. Giant bats can pick you up -and drop you elsewhere. There are also bottomless pits. If you fall into one -of these you will never get out. There is also the Grue itself. Though not an -aggressive creature, it will eat you if you come too close. There are also -earthquakes that move things around (the bats, the bottomless pits, the Grue, -and the exit.) -INSTRUCTIONS - -my $space = < {'link_count'}; - if ($current_link_count < $MAX_LINK_COUNT) { - $random_link_count = int(rand($MAX_LINK_COUNT - $current_link_count)) + 1; - - # Check that there are enough rooms left to link. If there are not - # then substitute the random link count with the rooms left to link. - $rooms_left_to_link = $MAX_ROOMS - $i; - if ($random_link_count >= $rooms_left_to_link) { - $random_link_count = $rooms_left_to_link; - } - } - - # If the room is fully linked then set the random link count to 0. - else { - $random_link_count = 0; - } - - # For each room create links upto a random link count by going through - # the vacant compass directions. - for (my $j = 0; $j < $random_link_count; $j++) { - for (my $k = 1; $k < 5; $k++) { - if ($i < $MAX_ROOMS) { - $room_direction_state = $rooms[$i] -> {$k}; - if ($room_direction_state == $CLOSED) { - $next_room = $i + 1; - if ($next_room < $MAX_ROOMS) { - $rooms[$i] -> {$k} = $next_room; - $rooms[$next_room] -> {opposite($k)} = $i; - } - $i = $next_room; - } - } - } - } - } -} - -sub place_directional_object { - my $room_number = shift; - my $object = shift; - my $direction; - - # Get a random direction and set the object in a random room direction. - $direction = int(rand(3)) + 1; - $rooms[$room_number] -> {$direction} = $object; - - # Update the room's link count - ($rooms[$room_number] -> {'link_count'})++; - - if ($object == $GRUE) { - $grue_location = $room_number; - } - elsif ($object == $EXIT) { - $exit_location = $room_number; - } - elsif ($object == $PIT1) { - $pit1_location = $room_number; - } - elsif ($object == $PIT2) { - $pit2_location = $room_number; - } -} - -sub get_random_rooms { - my $number_of_rooms = shift; - my $random_num = 0; - my %random_hash = (); - my @room_numbers = (); - - for (my $i = 0; $i < $number_of_rooms;) { - $random_num = int(rand($MAX_ROOMS)); - - if (!$random_hash{$random_num}) { - $random_hash{$random_num} = 1; - $room_numbers[$i] = $random_num; - $i++; - } - } - return \@room_numbers; -} - -sub set_state { - my $set = shift; - my $number_of_rooms; - my $room_numbers; - - if ($grue_bagged) { - $number_of_rooms = 5; - } - else { - $number_of_rooms = 6; - } - - $room_numbers = get_random_rooms($number_of_rooms); - - # Bats are non-directional objects and are placed in rooms. Since they are - # non-directional they do not occupy a compass direction and do not add to the - # room's link count. They are simply assigned to the Game State variables. - $bat1_location = @$room_numbers[0]; - $bat2_location = @$room_numbers[1]; - - # The Grue, Pits and Exit are directional objects, placed in rooms. They - # are directional they occupy compass dirctions and are added to the room's - # link count. In addition they are assigned to the Game State variables. The - # Grue is only placed in a room again if it has not been bagged. - place_directional_object(@$room_numbers[2], $PIT1); - place_directional_object(@$room_numbers[3], $PIT2); - place_directional_object(@$room_numbers[4], $EXIT); - if (!$grue_bagged) { - place_directional_object(@$room_numbers[5], $GRUE); - } - # If the game state is being set for the first time, then the player's - # location is set to the same location as the Exit. - if ($set) { - $player_location = @$room_numbers[4]; - } -} - -sub opposite { - my $direction = shift; - - if ($direction == $NORTH) { - return $SOUTH; - } - elsif ($direction == $SOUTH) { - return $NORTH; - } - elsif ($direction == $EAST) { - return $WEST; - } - elsif ($direction == $WEST) { - return $EAST; - } - else { - return 0; - } -} - -sub action_handler { - my ($action, $sub_action) = @_; - my $action_success = 0; - - if (defined $action) { - $action = lc($action); - - # If the sub action (direction) is defined. - if (defined $sub_action) { - $sub_action = lc($sub_action); - - # If sub action (direction) is a valid direction. - if (is_direction($sub_action)) { - if ($sub_action eq 'q' || $action eq 'quit') { - quit(); - } - elsif ($action eq 'm' || $action eq 'move') { - move_player($sub_action); - $action_success = 1; - } - elsif ($action eq 's' || $action eq 'shoot') { - shoot($sub_action); - $action_success = 1; - } - } - - # If the sub action (direction) is not a valid direction. - else { - print "Enter 'N', 'S', 'E' OR 'W'.\n"; - if ($action eq 'm' || $action eq 'move') { - move_player(); - } - elsif ($action eq 's' || $action eq 'shoot') { - shoot(); - } - } - - if ($action_success) { - my $random_num = 0; - $random_num = int(rand($EARTHQUAKE_CHANCE)); - - if ($random_num == $EARTHQUAKE) { - print "\n<<>>\n\n"; - randomize_rooms(); - set_state($RESET); - connect_rooms(); - } - - describe_location(); - } - } - # If the sub action (direction) is not defined. - else { - if ($action eq 'm' || $action eq 'move') { - move_player(); - } - elsif ($action eq 's' || $action eq 'shoot') { - shoot(); - } - elsif ($action eq 'q' || $action eq 'quit') { - quit(); - } - } - } -} - -sub display_text { - $| = 1; - my $text = shift; - for my $word (split/%/, $text) { - print $word."\n"; - print 'Press enter when ready to continue: '; - ; - } - print "\033[2J"; - print "\033[0;0H"; - print "\t\t\t\t".'***********************'."\n"; - print "\t\t\t\t".'*** ***'."\n"; - print "\t\t\t\t".'*** GRUE HUNTER ***'."\n"; - print "\t\t\t\t".'*** ***'."\n"; - print "\t\t\t\t".'***********************'."\n\n"; -} - -sub read_input { - my $action; - my @actions; - $action = <>; - @actions = split(/\s+/, $action); - return @actions; -} - -sub is_direction { - my $direction = shift; - if (defined $direction) { - return ( - $direction eq 'n' or - $direction eq 'north' or - $direction eq 's' or - $direction eq 'south' or - $direction eq 'e' or - $direction eq 'east' or - $direction eq 'w' or - $direction eq 'west' or - $direction eq 'q' or - $direction eq 'quit' - ); - } - return ''; -} - -sub direction { - my $direction = shift; - - if ($direction == $NORTH) { - return 'north'; - } - elsif ($direction == $SOUTH) { - return 'south'; - } - elsif ($direction == $EAST) { - return 'east'; - } - elsif ($direction == $WEST) { - return 'west'; - } - else { - return ''; - } -} - -sub move_player { - my $sub_action = shift; - my $direction; - my $room_direction; - - if (defined $sub_action) { - if ($sub_action eq 'n' || $sub_action eq 'north') { - $direction = $NORTH; - } - elsif ($sub_action eq 's' || $sub_action eq 'south') { - $direction = $SOUTH; - } - elsif ($sub_action eq 'e' || $sub_action eq 'east') { - $direction = $EAST; - } - elsif ($sub_action eq 'w' || $sub_action eq 'west') { - $direction = $WEST; - } - - $room_direction = $rooms[$player_location] -> {$direction}; - - # If the room that the player wants to move to is a room. - if ($room_direction > $CLOSED) { - - # Check if the room has a bat. - if ($room_direction == $bat1_location || $room_direction == $bat2_location) { - print "Bats have you now.\n"; - print "They're lifting you up.\n"; - print "Ohhhh, where are we now?\n"; - - my $number_of_rooms = 2; - my $room_numbers = get_random_rooms($number_of_rooms); - - # Change player location (to where the bat dropped the player). - $player_location = @$room_numbers[0]; - - # Change location of offending bat. - if ($room_direction == $bat1_location) { - $bat1_location = @$room_numbers[1]; - } - else { - $bat2_location = @$room_numbers[1]; - } - } - - # If free of bats, go ahead and move into the room. - else { - print "OK...\n"; - $player_location = $room_direction; - } - } - elsif ($room_direction == $CLOSED) { - print "You cannot go that way.\n"; - } - elsif ($room_direction == $GRUE) { - print "You bumped into the Grue.\n"; - print "He ate you before you could move.\n"; - quit(); - } - elsif ($room_direction == $EXIT) { - if ($grue_bagged) { - print "You have reached the exit with your Grue.\n"; - print "Your supper will be filling tonight for sure!\n"; - } - else { - print "You have reached the exit without any Grue.\n"; - print "You are sure to starve.\n"; - } - quit(); - } - elsif ($room_direction < $PIT1) { - my $pit_chance = int(rand($PIT_CHANCE)); - if ($pit_chance) { - print "This room contains a bottomless pit. Part of the ground around it gave way when you entered and you almost fell in.\n"; - print "Be more careful next time!\n"; - $player_location = $room_direction; - } - else { - print "You fell into a bottomless pit.\n"; - print "You fell a loooooong way...\n"; - quit(); - } - } - } - else { - my @actions; - print "Move which way?\n"; - @actions = read_input(); - action_handler('m', $actions[0]); - } -} - -sub shoot { - my $sub_action = shift; - my $direction; - my $room_direction; - - if (defined $sub_action) { - if ($sub_action eq 'n' || $sub_action eq 'north') { - $direction = $NORTH; - } - elsif ($sub_action eq 's' || $sub_action eq 'south') { - $direction = $SOUTH; - } - elsif ($sub_action eq 'e' || $sub_action eq 'east') { - $direction = $EAST; - } - elsif ($sub_action eq 'w' || $sub_action eq 'west') { - $direction = $WEST; - } - - $room_direction = $rooms[$player_location] -> {$direction}; - - # If the arrow was shot in a direction without the Grue. - if ($room_direction == $CLOSED) { - print "Clunk!\n"; - print "The arrow bounced off the wall.\n"; - } - # If the arrow was shot in a direction of the Grue. - elsif ($room_direction == $GRUE) { - my $shot = int(rand($EVEN_CHANCE)); - if ($shot) { - print "You caught the Grue!\n"; - print "Now to find a way out...\n"; - $grue_bagged++; - - # Remove the Grue from the Room once bagged. Set the Grue - # location to an undefined state (the Grue object -2). - $rooms[$player_location] -> {$direction} = $CLOSED; - ($rooms[$player_location] -> {'link_count'})--; - $grue_location = $GRUE; - } - else { - print "The arrow missed the Grue.\n"; - } - } - else { - print "The arrow missed the Grue.\n"; - } - } - else { - my @actions; - print "Shoot which way?\n"; - @actions = read_input(); - action_handler('s', $actions[0]); - } -} - -sub describe_location { - my $room_direction; - - print $rooms[$player_location] -> {'description'} . "\n"; -# print "Player Location: $player_location\n"; -# print "Grue Location: $grue_location\n"; -# print "Bat 1 Location: $bat1_location\n"; -# print "Bat 2 Location: $bat2_location\n"; -# print "Pit 1 Location: $pit1_location\n"; -# print "Pit 2 Location: $pit2_location\n"; -# print "Exit Location: $exit_location\n"; - - print 'I see passages to the '; - my @passages; - for (my $i = 1; $i < 5; $i++) { - $room_direction = $rooms[$player_location] -> {$i}; - if ($room_direction != $CLOSED) { - push(@passages, direction($i)); - } - } - - for (my $i = 0; $i < $#passages + 1; $i++) { - if ($i == 0) { - print $passages[$i]; - } - elsif ($i < $#passages) { - print ', ' . $passages[$i]; - } - elsif ($i == $#passages) { - print ' and ' . $passages[$i]; - } - } - print ". Choose wisely.\n"; - - # If the Grue is in the player's current location. - if ($player_location == $grue_location) { - print "I smell the Grue!\n"; - } - # If either pit is in the player's current location. - elsif ($player_location == $pit1_location || $player_location == $pit2_location) { - print "I feel a draft. A bottomless pit must be nearby. Be careful not to fall in.\n"; - } - # If the Exit is in the player's current location, tell the player which - # direction the Exit is located. - elsif ($player_location == $exit_location) { - for (my $i = 1; $i < 5; $i++) { - $room_direction = $rooms[$player_location] -> {$i}; - if ($room_direction == $EXIT) { - print 'The exit is to the ' . direction($i) . ".\n"; - } - } - } - # Check the adjacent rooms for the Exit, Grue, Bats and Pits. Here - # check whether the adjacent rooms are equivalent to the game state - # variables for the Exit, Grue, Bats and Pits. - else { - for (my $i = 1; $i < 5; $i++) { - $room_direction = $rooms[$player_location] -> {$i}; - if ($room_direction > $CLOSED) { - if ($room_direction == $exit_location) { - print "Exit nearby...\n"; - } - elsif ($room_direction == $grue_location) { - print "I smell the Grue!\n"; - } - # If the room adjacent contains one of the two bats then warn the player. - elsif ($room_direction == $bat1_location || $room_direction == $bat2_location) { - print "I hear bats flying around in the distance. Be careful or they may grab you and carry you away.\n"; - } - # If the room adjacent contains one of the two pits then warn the player. - elsif ($room_direction == $pit1_location || $room_direction == $pit2_location) { - print "I feel a draft. A bottomless pit must be nearby. Be careful not to fall in.\n"; - } - } - } - } -} - -sub quit { - exit; -} - -sub main { - my @actions; - - display_text($instructions); - randomize_rooms(); - set_state($SET); - connect_rooms(); - describe_location(); - while (1) { - print "Move or shoot?\n"; - @actions = read_input(); - action_handler(@actions); - } -} - -main();