The program contains some type definitions that can be used in a program for playing noughts and crosses (also known as tic-tac-toe). gamePos2 describes a completed position where one player has won
I am trying to change the record type GamePos to be a union type supporting two variants: a position of a completed game and a position of a game in progress.
Feel free to ask any questions so I can elaborate on my problem
type GamePos is
record
board : TTTBoard;
turn : Player;
value : Float;
end record;
procedure Put_Pos(pos : GamePos) is
begin
Put_Board(pos.board);
Put("Player to make the next move: ");
Put(pos.turn);
Put_Line("");
Put("Estimated advantage of player X over player O is: ");
Put(pos.value, 0, 0, 0);
Put_Line("");
end Put_Pos;
gamePos1 : GamePos
:= (board =>
((X, X, O),
(O, B, X),
(O, B, B)),
turn => Player_X,
value => 0.0);
gamePos2 : GamePos
:= (pos_variant => WON, -- the discriminant
board =>
((X, X, O),
(O, X, X),
(O, O, X)),
winner => Player_X);
begin
Put_Pos(gamePos1);
Put_Line("");
Put_Pos(gamePos2);
end TTT;
The example below shows how to create and use a variant record with a discriminator. More information can be found on learn.adacore.com.
main.adb
with Ada.Text_IO; use Ada.Text_IO;
procedure TTT is
type Player is (Player_X, Player_Y);
type Cell_State is (X, O, B);
type TTT_Board is array (Positive range 1 .. 3,
Positive range 1 .. 3) of Cell_State;
-- Game_State is the enumeration used as the discriminant type.
type Game_State is (Ongoing, Done);
-- Make sure you use a default initialization (here: "Ongoing"). If you
-- do not provide a default values, then the discriminant will be immutable.
type Game_Pos (State : Game_State := Ongoing) is record
Board : TTT_Board;
case State is
when Ongoing =>
Turn : Player;
Advantage : Float;
when Done =>
Winner : Player;
end case;
end record;
---------------
-- Put_Board --
---------------
procedure Put_Board (Board : TTT_Board) is
begin
for R in Board'Range (1) loop
for C in Board'Range (2) loop
Put (Board (R, C)'Image & " ");
end loop;
New_Line;
end loop;
end Put_Board;
-------------
-- Put_Pos --
-------------
procedure Put_Pos (Pos : Game_Pos) is
begin
Put_Board (Pos.Board);
New_Line;
case Pos.State is
when Ongoing =>
Put_Line ("Player to make the next move: " & Pos.Turn'Image);
New_Line;
when Done =>
Put_Line ("Winner: " & Pos.Winner'Image);
New_Line;
end case;
end Put_Pos;
Game_Pos_1 : Game_Pos :=
(State => Ongoing,
Board => ((X, X, O),
(O, B, X),
(O, B, B)),
Turn => Player_X,
Advantage => 0.0);
Game_Pos_2 : Game_Pos :=
(State => Done,
Board => ((X, X, O),
(O, X, X),
(O, O, X)),
Winner => Player_X);
begin
Put_Pos (Game_Pos_1);
New_Line;
Put_Pos (Game_Pos_2);
end TTT;
output
$ ./ttt
X X O
O B X
O B B
Player to make the next move: PLAYER_X
X X O
O X X
O O X
Winner: PLAYER_X