From 7605116b06260aeaf0f2ae57ae418cbccc7da639 Mon Sep 17 00:00:00 2001 From: James Allenspach Date: Sun, 2 Jan 2022 10:14:23 -0600 Subject: [PATCH 1/2] Initial commit --- 05_Bagels/perl/bagels.pl | 196 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100755 05_Bagels/perl/bagels.pl diff --git a/05_Bagels/perl/bagels.pl b/05_Bagels/perl/bagels.pl new file mode 100755 index 00000000..92318e13 --- /dev/null +++ b/05_Bagels/perl/bagels.pl @@ -0,0 +1,196 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +# global variable declaration (just the user's score) +my($Y) = 0; + + +# yes_input is a subroutine that returns a true value +# if the first character of the user's input from STDIN +# is a 'Y' (checking case-insensitively via regex) +sub yes_input { + chomp(my $A = ); + return $A =~ m/^Y/i; +} + +# Main code starts here. +# +# Provide instructions if requested + +print ' 'x32; print "Bagels\n"; +print ' 'x14; print "Creative Computing Morristown, New Jersey\n\n"; + +print "Would you like the rules (yes or no)? "; +if (yes_input()) { + + # Print out the instructions using a here doc + # (useful for large blocks of text) + print <); + + # Use a regex to check if the user entered three digits, + # and complain if they did not. + if ($A !~ m{^(\d)(\d)(\d)$}) { + print "What?\n"; + # Program execution will now pass through the rest + # of the logic below and loop back to the start + # of the CHECK loop. + } else { + + # As a side effect of the regex match above, the + # $1, $2, and $3 variables are each of the digits + # of the user's guess. Perl treats numbers and + # strings interchangably, so we will not have to + # use the ASC() conversion functions required + # by the BASIC program. + my @B = ($1,$2,$3); + + # Check for duplicate digits in the user's guess + if ($B[0] == $B[1] || $B[0] == $B[2] || $B[1] == $B[2]) { + print "Oh, I forgot to tell you that the number I have in mind\n"; + print "has no two digits the same.\n"; + # Again, no further action is required here + # because we want to loop back to the start + # of the CHECK loop. + } else { + + # This code block is the actual game logic, so + # it's executed only if the user's input has + # passed all the above checks. + my($C,$D); + $C = 0; $D = 0; + + # As a replacement for the original BASIC logic, + # this for loop works over an anonymous array of + # pairs of digits to compare the computer's and + # the user's digits to see how many similar ones + # there are. Keep in mind that Perl arrays are + # zero-indexed, so we're comparing items numbered + # 0, 1, and 2, instead of 1, 2, and 3 in BASIC. + + for my $PAIR ( [0,1], [1,0], [1,2], [2,1], [0,2], [2,0] ) { + if ($A[$PAIR->[0]] == $B[$PAIR->[1]]) { + ++$C; + } + } + + # Check for digits that are correctly guessed + for my $i (0..2) { + if ($A[$i] == $B[$i]) { + ++$D; + } + } + + # If the user guessed all 3 digits they get + # a point, and the 'PLAY' loop is restarted + # (see the 'continue' loop below) + if ($D == 3) { + print "You got it!!!\n\n"; + ++$Y; + next PLAY; + } + + # Print out the clues. The 'x' operator + # prints out the string the indicated number + # of times. The "BAGELS" line uses Perl's + # ternary operator to print the word if + # the expression ($C + $D) is equal to 0. + + printf("%s%s%s\n", + "PICO " x$C, + "FERMI "x$D, + ($C+$D==0 ? "BAGELS" : '') + ); + + # Program execution leaves the CHECK loop and + # goes to the next iteration of the $i loop. + last CHECK; + + } # end of game logic else block + } # end of regex match else block + + # If program execution reaches this particular point, + # then the user's input has not been accepted (the + # only ways out of this loop are the "next PLAY" statement + # when the user wins, and the "last CHECK" statement + # when the user's input is successfully parsed). + # So the program execution goes back to the top of the + # CHECK loop, printing the request for user input + # again. + + } # end of CHECK loop + + # This location is reached by the "last CHECK" statement, + # and it's another execution of the $i loop. + + } # end of $i loop + + # If program execution reaches here, the user has guessed 20 + # times and not won. + + print "Oh well.\n"; + printf("That's twenty guesses. My number was %s\n", join('',@A)); + +} # end of the PLAY loop + +# This 'continue' block is executed before the conditional part of the +# PLAY loop is evaluated, so we can ask if the user wants another game +# (i.e., if we should restart the PLAY loop). + +continue { + + # This 'continue' loop is reached either when the PLAY loop has completed + # or via the 'next PLAY' statement when the user wins a game. In either + # case we ask if the player wants to go again, and use the 'last' + # statement to exit the loop if the response is not yes. + print "Play again (yes or no) ? "; + last unless yes_input(); +} + +# And as in the original BASIC program, print out +# the user's score only if it is > 0. +printf("A %d point bagels buff!\n", $Y) if $Y > 0; +print "Hope you had fun. Bye.\n"; From e37cad9ae3893b68797901fea888848790fed672 Mon Sep 17 00:00:00 2001 From: James Allenspach Date: Sun, 2 Jan 2022 10:18:35 -0600 Subject: [PATCH 2/2] Modified comment --- 05_Bagels/perl/bagels.pl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/05_Bagels/perl/bagels.pl b/05_Bagels/perl/bagels.pl index 92318e13..739ded0e 100755 --- a/05_Bagels/perl/bagels.pl +++ b/05_Bagels/perl/bagels.pl @@ -16,12 +16,11 @@ sub yes_input { } # Main code starts here. -# -# Provide instructions if requested print ' 'x32; print "Bagels\n"; print ' 'x14; print "Creative Computing Morristown, New Jersey\n\n"; +# Provide instructions if requested print "Would you like the rules (yes or no)? "; if (yes_input()) {