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


#!/usr/local/bin/shale
 
maths library
file library
string library
 
n0 var
n1 var
n2 var
n3 var
g0 var
g1 var
g2 var
g3 var
 
init dup var {
  c guess:: var
} =
 
getNum dup var {
  random maths::() 15 >> 9 % 1 +
} =
 
game dup var {
  haveWon dup var false =
  ans var
  i var
  c var
  b var
 
  c guess:: 0 =
 
  n0 getNum() =
  n1 getNum() =
  { n1 n0 == } {
    n1 getNum() =
  } while
  n2 getNum() =
  { n2 n0 == n2 n1 == or } {
    n2 getNum() =
  } while
  n3 getNum() =
  { n3 n0 == n3 n1 == n3 n2 == or or } {
    n3 getNum() =
  } while
 
  "New game" println
  { haveWon not } {
    "> " print
    stdin file:: fgets file::() {
      ans swap atoi string::() =
      g3 ans 10 % =
      g2 ans 10 / 10 % =
      g1 ans 100 / 10 % =
      g0 ans 1000 / 10 % =
      g0 0 > g0 10 < and g1 0 > g1 10 < and g2 0 > g2 10 < and g3 0 > g3 10 < and and and and {
        c 0 =
        b 0 =
 
        g0 n0 == {
          b++
        } {
          g0 n1 == g0 n2 == g0 n3 == or or { c++ } ifthen
        } if
 
        g1 n1 == {
          b++
        } {
          g1 n0 == g1 n2 == g1 n3 == or or { c++ } ifthen
        } if
 
        g2 n2 == {
          b++
        } {
          g2 n0 == g2 n1 == g2 n3 == or or { c++ } ifthen
        } if
 
        g3 n3 == {
          b++
        } {
          g3 n0 == g3 n1 == g3 n2 == or or { c++ } ifthen
        } if
 
        i c guess:: =
        i.value guess:: guess:: defined not {
          i.value guess:: guess:: var
          i.value cow:: guess:: var
          i.value bull:: guess:: var
        } ifthen
        i.value guess:: guess:: ans =
        i.value cow:: guess:: c =
        i.value bull:: guess:: b =
        c guess::++
 
        "Go  Guess Cows Bulls" println
        i 0 =
        { i c guess:: < } {
          i.value bull:: guess:: i.value cow:: guess:: i.value guess:: guess:: i 1 + "%2d  %d  %4d %5d\n" printf
          i++
        } while
 
        b 4 == { haveWon true = } ifthen
      } {
        "Illegal input" println
      } if
    } {
      0 exit
    } if
  } while
 
} =
 
play dup var {
  { true } {
    game()
  } while
} =
 
init()
play()