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


Buf_Switch(Buf_Free)
#90 = Time_Tick                     // seed for random number generator
#91 = 10                            // random numbers in range 0 to 9
while (EOB_pos < 4) {               // 4 digits needed
    Call("RANDOM")
    BOF Ins_Char(Return_Value + '0')
    Replace("(.)(.*)\1", "\1\2", REGEXP+BEGIN+NOERR)  // remove any duplicate
}
 
#3 = 0
repeat (99) {
    Get_Input(10, "Guess a 4-digit number with no duplicate digits: ", NOCR)
    if (Reg_Size(10) == 0) { Break }                // empty string = exit
    Num_Eval_Reg(10)                                // check for numeric digits
    if (Chars_Matched != 4) {
        M("You should enter 4 numeric digits\n")
        Continue
    }
 
    Goto_Pos(4)                                     // count bulls
    Reg_Ins(10, OVERWRITE)
    #1 = Search("(.)...\1", REGEXP+BEGIN+ALL+NOERR)
 
    RS(10, "[", INSERT)                             // count cows
    RS(10, "]", APPEND)
    #2 = Search_Block(@10, 0, 4, REGEXP+BEGIN+ALL+NOERR) - #1
 
    #3++
    NT(#1, NOCR) M(" bulls,") NT(#2, NOCR) M(" cows\n") 
    if (#1 == 4) {
        M("You won after") NT(#3, NOCR) M(" guesses!\n")
        Break
    }
}
Buf_Quit(OK)
Return
 
//--------------------------------------------------------------
// Generate random numbers in range 0 <= Return_Value < #91
//  #90 = Seed    (0 to 0x7fffffff)
//  #91 = Scaling (0 to 0x10000)
 
:RANDOM:
#92 = 0x7fffffff / 48271
#93 = 0x7fffffff % 48271
#90 = (48271 * (#90 % #92) - #93 * (#90 / #92)) & 0x7fffffff
Return ((#90 & 0xffff) * #91 / 0x10000)