WITH ada.Text_IO; USE ada.Text_IO;
WITH ada.Integer_Text_IO; USE ada.Integer_Text_IO;
PROCEDURE nim IS
SUBTYPE piletype IS character RANGE 'A'..'B'; -- used to keep track of the pile being used, A or B.
chips, -- chips holds initial number of chips
pile_a, pile_b : natural; -- pile_a, pile_b hold the current number of chips in each pile
done : boolean := false; -- set to true when the game is over
whichpile : piletype; -- holds the current pile being picked from
chipstaken : positive; -- holds the number of chips taken on current turn
p1turn : boolean := true; -- keeps track of whose turn it is ...
-- when p1turn is true it is player 1's turn,
-- when false it is player 2's turn
PROCEDURE Displaypile(achips, bchips : natural);
FUNCTION Initgame RETURN natural;
FUNCTION Getpile(achips, bchips : natural; whoseturn : boolean) RETURN piletype;
FUNCTION Getchips(achips, bchips: natural; pile: piletype; whoseturn: boolean) RETURN positive;
--FUNCTION Iswinner(achips, bchips: natural) RETURN boolean;
--PROCEDURE Declarewinner(whoseturn : boolean);
PROCEDURE Displaypile(Achips, Bchips : Natural) IS
Acount: integer :=1;
Bcount: integer :=1;
BEGIN
New_line;
Put("The piles look like this:"); -- This procedure displays the chips in each pile by outputting some symbol like an 'o' or a '#'
New_line;
Put("A: ");
WHILE Acount <= achips LOOP
Put("0");
IF Acount REM 5=0 THEN
Put(" ");
END IF;
ACount:= ACount + 1;
END LOOP;
New_line;
Put("B: ");
WHILE Bcount <= Bchips LOOP
Put("0");
IF Bcount REM 5=0 THEN
Put(" ");
End IF;
Bcount:= Bcount + 1;
END LOOP;
END Displaypile;
FUNCTION Initgame RETURN Natural IS
SUBTYPE One_Twenty IS Integer RANGE 1..20;
initchips: One_Twenty;
BEGIN
Put("How many chips do you want to start with in each pile? (max 20)");
get(initchips);
return(initchips);
END Initgame;
FUNCTION Getpile(Achips, Bchips : Natural; Whoseturn : Boolean) RETURN Piletype IS
chosenpile: piletype;
BEGIN
NEW_LINE;
IF P1turn THEN
Put("Player 1, would you like to take chips from pile A or B? ");
Get(chosenpile);
IF chosenpile= 'A' AND achips < 1 THEN
Put("Sorry there are not that many chips in the pile. Please try again.");
ELSIF Chosenpile= 'B' AND Bchips < 1 THEN
PUT("Sorry there are not that many chips in the pile. Please try again.");
END IF;
ELSE
Put("Player 2, would you like to take chips from pile A or B?");
Get(Chosenpile);
IF chosenpile= 'A' AND achips < 1 THEN
Put("Sorry there are not that many chips in the pile. Please try again.");
ELSIF Chosenpile= 'B' AND Bchips < 1 THEN
PUT("Sorry there are not that many chips in the pile. Please try again.");
END IF;
END IF;
return (Whichpile);
END Getpile;
FUNCTION Getchips(achips, bchips: natural; pile : piletype; whoseturn : boolean) RETURN positive IS
notdone : boolean := true; -- set to true when acceptable chipstaken is set
BEGIN
NEW_LINE;
IF P1turn THEN
WHILE (notdone) LOOP
Put("Player 1, how many chips would you like from pile ");
Put(Whichpile);
Put("? ");
Get(chipstaken);
IF Whichpile = 'A' AND chipstaken > achips THEN
Put("Sorry there are not that many chips in the pile.");
Put(“Please try again.");
ELSIF Whichpile = 'B' AND chipstaken > bchips THEN
Put("Sorry there are not that many chips in the pile.");
Put(“Please try again.");
ELSE
notdone:= false;
END IF;
END LOOP;
ELSE -- Not P1turn
WHILE (notdone) LOOP
Put("Player 2, how many chips would you like from pile ");
Put(Whichpile);
Put("? ");
Get(chipstaken);
IF Whichpile = 'A' AND chipstaken > achips THEN
Put("Sorry there are not that many chips in the pile.");
Put(“Please try again.");
ELSIF Whichpile = 'B' AND chipstaken > bchips THEN
Put("Sorry there are not that many chips in the pile.");
Put(“Please try again.");
ELSE
notdone:= false;
END IF;
END LOOP;
END IF;
return(chipstaken);
END Getchips;
FUNCTION Iswinner (achips, bchips : natural) RETURN boolean IS
BEGIN
IF achips = 0 AND bchips = 0 THEN
return(true);
ELSE
return (false);
END IF;
END Iswinner;
PROCEDURE Declarewinner (whoseturn : boolean) IS
BEGIN
IF P1turn THEN
put(“Congratulations player 1. You won the game!);
ELSE
put(“Congratulations player 2. You won the game!);
END IF;
END Declarewinner;
BEGIN -- main program of nim
chips := initgame;
put(item=> "the number of chips you chose is ");
put(chips);
pile_a := chips;
pile_b := chips;
WHILE (NOT done) LOOP
Displaypile(achips => pile_a, bchips => pile_b);
whichpile := Getpile(achips => pile_a, bchips => pile_b, whoseturn => p1turn);
chipstaken := Getchips(achips => pile_a, bchips => pile_b, pile => whichpile, whoseturn => p1turn);
IF whichpile = 'A' THEN
pile_a := pile_a - chipstaken;
ELSE
pile_b := pile_b - chipstaken;
END IF;
IF Iswinner(achips => pile_a, bchips => pile_b) THEN
done := true;
ELSE
p1turn := NOT p1turn;
END IF;
END LOOP;
Declarewinner(p1turn);
END nim;