The state data that we need to manage in the model
section includes the value sets representing the moves of User
and Computer
, and the remaining empty cells on the table. In addition, another type of state data is also needed, Match_Status
, which represents the current state of the game, whether it is continuing or finished with a certain result.
App_State
To store sets of values representing the steps taken by User
and Computer
, and the remaining blank cells on the table the most suitable is probably the Set
structure as known in the JavaScript
Sub-Series
. Because we will be able to guarantee that at least the values in each Set
will not be duplicated and are unique.
Compared to C
, Ada
‘s standard library is much broader and has more common data structures in the DSA
topic, only missing the Stack
. Obviously with a with .. use
clause we will be able to use Set
instead of self-defined Array
to solve the situation.
However, my purpose when creating this project
was to practice a little bit about my ability to define data types myself and use binding tools like subtype
and contract
; So…
1 2 3 4 5 6 7 8 9 10 11 12 13 | package App_Model is subtype Digit is Integer range 0 .. 9; type Digit_Array is array (1 .. 9) of Digit; type Status is (PLAYING, DRAW, USER_WIN, COMPUTER_WIN); type State is record Common_Set : Digit_Array; User_Set : Digit_Array; Computer_Set : Digit_Array; Match_Status : Status; end record; end App_Model; |
We have a central definition of type State
with the following components:
Common_Set
– The remaining empty cells on the tableUser_Set
– Cells thatUser
has checkedComputer_Set
– Cells thatComputer
has checkedMatch_Status
– The current state of the game
The convention used here is that *_Set
data sets will store significant arithmetic values of 1 .. 9
representing the cells on the Tic-Tac-Toe table. And the value 0
is used as a meaningless value and represents no cell on the table. So at the beginning of each chess game we will have a Common_Set
containing all the values 1 .. 9
, and User_Set
and Computer_Set
will contain the values 0
.
The status type Status
represents the states of the game listed as: In progress.. Result Draw.. User Wins.. and Computer wins.
Init_App_State;
When declaring a local variable App_State : State
, the variable is essentially allocated a memory area for the record
with uninitialized meaningful data fields. So should be similar to the Get_User_Symbol;
, here manipulate Init_App_State;
as intended can be defined with the syntax using procedure
or function
:
1 2 3 4 5 6 | -- procedure Init (App_State); -- function App_State := App_Model.Init; |
You can choose the method that suits your thinking style. And here, I choose the
procedure
to match the spirit of this Sub-Series.1 2 3 4 5 6 7 8 | package App_Model is -- subtype Digit is ... -- type State is ... procedure Init (App_State : out State); end App_Model; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | package body App_Model is procedure Init (App_State : out State) is -- local begin App_State := ( Common_Set => (1, 2, 3, 4, 5, 6, 7, 8, 9) , User_Set => (others => 0) , Computer_Set => (others => 0) , Match_Status => PLAYING ) ; -- App_State end Init; end App_Model; |
In the code used in
Main
, we will temporarily add the test command App_State
to check the operation of Init (App_State);
.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | with Ada.Text_IO; use Ada.Text_IO; with App_Model; use App_Model; with Console_IO; use Console_IO; procedure Main is User_Symbol : Symbol; App_State : State; begin Put_Symbol_Menu; Get (User_Symbol); Init (App_State); Put_Line (State'Image (App_State)); -- loop -- 3. Put_Chess_Board -- 4. Get_User_Move -- 5. Update_User_Set -- 6. Update_Match_Status -- -- 7. Put_Chess_Board -- 8. Get_Computer_Move -- 9. Update_Computer_Set -- 10. Update_Match_Status -- -- exit when App_State.Match_Status /= PLAYING; -- end loop end Main; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Choose your Symbol ... 1. Letter 'X' 2. Letter 'O' Your choice: 1 You've chosen: X (COMMON_SET => [ 1, 2, 3, 4, 5, 6, 7, 8, 9], USER_SET => [ 0, 0, 0, 0, 0, 0, 0, 0, 0], COMPUTER_SET => [ 0, 0, 0, 0, 0, 0, 0, 0, 0], MATCH_STATUS => PLAYING) |