如何将 Ada 记录类型修改为支持两种变体的联合类型?
How do I modify the Ada record type to be a union type supporting two variants?
该程序包含一些类型定义,可用于
玩数字和十字(也称为井字游戏)的程序。 gamePos2 描述了一个玩家获胜的完整位置
我正在尝试将记录类型 GamePos 更改为支持两种变体的联合类型:已完成游戏的位置和正在进行的游戏的位置。
欢迎随时提出任何问题,以便我详细说明我的问题
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;
下面的示例显示了如何创建和使用带有鉴别器的变体记录。可以在 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;
输出
$ ./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
该程序包含一些类型定义,可用于 玩数字和十字(也称为井字游戏)的程序。 gamePos2 描述了一个玩家获胜的完整位置
我正在尝试将记录类型 GamePos 更改为支持两种变体的联合类型:已完成游戏的位置和正在进行的游戏的位置。
欢迎随时提出任何问题,以便我详细说明我的问题
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;
下面的示例显示了如何创建和使用带有鉴别器的变体记录。可以在 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;
输出
$ ./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