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


$ include "seed7_05.s7i";
 
const proc: main is func
  local
    const integer: size is 4;
    var set of char: digits is {'1' .. '9'};
    var string: chosen is " " mult size;
    var integer: guesses is 0;
    var string: guess is "";
    var integer: pos is 0;
    var integer: bulls is 0;
    var integer: cows is 0;
    var boolean: okay is FALSE;
  begin
    for pos range 1 to 4 do
      chosen @:= [pos] rand(digits);
      excl(digits, chosen[pos]);
    end for;
    writeln("I have chosen a number from " <& size <& " unique digits from 1 to 9 arranged in a random order.");
    writeln("You need to input a " <& size <& " digit, unique digit number as a guess at what I have chosen");
    repeat
      incr(guesses);
      repeat
        write("Next guess [" <& guesses <& "]: ");
        readln(guess);
        okay := length(guess) = size;
        for key pos range guess do
          okay := okay and guess[pos] in {'1' .. '9'} and pos(guess[succ(pos) ..], guess[pos]) = 0;
        end for;
        if not okay then
          writeln("Problem, try again. You need to enter " <& size <& " unique digits from 1 to 9");
        end if;
      until okay;
      if guess <> chosen then
        bulls := 0;
        cows := 0;
        for key pos range chosen do
          if guess[pos] = chosen[pos] then
            incr(bulls);
          elsif pos(chosen, guess[pos]) <> 0 then
            incr(cows);
          end if;
        end for;
        writeln("  " <& bulls <& " Bulls");
        writeln("  " <& cows <& " Cows");
      end if;
    until guess = chosen;
    writeln("Congratulations you guessed correctly in " <& guesses <& " attempts");
  end func;