Now we will add logic to handle the last move for Computer
; And given the average length of the articles that we are applying, it is likely that we will need a few more posts to complete the procedure
. This is accompanied by a summary of the most remarkable things that I have learned about Procedural Programming
with the help of Ada
.
Here we will talk a little bit about how thinking handles the case of multiple Double_Threat
at the end of the previous article.
1 2 3 4 5 6 7 8 9 10 11 12 | User : X Computer : O + - - + - - + - - + | | | X | + - - + - - + - - + | | O | | + - - + - - + - - + | X | | | + - - + - - + - - + Computer move : |
Suppose if we put ourselves in the position of the Computer
‘s move, we will see that on the next turn the User
on the other side has a chance to create a Double_Threat
if we select the box in the upper left corner or the lower right corner. Obviously blocking Block_Double_Threat
directly will not resolve the situation to equalize the outcome of the game. If so we need to create a Direct_Chance
direct win chance to force the User
side to prioritize blocking instead of creating Double_Threat
on the next move as they intended.
We will probably have multiple options on the next move to generate a direct chance of winning with any empty cells that have the ability to combine with the boxes marked with O
to create a near-perfect line. However, our goal in this case is not simply to generate Direct_Chance
but to get the User
to select Direct_Chance
to intercept and deviate from the Double_Threat
generation steps. And that means when choosing a Direct_Chance
value for Computer
, we have to exclude the case that this value is also present in the Double_Threat
set from the User
side.
So we’ll call the predictive move to initialize the chance Direct_Chance_Init
, and the winning move that the User
needs to block is Direct_Chance
. And the supporting procedure
that we need are:
Get_Double_Threats;
– Predict the value set of steps theUser
might be taking to createDouble_Threat
.Get_Direct_Chance_Inits;
– Predicting the set of moves will initiate a direct chance of winning for theComputer
.Get_Direct_Chance;
– Predict the move that will complete the winning line of theComputer
corresponding to the previously predicted move and at the same time this is also the step that theComputer
needs to choose to block.
And the configuration file of the package AI_Mockup
will have a complete list with the new sub-program
being temporarily -- comment
as follows:
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 29 | with App_Model; use App_Model; package AI_Mockup is procedure Get (Computer_Move : out Digit; App_State : in State); procedure Get_Prioritized (Computer_Move : out Digit; App_State : in State); procedure Block_Direct_Winning (Computer_Move : in out Digit; App_State : in State); procedure Block_Double_Threat (Computer_Move : in out Digit; App_State : in State); -- procedure Redirect_User_Concern (Computer_Move : in out Digit; App_State : in State); -- procedure Get_Double_Threats (User_Moves : in out Digit_Array; App_State : in State); -- procedure Get_Direct_Chance_Inits (Computer_Moves : in out Digit_Array; App_State : in State); -- procedure Get_Direct_Chance (Computer_Move : in out Digit; App_State : in State); function Count_Direct_Threats (App_State : State) return Integer; -- function Count_Double_Threats (App_State : State) -- return Integer; -- function Count_Direct_Chances (App_State : State) -- return Integer; end AI_Mockup; |
We’ll start with a line of code that adds logic to the procedure Get (Computer_Move)
and omit -- comment
to write code for each of the proposed supporting procedure
. New additional processing logic called Redirect_User_Concern;
and has higher priority than Block_Double_Threat
and lower than Block_Direct_Winning
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | with Ada.Text_IO; use Ada.Text_IO; package body AI_Mockup is procedure Get ( Computer_Move : out Digit ; App_State : in State ) is begin Get_Prioritized (Computer_Move, App_State); Block_Double_Threat (Computer_Move, App_State); Redirect_User_Concern (Computer_Move, App_State); -- new Block_Direct_Winning (Computer_Move, App_State); -- Put_Line ("Computer move:" & Digit'Image (Computer_Move)); end Get; -- ... end AI_Mockup; |
And here we are expecting that Redirect_User_Concern;
will only really work when we see multiple Double_Threat
, because if we only see a single Double_Threat
we would already have the desired result on the line calling Block_Double_Threat;
just before that. So we will need to create a support operation to count the number of Count_Double_Threats
before deciding to run the logic to handle the situation.
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | with Ada.Text_IO; use Ada.Text_IO; package body AI_Mockup is -- ... procedure Redirect_User_Concern ( Computer_Move : in out Digit ; App_State : in State ) is begin if Count_Double_Threats (App_State) > 1 then Put_Line ("Double_Threats : " & Integer'Image (Count_Double_Threats (App_State))); end if; end Redirect_User_Concern; -- ... -- function Count_Direct_Threats ... function Count_Double_Threats (App_State : State) return Integer is -- local Foreseen_User_Move : Digit := 0; Foreseen_App_State : State; Counter : Integer := 0; begin for Index in App_State.Common_Set'Range loop if App_State.Common_Set (Index) /= 0 then Copy (Foreseen_App_State, App_State); Foreseen_User_Move := App_State.Common_Set (Index); Update_User_Set (Foreseen_App_State, Foreseen_User_Move); -- if Count_Direct_Threats (Foreseen_App_State) > 1 then Counter := Counter + 1; end if; end if; end loop; -- return Counter; end Count_Double_Threats; end AI_Mockup; |
Here we consider that User
‘s next move can be any empty square left on the current chessboard because we haven’t fixed the move for Computer
yet. And so it would be necessary to iterate through each significant value of the Common_Set
assuming that it will be chosen by the User
to generate Forseen_App_State
predictive instances. Then for the case where we find the number of direct threats Count_Direct_Threats
to be plural, we increase the count variable by one.
Now we need to check the chess case at the beginning of the article, User
has the ability to create Double_Threat
in the empty cells in the upper left corner and the lower right corner.
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | alr run Choose your Symbol ... 1. Letter 'X' 2. Letter 'O' Your choice: 1 You've chosen: X + - - + - - + - - + | 2 | 9 | 4 | + - - + - - + - - + | 7 | 5 | 3 | + - - + - - + - - + | 6 | 1 | 8 | + - - + - - + - - + Your move: 6 PLAYING ... + - - + - - + - - + | 2 | 9 | 4 | + - - + - - + - - + | 7 | 5 | 3 | + - - + - - + - - + | X | 1 | 8 | + - - + - - + - - + Computer move: 5 PLAYING ... + - - + - - + - - + | 2 | 9 | 4 | + - - + - - + - - + | 7 | O | 3 | + - - + - - + - - + | X | 1 | 8 | + - - + - - + - - + Your move: 4 PLAYING ... + - - + - - + - - + + - - + - - + - - + | 2 | 9 | X | => | ? | | X | + - - + - - + - - + + - - + - - + - - + | 7 | O | 3 | => | | O | | + - - + - - + - - + + - - + - - + - - + | X | 1 | 8 | => | X | | ? | + - - + - - + - - + + - - + - - + - - + Double_Threats : 2 Computer move: _ |
And another situation where User
goes first in the central blank with more chance of creating Double_Threat
.
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | alr run Choose your Symbol ... 1. Letter 'X' 2. Letter 'O' Your choice: 1 You've chosen: X + - - + - - + - - + | 2 | 9 | 4 | + - - + - - + - - + | 7 | 5 | 3 | + - - + - - + - - + | 6 | 1 | 8 | + - - + - - + - - + Your move: 5 PLAYING ... + - - + - - + - - + | 2 | 9 | 4 | + - - + - - + - - + | 7 | X | 3 | + - - + - - + - - + | 6 | 1 | 8 | + - - + - - + - - + Computer move: 2 PLAYING ... + - - + - - + - - + | O | 9 | 4 | + - - + - - + - - + | 7 | X | 3 | + - - + - - + - - + | 6 | 1 | 8 | + - - + - - + - - + Your move: 8 PLAYING ... + - - + - - + - - + + - - + - - + - - + | O | 9 | 4 | => | O | | ? | + - - + - - + - - + + - - + - - + - - + | 7 | X | 3 | => | | X | ? | + - - + - - + - - + + - - + - - + - - + | 6 | 1 | X | => | ? | ? | X | + - - + - - + - - + + - - + - - + - - + Double_Threats : 4 Computer move: _ |
[Procedural Programming + Ada] Lesson 26 – Console Tic-Tac-Toe App (continued)