From 7a7b86d458dabf99f5cee873e0fd8443df97c166 Mon Sep 17 00:00:00 2001 From: Tom Armitage Date: Sun, 28 Feb 2021 18:32:34 +0000 Subject: [PATCH 1/9] First pass at 'bagels' port. --- 05 Bagels/ruby/bagels.rb | 106 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 05 Bagels/ruby/bagels.rb diff --git a/05 Bagels/ruby/bagels.rb b/05 Bagels/ruby/bagels.rb new file mode 100644 index 00000000..48b3a59b --- /dev/null +++ b/05 Bagels/ruby/bagels.rb @@ -0,0 +1,106 @@ +# Bagels +# Number guessing game. +# Original source unknown but suspected to be +# Lawrence Hall of Science, U.C. Berkely + +def print_instructions + puts + puts 'I am thinking of a three-digit number. Try to guess' + puts 'my number and i will give you clues as follows:' + puts ' PICO - one digit correct but in the wrong position' + puts ' FERMI - one digit correct and in the right position' + puts ' BAGELS - no digits correct' +end + +def generate_number_array + target = 0 + target = rand(100..999) while target.to_s.split('').uniq.size < 3 + target.to_s.split('') +end + +def puts_clue_for(guess_array, target_array) + clues = [].tap do |clue| + guess_array.each_with_index do |n, i| + if target_array[i] == n + clue << 'FERMI' + elsif target_array.include?(n) + clue << 'PICO' + end + end + end + + # sort clues so that FERMIs come before PICOs, but + # you don't know which response responds to which number + puts clues.length > 0 ? clues.sort.join(' ') : 'BAGELS' +end + +player_points = 0 +desire_to_play = true + +puts 'Bagels'.center(72) +puts 'Creative Computing Morristown, New Jersey'.center(72) + +5.times { puts } + +puts 'Would you like to the rules? [Y]es or [N]o.' +instructions_request = gets.chomp.downcase + +print_instructions if %w[yes y].include?(instructions_request) + +while desire_to_play + target_number_array = generate_number_array + + 2.times { puts } + puts 'OK. I have a number in mind.' + + guess_count = 0 + guess_array = [] + + while (guess_array != target_number_array) && guess_count < 20 + guess_count += 1 + + puts "Guess ##{guess_count}:" + + guess = gets.chomp + + if guess =~ /[^1-9]/ + puts 'What?' + next + end + + if guess.length != 3 + puts 'Try guessing a three digit number' + next + end + + guess_array = guess.split('') + + if guess_array.uniq.size < 3 + puts 'Oh, I forgot to tell you: the number I have in mind has no two digits the same.' + next + end + + if guess_array != target_number_array + puts_clue_for(guess_array, target_number_array) + puts + end + end + + if guess_array == target_number_array + player_points += 1 + + puts 'You got it!!!' + puts + else + puts 'Oh well.' + puts "That's twenty guesses. My number was #{target_number_array.join('')}." + end + + puts + puts 'Would you like to play again? [Y]es or [N]o' + play_again_request = gets.chomp + desire_to_play = %w[yes y].include?(play_again_request) +end + +puts "A #{player_points} point bagels buff!!" +puts 'Hope you had fun. Bye.' From ea73772a9e6f5e39e1230e43852a101f0e63f6e0 Mon Sep 17 00:00:00 2001 From: Tom Armitage Date: Sun, 28 Feb 2021 18:38:31 +0000 Subject: [PATCH 2/9] Target and guess should be number, not arrays. --- 05 Bagels/ruby/bagels.rb | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/05 Bagels/ruby/bagels.rb b/05 Bagels/ruby/bagels.rb index 48b3a59b..07024559 100644 --- a/05 Bagels/ruby/bagels.rb +++ b/05 Bagels/ruby/bagels.rb @@ -12,13 +12,15 @@ def print_instructions puts ' BAGELS - no digits correct' end -def generate_number_array - target = 0 +def generate_target target = rand(100..999) while target.to_s.split('').uniq.size < 3 - target.to_s.split('') + target end -def puts_clue_for(guess_array, target_array) +def puts_clue_for(guess_number, target_number) + guess_array = guess_number.to_s.split("") + target_array = target_number.to_s.split("") + clues = [].tap do |clue| guess_array.each_with_index do |n, i| if target_array[i] == n @@ -48,45 +50,47 @@ instructions_request = gets.chomp.downcase print_instructions if %w[yes y].include?(instructions_request) while desire_to_play - target_number_array = generate_number_array + target = generate_target 2.times { puts } puts 'OK. I have a number in mind.' - guess_count = 0 - guess_array = [] + puts target - while (guess_array != target_number_array) && guess_count < 20 + guess_count = 0 + guess = 0 + + while (guess != target) && guess_count < 20 guess_count += 1 puts "Guess ##{guess_count}:" - guess = gets.chomp + raw_guess = gets.chomp - if guess =~ /[^1-9]/ + if raw_guess =~ /[^0-9]/ puts 'What?' next end - if guess.length != 3 + if raw_guess.length != 3 puts 'Try guessing a three digit number' next end - guess_array = guess.split('') - - if guess_array.uniq.size < 3 + if raw_guess.split('').uniq.size < 3 puts 'Oh, I forgot to tell you: the number I have in mind has no two digits the same.' next end - if guess_array != target_number_array - puts_clue_for(guess_array, target_number_array) + guess = raw_guess.to_i + + if guess != target + puts_clue_for(guess, target) puts end end - if guess_array == target_number_array + if guess == target player_points += 1 puts 'You got it!!!' From 2fb3ca21cf82a2727eb860210ebd884a7764ff98 Mon Sep 17 00:00:00 2001 From: Tom Armitage Date: Sun, 28 Feb 2021 18:41:56 +0000 Subject: [PATCH 3/9] Letting Rubocop have its way. --- 05 Bagels/ruby/bagels.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/05 Bagels/ruby/bagels.rb b/05 Bagels/ruby/bagels.rb index 07024559..44cd31da 100644 --- a/05 Bagels/ruby/bagels.rb +++ b/05 Bagels/ruby/bagels.rb @@ -18,8 +18,8 @@ def generate_target end def puts_clue_for(guess_number, target_number) - guess_array = guess_number.to_s.split("") - target_array = target_number.to_s.split("") + guess_array = guess_number.to_s.split('') + target_array = target_number.to_s.split('') clues = [].tap do |clue| guess_array.each_with_index do |n, i| From 08c05d464643bd056ed969711987e7d9d44498bf Mon Sep 17 00:00:00 2001 From: Tom Armitage Date: Sun, 28 Feb 2021 18:42:28 +0000 Subject: [PATCH 4/9] Translator's notes. --- 05 Bagels/ruby/README.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/05 Bagels/ruby/README.md b/05 Bagels/ruby/README.md index fb32811e..8e47c0dd 100644 --- a/05 Bagels/ruby/README.md +++ b/05 Bagels/ruby/README.md @@ -1,3 +1,16 @@ +## BAGELS + Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) -Conversion to [Ruby](https://www.ruby-lang.org/en/) +Conversion to [Ruby](https://www.ruby-lang.org/en/) by [Tom Armitage](https://github.com/infovore) + +## Translator's notes: + +This is a highly imperative port. As such, it's very much, in the spirit of David Ahl's original version, and also highly un-Rubyish. + +A few decisions I made: + +* the main loop is a 'while' loop. Most games are a main loop that runs until it doesn't, and I felt that "while the player wished to keep playing, the game should run" was an appropriate structure. +* lots of puts and gets; that feels appropriate to the Ahl implementation. No clever cli or curses libraries here. +* the number in question, and the player's answer, are stored as numbers. They're only converted into arrays for the purpose of `puts_clue_for` - ie, when comparison is need. The original game stored them as arrays, which made sense, but given the computer says "I have a number in mind", I decided to store what was in its 'mind' as a number. +* the `String#center` method from Ruby 2.5~ sure is handy. From 412b10491d4580fe99ea24fe39d1b6f2033a1711 Mon Sep 17 00:00:00 2001 From: Tom Armitage Date: Sun, 28 Feb 2021 18:45:21 +0000 Subject: [PATCH 5/9] Remove golfy ternary. --- 05 Bagels/ruby/bagels.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/05 Bagels/ruby/bagels.rb b/05 Bagels/ruby/bagels.rb index 44cd31da..e3c2d9f7 100644 --- a/05 Bagels/ruby/bagels.rb +++ b/05 Bagels/ruby/bagels.rb @@ -13,7 +13,10 @@ def print_instructions end def generate_target - target = rand(100..999) while target.to_s.split('').uniq.size < 3 + + # pick a three digit number with no repeating numbers. + # gien that, 102-987 is a reasonable starting point! + target = rand(102..987) while target.to_s.split('').uniq.size < 3 target end @@ -33,7 +36,11 @@ def puts_clue_for(guess_number, target_number) # sort clues so that FERMIs come before PICOs, but # you don't know which response responds to which number - puts clues.length > 0 ? clues.sort.join(' ') : 'BAGELS' + if clues.length > 0 + puts clues.sort.join + else + puts 'BAGELS' + end end player_points = 0 From 7ddc519bb33928e92199384497b9d086ded0d0c9 Mon Sep 17 00:00:00 2001 From: Tom Armitage Date: Sun, 28 Feb 2021 18:45:50 +0000 Subject: [PATCH 6/9] Works better if you hide the number in mind. --- 05 Bagels/ruby/bagels.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/05 Bagels/ruby/bagels.rb b/05 Bagels/ruby/bagels.rb index e3c2d9f7..bbf2b3a2 100644 --- a/05 Bagels/ruby/bagels.rb +++ b/05 Bagels/ruby/bagels.rb @@ -62,8 +62,6 @@ while desire_to_play 2.times { puts } puts 'OK. I have a number in mind.' - puts target - guess_count = 0 guess = 0 From 6d102c6c497f9afc26f01cd45d8df94ad66bb2e7 Mon Sep 17 00:00:00 2001 From: Tom Armitage Date: Sun, 28 Feb 2021 18:46:46 +0000 Subject: [PATCH 7/9] Typo. --- 05 Bagels/ruby/bagels.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/05 Bagels/ruby/bagels.rb b/05 Bagels/ruby/bagels.rb index bbf2b3a2..9dea2b78 100644 --- a/05 Bagels/ruby/bagels.rb +++ b/05 Bagels/ruby/bagels.rb @@ -1,7 +1,7 @@ # Bagels # Number guessing game. # Original source unknown but suspected to be -# Lawrence Hall of Science, U.C. Berkely +# Lawrence Hall of Science, U.C. Berkeley def print_instructions puts From a7e099671d077a4f49e0f3ec835560de10c0e759 Mon Sep 17 00:00:00 2001 From: Tom Armitage Date: Sun, 28 Feb 2021 18:47:01 +0000 Subject: [PATCH 8/9] Spacing. --- 05 Bagels/ruby/bagels.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/05 Bagels/ruby/bagels.rb b/05 Bagels/ruby/bagels.rb index 9dea2b78..00330ce1 100644 --- a/05 Bagels/ruby/bagels.rb +++ b/05 Bagels/ruby/bagels.rb @@ -13,7 +13,6 @@ def print_instructions end def generate_target - # pick a three digit number with no repeating numbers. # gien that, 102-987 is a reasonable starting point! target = rand(102..987) while target.to_s.split('').uniq.size < 3 From 6039fb600b1ed827b6eda429d3f4c56ae2850765 Mon Sep 17 00:00:00 2001 From: Tom Armitage Date: Sun, 28 Feb 2021 18:48:33 +0000 Subject: [PATCH 9/9] Final tweaks. --- 05 Bagels/ruby/bagels.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/05 Bagels/ruby/bagels.rb b/05 Bagels/ruby/bagels.rb index 00330ce1..3a4eb789 100644 --- a/05 Bagels/ruby/bagels.rb +++ b/05 Bagels/ruby/bagels.rb @@ -47,7 +47,6 @@ desire_to_play = true puts 'Bagels'.center(72) puts 'Creative Computing Morristown, New Jersey'.center(72) - 5.times { puts } puts 'Would you like to the rules? [Y]es or [N]o.' @@ -71,16 +70,19 @@ while desire_to_play raw_guess = gets.chomp + ## if the guess isn't numerical, sound confused if raw_guess =~ /[^0-9]/ puts 'What?' next end + ## if the guess is more ore less than three digits, prompt player if raw_guess.length != 3 puts 'Try guessing a three digit number' next end + ## if the guess contains duplicate numbers, give player a clue if raw_guess.split('').uniq.size < 3 puts 'Oh, I forgot to tell you: the number I have in mind has no two digits the same.' next @@ -106,6 +108,7 @@ while desire_to_play puts puts 'Would you like to play again? [Y]es or [N]o' + play_again_request = gets.chomp desire_to_play = %w[yes y].include?(play_again_request) end