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


DEFINE DIGNUM="4"
 
TYPE Score=[BYTE bulls,cows,err]
 
PROC Generate(CHAR ARRAY secret)
  DEFINE DIGCOUNT="9"
  CHAR ARRAY digits(DIGCOUNT)
  BYTE i,j,d,tmp,count
 
  FOR i=0 TO DIGCOUNT-1
  DO
    digits(i)=i+'1
  OD
 
  secret(0)=DIGNUM
  count=DIGCOUNT
  FOR i=1 TO DIGNUM
  DO
    d=Rand(count)
    secret(i)=digits(d)
    count==-1
    digits(d)=digits(count)
  OD
RETURN
 
PROC CheckScore(CHAR ARRAY code,guess Score POINTER res)
  BYTE i,j
 
  res.bulls=0
  res.cows=0
  IF guess(0)#DIGNUM THEN
    res.err=1
    RETURN
  FI
  res.err=0
  FOR i=1 TO DIGNUM
  DO
    IF guess(i)=code(i) THEN
      res.bulls==+1
    ELSE
      FOR j=1 TO DIGNUM
      DO
        IF j#i AND guess(j)=code(i) THEN
          res.cows==+1
          EXIT
        FI
      OD
    FI
  OD
RETURN
 
PROC Main()
  CHAR ARRAY code(DIGNUM+1),guess(255)
  Score res
 
  Generate(code)
  PrintE("Bull and cows game.") PutE()
  Print("I choose a 4-digit number from digits 1 to 9 without repetition. ")
  PrintE("Your goal is to guess it.") PutE()
  PrintE("Enter your guess:")
  DO
    InputS(guess)
    CheckScore(code,guess,res)
    Put(28) ;cursor up
    PrintF("%S -> ",guess)
    IF res.err THEN
      Print("Wrong input")
    ELSE
      PrintF("Bulls=%B Cows=%B",res.bulls,res.cows)
      IF res.bulls=DIGNUM THEN
        PutE() PutE()
        PrintE("You win!")
        EXIT
      FI
    FI
    PrintE(", try again:")
  OD
RETURN