Task

Write a player of the Bulls and Cows game, rather than a scorer. The player should give intermediate answers that respect the scores to previous attempts.

One method is to generate a list of all possible numbers that could be the answer, then to prune the list by keeping only those numbers that would give an equivalent score to how your last guess was scored. Your next guess can be any number from the pruned list.

Either you guess correctly or run out of numbers to guess, which indicates a problem with the scoring.



Related tasks

   Bulls and cows
   Guess the number
   Guess the number/With Feedback (Player)


 
guesses    =0
 
do while len( secret$) <4    '    zero not allowed    <<<<<<<<<
    n$ =chr$( int( rnd( 1) *9) +49)
    if not( instr( secret$, n$)) then secret$ =secret$ +n$
loop
 
print " Secretly, my opponent just chose a number. But she didn't tell anyone!                                     "; secret$; "."
print "     I can however be given a score for my guesses."
 
for i =1234 to 9876    '                    <<<<<<<<<
    if check( str$( i)) =0 then available$ =available$ +" " +str$( i): k =k +1
next i
 
available$ =trim$( available$)  '   remove the surplus, leading space
 
print
print "Currently holding "; k; " possible numbers. "
 
while 1
    guess$ =word$( available$, 1 +int( k *rnd( 1)), " ")
    print
    print "Computer guessed "; guess$; " & got ";
 
    bulls    =0
    cows     =0
    guesses  =guesses +1
 
    r$    =score$( guess$, secret$)
 
    bulls =val( word$( r$, 1, ","))
    cows  =val( word$( r$, 2, ","))
 
    print bulls; " bull(s), and "; cows; " cow(s), .... ";
 
    if guess$ =secret$ then
        print "Computer won after "; guesses; " guesses!";
        secs =( time$( "seconds") -now +86400) mod 86400
        print " That took "; secs; " seconds. ENDED!"
        print
        print " Now scroll right to see original choice and check!"
        exit while
    end if
 
    print " so possible numbers are now only..."
    kk      =0
    new$    =""
 
    for j =1 to k
        bullsT    =0
        cowsT     =0
 
        possible$ =word$( available$, j, " ")
 
        r$ =score$( guess$, possible$)
 
        bullsT =val( word$( r$, 1, ","))
        cowsT  =val( word$( r$, 2, ","))
 
        if ( bullsT =bulls) and ( cowsT =cows)  then
            new$ =new$ +" " +possible$    '    keep those with same score
            kk =kk +1
            print possible$; " ";
            if ( kk mod 20) =0 then print
        end if
 
        scan
    next j
 
    available$ =trim$( new$)
    k =kk
 
    scan
wend
 
end
 
function score$( a$, b$)    '   return as a csv string the number of bulls & cows.
    bulls    = 0:  cows     = 0
    for i = 1 to 4
        c$ = mid$( a$, i, 1)
        if mid$( b$, i, 1) = c$ then
            bulls = bulls + 1
        else
            if instr( b$, c$) <>0 and instr( b$, c$) <>i then cows = cows + 1
        end if
    next i
    score$ =str$( bulls); ","; str$( cows)
end function
 
function check( i$)
    check =0    '    zero flags available: 1 means not available
    for i =1 to 3
        for j =i +1 to 4
            if mid$( i$, i, 1) =mid$( i$, j, 1) then check =1
        next j
    next i
    if instr( i$, "0") then check =1
end function
 