mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			189 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			189 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| Program BullCow;
 | |
| 
 | |
| {$mode objFPC}
 | |
| 
 | |
| uses Math, SysUtils;
 | |
| 
 | |
| type
 | |
|    TFourDigit = array[1..4] of integer;
 | |
| 
 | |
| Procedure WriteFourDigit(fd: TFourDigit);
 | |
| { Write out a TFourDigit with no line break following. }
 | |
| var
 | |
|    i: integer;
 | |
| begin
 | |
|    for i := 1 to 4 do
 | |
|    begin
 | |
|       Write(fd[i]);
 | |
|    end;
 | |
| end;
 | |
| 
 | |
| Function WellFormed(Tentative: TFourDigit): Boolean;
 | |
| { Does the TFourDigit avoid repeating digits? }
 | |
| var
 | |
|    current, check: integer;
 | |
| begin
 | |
| 
 | |
|    Result := True;
 | |
| 
 | |
|    for current := 1 to 4 do
 | |
|    begin
 | |
|       for check := current + 1 to 4 do
 | |
|       begin
 | |
|          if Tentative[check] = Tentative[current] then
 | |
|          begin
 | |
|             Result := False;
 | |
|          end;
 | |
|       end;
 | |
|    end;
 | |
| 
 | |
| end;
 | |
| 
 | |
| Function MakeNumber(): TFourDigit;
 | |
| { Make a random TFourDigit, keeping trying until it is well-formed. }
 | |
| var
 | |
|    i: integer;
 | |
| begin
 | |
|    for i := 1 to 4 do
 | |
|    begin
 | |
|       Result[i] := RandomRange(1, 9);
 | |
|    end;
 | |
|    if not WellFormed(Result) then
 | |
|    begin
 | |
|       Result := MakeNumber();
 | |
|    end;
 | |
| end;
 | |
| 
 | |
| Function StrToFourDigit(s: string): TFourDigit;
 | |
| { Convert an (input) string to a TFourDigit. }
 | |
| var
 | |
|    i: integer;
 | |
| begin
 | |
|    for i := 1 to Length(s) do
 | |
|    begin
 | |
|       StrToFourDigit[i] := StrToInt(s[i]);
 | |
|    end;
 | |
| end;
 | |
| 
 | |
| Function Wins(Num, Guess: TFourDigit): Boolean;
 | |
| { Does the guess win? }
 | |
| var
 | |
|    i: integer;
 | |
| begin
 | |
|    Result := True;
 | |
|    for i := 1 to 4 do
 | |
|    begin
 | |
|       if Num[i] <> Guess[i] then
 | |
|       begin
 | |
|          Result := False;
 | |
|          Exit;
 | |
|       end;
 | |
|    end;
 | |
| end;
 | |
| 
 | |
| Function GuessScore(Num, Guess: TFourDigit): string;
 | |
| { Represent the score of the current guess as a string. }
 | |
| var
 | |
|    i, j, bulls, cows: integer;
 | |
| begin
 | |
| 
 | |
|    bulls := 0;
 | |
|    cows := 0;
 | |
| 
 | |
|    { Count the cows and bulls. }
 | |
|    for i := 1 to 4 do
 | |
|    begin
 | |
|       for j := 1 to 4 do
 | |
|       begin
 | |
|          if  (Num[i] = Guess[j]) then
 | |
|          begin
 | |
|             { If the indices are the same, that would be a bull. }
 | |
|             if (i = j) then
 | |
|             begin
 | |
|                bulls := bulls + 1;
 | |
|             end
 | |
|             else
 | |
|             begin
 | |
|                cows := cows + 1;
 | |
|             end;
 | |
|          end;
 | |
|       end;
 | |
|    end;
 | |
| 
 | |
|    { Format the result as a sentence. }
 | |
|    Result := IntToStr(bulls) + ' bulls, ' + IntToStr(cows) + ' cows.';
 | |
| 
 | |
| end;
 | |
| 
 | |
| Function GetGuess(): TFourDigit;
 | |
| { Get a well-formed user-supplied TFourDigit guess. }
 | |
| var
 | |
|    input: string;
 | |
| begin
 | |
| 
 | |
|    WriteLn('Enter a guess:');
 | |
|    ReadLn(input);
 | |
| 
 | |
|    { Must be 4 digits. }
 | |
|    if Length(input) = 4 then
 | |
|    begin
 | |
| 
 | |
|       Result := StrToFourDigit(input);
 | |
| 
 | |
|       if not WellFormed(Result) then
 | |
|       begin
 | |
|          WriteLn('Four unique digits, please.');
 | |
|          Result := GetGuess();
 | |
|       end;
 | |
| 
 | |
|    end
 | |
|    else
 | |
|    begin
 | |
|       WriteLn('Please guess a four-digit number.');
 | |
|       Result := GetGuess();
 | |
|    end;
 | |
| 
 | |
| end;
 | |
| 
 | |
| var
 | |
|    Num, Guess: TFourDigit;
 | |
|    Turns: integer;
 | |
| begin
 | |
| 
 | |
|    { Initialize the randymnity. }
 | |
|    Randomize();
 | |
| 
 | |
|    { Make the secred number. }
 | |
|    Num := MakeNumber();
 | |
| 
 | |
|    WriteLn('I have a secret number. Guess it!');
 | |
| 
 | |
|    Turns := 0;
 | |
| 
 | |
|    { Guess until the user gets it. }
 | |
|    While True do
 | |
|    begin
 | |
| 
 | |
|       Guess := GetGuess();
 | |
| 
 | |
|       { Count each guess as a turn. }
 | |
|       Turns := Turns + 1;
 | |
| 
 | |
|       { If the user won, tell them and ditch. }
 | |
|       if Wins(Num, Guess) then
 | |
|       begin
 | |
|          WriteLn('You won in ' + IntToStr(Turns) + ' tries.');
 | |
|          Write('The number was ');
 | |
|          WriteFourDigit(Num);
 | |
|          WriteLn('!');
 | |
|          Exit;
 | |
|       end
 | |
|       else { Otherwise, score it and get a new guess. }
 | |
|       begin
 | |
|          WriteLn(GuessScore(Num, Guess));
 | |
|       end;
 | |
| 
 | |
|    end;
 | |
| 
 | |
| end.
 |