90 lines
1.9 KiB
ObjectPascal
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.
|