#!perl -w ## Animals ## Attempts to guess an animal by yes/no questions, ## Learns new animals as it goes. ## Based on a game I remember playing on an Apple II use strict; my $animalfile = "animals.dat"; ## Open and read in the animal file, or our default data unless (open(ANIMALS, "$animalfile")) { *ANIMALS = *DATA; print qq[**WARNING**\nThe file "$animalfile" was not found. ]; print "Using the default list instead.\n"; } my $yesno="ASK"; my @q; my $total=0; my $new=0; my ($ark, $answer); my ($animal, $Animal, $beast, $Beast); ## Read in all the animals while() { next if /^#/; ## Allow comments - why not? last if /^END!/; ## Allow a graceful end if needed chop; if ($yesno eq "ASK") { $q[++$total]->{$yesno}=$_; $yesno="YES"; next; } if (m/^>(\d*)/) { $q[$total]->{$yesno}=\$q[$1]; } else { $q[$total]->{$yesno}=$_; } $yesno = $yesno eq "YES" ? "NO" : "ASK"; } close(ANIMALS); ## Begin the game print qq[ Welcome to the game of Animals! Just think of an animal, and I will try and guess what it is. (I know $total animals!) --Please answer es, o, or uit for each question.-- ]; $ark=\$q[1]; while($ark) { print "\n$$ark->{ASK}\n\n"; $yesno = ; &Quit if $yesno =~ /^Q/i; if ($yesno =~ s#^([YN]).*#$1=~/Y/i ? "YES" : "NO"#eis) { $animal = $$ark->{$yesno}; if (ref($animal)) { $ark=$animal; next; } } else { print "**Please answer Yes, No, or Quit**\n\n"; next; } ## Did we guess the right animal? ($Animal = $animal) =~ s/^([aeiou])?/$1 ? "an $1" : "a "/ei; print "\n**It must be $Animal!**\n"; do { print "\nDid I guess your animal?\n\n"; } while ($answer=) !~ /^[YN]/i; if ($answer =~ /^Y/i) { print "\n**Yay! I win!**\n"; do { print "\nDo you want to

lay again or uit?\n\n"; } while ($answer=) !~ /^[PQ]/i; &Quit if $answer =~ /Q/i; $ark=\$q[1]; next; } print "\nWhat animal were you thinking of?\n\n"; chop($beast=); ($Beast = $beast) =~ s/^([aeiou])?/$1 ? "an $1" : "a "/ei; $total++; $new++; do { print "\nWhat could I ask to tell the difference between ", "$Animal and $Beast?\n\n"; chop($q[$total]->{ASK}=); print "\n\nIf I asked someone:\n\"$q[$total]->{ASK}\"\n\n"; print "Would they answer es or o for $Animal?\n"; print "( to re-enter your question)\n\n"; } while ($answer = ) !~ /^[YN]/i; ## Store the animals in the new Yes/No $q[$total]->{YES} = $answer=~/^Y/i ? $animal : $beast; $q[$total]->{NO} = $answer=~/^N/i ? $animal : $beast; ## Make the current yes/no point to the new entry $$ark->{$yesno} = \$q[$total]; print "\n\n**Thank you! Now I know about $total animals, ", "including $Beast!**\n"; do { print "\nWould you like to

lay again or uit?\n\n"; } while ($answer=) !~ /^[PQ]/i; &Quit if $answer =~ /^Q/i; print "I now know $total animals!\n\n"; $ark=\$q[1]; ## Start over... } sub SaveAnimals { ## Write the list to the file open(ANIMALS, ">$animalfile") or die "Could not open $animalfile: $!\n"; my $oldselect = select(ANIMALS); ## Create a quick lookup table my $y=0; my %LU; $LU{$q[$y]->{ASK}}=$y while ($q[++$y]); ## Write each one in order $y=1; while($ark = $q[$y]) { print "$ark->{ASK}\n"; for $yesno (qw(YES NO)) { if (ref($ark->{$yesno})) { printf ">%d\n", $LU{${$ark->{$yesno}}->{ASK}}; } else { print "$ark->{$yesno}\n"; } } $y++; } select($oldselect); close(ANIMALS); print "\nSaved information on $total animals.\n"; } ## end of the sub SaveAnimals sub Quit { if ($new) { do { printf "\n**I learned about $new new animal%s!**\n", $new==1 ? "" : "s"; print "\nDo you want to ave or just uit?\n\n"; } while ($answer = ) !~ /^[SQ]/i; &SaveAnimals if $answer =~ /^S/i; } print "\n**Goodbye! Thanks for playing!**\n"; exit; } __END__ ## This is the default list if the data file is not found. Does it live in the water? >2 >3 Does it have a tail? Whale Starfish Does it have wings? >4 >5 Can it fly? Eagle Penguin Does it have fur? >6 >7 Does it have stripes? Tiger Bear Does it have a trunk? Elephant Armadillo END! mmmm.....typeglobs