Bulls and Cows


Task

Create a four digit random number from the digits   1   to   9,   without duplication.

The program should:

   ask for guesses to this number
   reject guesses that are malformed
   print the score for the guess


The score is computed as:

 The player wins if the guess is the same as the randomly chosen number, and the program ends.
 A score of one bull is accumulated for each digit in the guess that equals the corresponding digit in the randomly chosen initial number.
 A score of one cow is accumulated for each digit in the guess that also appears in the randomly chosen number, but in the wrong position.


Related tasks

   Bulls and cows/Player
   Guess the number
   Guess the number/With Feedback
   Mastermind


secret_length = 4
 
secret = [1 2 3 4 5 6 7 8 9].shuffle.pop secret_length
 
score = { guess |
  cows = 0
  bulls = 0 
 
  guess.each_with_index { digit, index | 
    true? digit == secret[index]
      { bulls = bulls + 1 }
      { true? secret.include?(digit)
        { cows = cows + 1 }
      }
  } 
 
  [cows: cows, bulls: bulls]
}
 
won = false
guesses = 1
 
p "I have chosen a number with four unique digits from 1 through 9. Can you guess it?"
 
while { not won }
  {
    print "Guess #{guesses}: "
    guess = g.strip.dice.map { d | d.to_i }
 
    when { guess == secret }  { p "You won in #{guesses} guesses!"; won = true }
      { guess.include?(0) || guess.include?(null) } { p "Your guess should only include digits 1 through 9." }
      { guess.length != secret.length } { p "Your guess was not the correct length. The number has exactly #{secret.length} digits." }
      { guess.unique.length != secret.length } { p "Each digit should only appear once in your guess." }
      { true } {
        result = score guess
        p "Score: #{result[:bulls]} bulls, #{result[:cows]} cows."
        guesses = guesses + 1
      }    
  }