RosettaCodeData/Task/Nim-game/Pascal/nim-game.pas
2023-07-01 13:44:08 -04:00

90 lines
1.9 KiB
ObjectPascal

program Nim;
{$mode objfpc}{$H+}
uses
sysutils;
const
maxtokens = 12;
machine = 0;
human = 1;
var
player, tokens, taken : integer;
procedure Welcome;
begin
writeln('The Game of Nim');
writeln;
writeln('This is one of many variants of the classic game of');
writeln('Nim. We start with',maxtokens,' tokens. On each turn a player');
writeln('takes between 1 and 3 tokens. The player who takes');
writeln('the last token wins.');
writeln;
end;
procedure ShowRemaining(n : integer);
begin
writeln('Available tokens: ', n);
end;
function getnum(lowlim, toplim : integer) : integer ;
var
n : integer;
ok : boolean;
begin
repeat
write('You take: ');
readln(n);
if (n < lowlim) or (n > toplim) then
begin
writeln('Must take between ',lowlim,' and ',toplim);
write('Try again: ');
ok := false;
end
else
ok := true;
until ok;
getnum := n;
end;
function PlayTurn(player, taken, tokens : integer) : integer;
begin
if player = human then
taken := getnum(1,3)
else { machine's move this time }
begin
if tokens <= 3 then
taken := tokens { take all if 3 or less remain }
else
taken := 4 - taken; { othewise, follow winning strategy }
end;
PlayTurn := taken;
end;
procedure Report(winner : integer);
begin
if winner = human then
writeln('You took the last one, so you win. Congratulations!')
else
writeln('I took the last one, so I win. Sorry about that.');
end;
begin
Welcome;
tokens := maxtokens;
taken := 0;
player := human;
writeln('You go first');
repeat
ShowRemaining(tokens);
taken := PlayTurn(player, taken, tokens);
if player = machine then writeln('I took: ',taken);
tokens := tokens - taken;
if tokens > 0 then player := 1 - player;
until tokens <= 0;
report(player);
writeln('Thanks for playing!');
readln;
end.