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


 
#lang transd
 
MainModule: {
 
contains-duplicates: (λ s String() -> Bool()
    (with str String(s) (sort str) 
        (ret (neq (find-adjacent str) (end str))))
),
 
play: (λ 
    syms "0123456789" 
    len 4 
    thenum String() 
    guess String()
 
    (shuffle syms)
    (= thenum (substr syms 0 len))
    (textout "Your guess: ")
    (while (getline guess)
        (if (eq guess "q") break)
        (if (or (neq (size guess) len) 
                (neq (find-first-not-of guess syms) -1)
                (contains-duplicates guess))
            (lout guess " is not valid guess")
            (textout "Your guess: ")
            continue
        )
        (with bulls 0 cows 0 pl 0
            (for i in Range(len) do 
                (= pl (find thenum (subn guess i)))
                (if (eq pl i) (+= bulls 1)
                elsif (neq pl -1) (+= cows 1))
            )
            (lout "bulls: " bulls ", cows: " cows)
            (if (eq bulls len)
                (lout "Congratulations! You have found out the number!")
                (ret null)
            else (textout "Your guess: "))
        )
    )
    (lout "You quit the game.")
),
 
_start: (λ s String()
    (lout "Welcome to \"Bulls and cows\"!") 
    (while true
        (while true
            (textout "Do you want to play? (yes|no) : ")
            (textin s 3)
            (if (not (size s)) 
                (lout "Didn't receive an answer. Exiting.") (exit)
            elsif (== (sub (tolower s) 0 1) "n") (lout "Bye!")(exit)
            elsif (== (sub (tolower s) 0 1) "y") break
            else (lout "(Hint: \"yes\" or \"no\".)"))
        )
        (play)
        (lout "Another game?")
    )
)
}
 