[four-in-a-row] Use uint8 more.



commit a818be7d42845c10388950f03f7998887a2d848a
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date:   Mon Dec 23 10:32:34 2019 +0100

    Use uint8 more.

 src/ai.vala            | 141 ++++++++++++++++++++++++++-----------------------
 src/four-in-a-row.vala |  32 +++--------
 src/player.vala        |   6 +++
 src/test-ai.vala       | 137 ++++++++++++++++++++++++-----------------------
 4 files changed, 157 insertions(+), 159 deletions(-)
---
diff --git a/src/ai.vala b/src/ai.vala
index 6a07354..6b56b57 100644
--- a/src/ai.vala
+++ b/src/ai.vala
@@ -20,7 +20,7 @@
 
 private enum Difficulty { EASY, MEDIUM, HARD; }
 
-private int playgame(string moves_until_now)
+private uint8 playgame(string moves_until_now)
 {
     DecisionTree t = new DecisionTree();
     return t.playgame(moves_until_now);
@@ -34,34 +34,32 @@ private class DecisionTree
     MAX_HEURIST_VALUE < NEG_INF/plies */
     private const int NEG_INF = -100000;
     private const int MAX_HEURIST_VALUE = 10000;
-    private const int BOARD_ROWS = 6;
-    private const int BOARD_COLUMNS = 7;
 
     /* to mantain the status of the board, to be used by the heuristic function, the top left cell is [0, 0] 
*/
     private Player[,] board = new Player [BOARD_ROWS, BOARD_COLUMNS];
     /* plies - depth of the DecisionTree */
-    private int plies = 8;
+    private uint8 plies = 8;
     /* last_moving_player - The player who made the last move, set to Player.NOBODY if no one has made a 
move yet */
     private Player last_moving_player = Player.NOBODY;
     /* next_move_in_column - stores the column number in which next move is to be made */
-    private int next_move_in_column = -1;
+    private uint8 next_move_in_column = uint8.MAX;
     /* stores the difficulty level of the game */
     private Difficulty level;
 
     /* Initializes an empty board */
     internal DecisionTree()
     {
-        for (int i = 0; i < BOARD_ROWS; i++)
-            for (int j = 0; j < BOARD_COLUMNS; j++)
+        for (uint8 i = 0; i < BOARD_ROWS; i++)
+            for (uint8 j = 0; j < BOARD_COLUMNS; j++)
                 board [i, j] = Player.NOBODY;
     }
 
     /* utility function for debugging purposes, prints a snapshot of current status of the board */
     internal void print_board()
     {
-        for (int i = 0; i< BOARD_ROWS; i++)
+        for (uint8 i = 0; i < BOARD_ROWS; i++)
         {
-            for (int j = 0; j < BOARD_COLUMNS; j++)
+            for (uint8 j = 0; j < BOARD_COLUMNS; j++)
                 stdout.printf("%d\t", board [i, j]);
             stdout.printf("\n");
         }
@@ -70,7 +68,7 @@ private class DecisionTree
 
     /* Recursively implements a negamax tree in memory with alpha-beta pruning. The function is first called 
for the root node.
        It returns the value of the current node. For nodes at height == 0, the value is determined by a 
heuristic function. */
-    private int negamax(int height, int alpha, int beta)
+    private int negamax(uint8 height, int alpha, int beta)
     {
         /* base case of recursive function, returns if we have reached the lowest depth of DecisionTree or 
the board if full */
         if (height == 0 || board_full())
@@ -89,9 +87,9 @@ private class DecisionTree
 
         /* Local variable that stores the column number in which next move is to be made.
            Initialized with -1 because we do not know the column number yet. */
-        int next = -1;
+        uint8 next = uint8.MAX;
 
-        for (int column = 0; column < BOARD_COLUMNS; column++)
+        for (uint8 column = 0; column < BOARD_COLUMNS; column++)
         {
             /* make a move into the i'th column */
             if (!move(column))
@@ -125,10 +123,10 @@ private class DecisionTree
     }
 
     /* all these functions return true if last_moving_player wins, or false */
-    private bool victory(int column)
+    private bool victory(uint8 column)
     {
         /* find the cell on which the last move was made */
-        int row;
+        uint8 row;
         for (row = 0; row < BOARD_ROWS && board [row, column] == Player.NOBODY; row++);
 
         return vertical_win(row, column) ||
@@ -137,41 +135,50 @@ private class DecisionTree
                backward_diagonal_win(row, column);
     }
 
-    private inline bool forward_diagonal_win(int i, int j)
+    private inline bool forward_diagonal_win(uint8 _i, uint8 _j)
     {
-        int count = 0;
+        int8 i = (int8) _i;
+        int8 j = (int8) _j;
+
+        uint8 count = 0;
 
-        for (int k = i, l = j; k >= 0 && l < BOARD_COLUMNS && board [k, l] == last_moving_player; k--, l++, 
count++);
-        for (int k = i + 1, l = j - 1; k < BOARD_ROWS && l >= 0 && board [k, l] == last_moving_player; k++, 
l--, count++);
+        for (int8 k = i, l = j; k >= 0 && l < BOARD_COLUMNS && board [k, l] == last_moving_player; k--, l++, 
count++);
+        for (int8 k = i + 1, l = j - 1; k < BOARD_ROWS && l >= 0 && board [k, l] == last_moving_player; k++, 
l--, count++);
 
         return count >= 4;
     }
 
-    private inline bool backward_diagonal_win(int i, int j)
+    private inline bool backward_diagonal_win(uint8 _i, uint8 _j)
     {
-        int count = 0;
+        int8 i = (int8) _i;
+        int8 j = (int8) _j;
 
-        for (int k = i, l = j; k >= 0 && l >= 0 && board [k, l] == last_moving_player; k--, l--, count++);
-        for (int k = i + 1, l = j + 1; k < BOARD_ROWS && l < BOARD_COLUMNS && board [k, l] == 
last_moving_player; k++, l++, count++);
+        uint8 count = 0;
+
+        for (int8 k = i, l = j; k >= 0 && l >= 0 && board [k, l] == last_moving_player; k--, l--, count++);
+        for (int8 k = i + 1, l = j + 1; k < BOARD_ROWS && l < BOARD_COLUMNS && board [k, l] == 
last_moving_player; k++, l++, count++);
 
         return count >= 4;
     }
 
-    private inline bool horizontal_win(int i, int j)
+    private inline bool horizontal_win(uint8 _i, uint8 _j)
     {
-        int count = 0;
+        int8 i = (int8) _i;
+        int8 j = (int8) _j;
 
-        for (int k = j; k >= 0 && board [i, k] == last_moving_player; k--, count++);
-        for (int k = j + 1; k < BOARD_COLUMNS && board [i, k] == last_moving_player; k++, count++);
+        uint8 count = 0;
+
+        for (int8 k = j; k >= 0 && board [i, k] == last_moving_player; k--, count++);
+        for (int8 k = j + 1; k < BOARD_COLUMNS && board [i, k] == last_moving_player; k++, count++);
 
         return count >= 4;
     }
 
-    private inline bool vertical_win(int i, int j)
+    private inline bool vertical_win(uint8 i, uint8 j)
     {
-        int count = 0;
+        uint8 count = 0;
 
-        for (int k = i; k < BOARD_ROWS && board [k, j] == last_moving_player; k++, count++);
+        for (uint8 k = i; k < BOARD_ROWS && board [k, j] == last_moving_player; k++, count++);
 
         return count >= 4;
     }
@@ -179,17 +186,17 @@ private class DecisionTree
     /* returns true if the board is full, false if not */
     private bool board_full()
     {
-        for (int i = 0 ; i < BOARD_COLUMNS ; i++)
+        for (uint8 i = 0 ; i < BOARD_COLUMNS ; i++)
             if (board [0, i] == Player.NOBODY)
                 return false;
         return true;
     }
 
     /* makes a move into the column'th column. Returns true if the move was succesful, false if it wasn't */
-    private bool move(int column)
+    private bool move(uint8 column)
     {
         /* find the cell on which to move */
-        int row;
+        int8 row;
         for (row = BOARD_ROWS - 1; row >= 0 && board [row, column] != Player.NOBODY; row--);
 
         if (row < 0)
@@ -204,11 +211,11 @@ private class DecisionTree
     }
 
     /* unmove the last move made in the column'th column */
-    private void unmove(int column)
+    private void unmove(uint8 column)
         requires(last_moving_player != Player.NOBODY)
     {
         /* find the cell on which the last move was made */
-        int row;
+        uint8 row;
         for (row = 0; row < BOARD_ROWS && board [row, column] == Player.NOBODY; row++);
 
         board [row, column] = Player.NOBODY;
@@ -219,19 +226,19 @@ private class DecisionTree
     /* vstr is the sequence of moves made until now. We update DecisionTree::board to reflect these sequence 
of moves. */
     private void update_board(string vstr)
     {
-        next_move_in_column = -1;
+        next_move_in_column = uint8.MAX;
 
         /* AI will make the first move, nothing to add to the board */
         if (vstr.length == 2) return;
 
         Player move = vstr.length % 2 == 0 ? Player.OPPONENT : Player.HUMAN;
 
-        for (int i = 1; i < vstr.length - 1; i++)
+        for (uint8 i = 1; i < vstr.length - 1; i++)
         {
-            int column = int.parse(vstr [i].to_string()) - 1;
+            uint8 column = (uint8) int.parse(vstr [i].to_string()) - 1;
 
             /* find the cell on which the move is made */
-            int row;
+            int8 row;
             for (row = BOARD_ROWS - 1; row >= 0 && board [row, column] != Player.NOBODY; row--);
 
             board [row, column] = move;
@@ -242,16 +249,16 @@ private class DecisionTree
         last_moving_player = Player.HUMAN;
     }
 
-    /* Check for immediate win of HUMAN or OPPONENT. It checks the current state of the board. Returns -1 if 
no immediate win for Player P.
+    /* Check for immediate win of HUMAN or OPPONENT. It checks the current state of the board. Returns 
uint8.MAX if no immediate win for Player P.
        Otherwise returns the column number in which Player P should move to win. */
-    private int immediate_win(Player p)
+    private uint8 immediate_win(Player p)
     {
         Player old_last_moving_player = last_moving_player;
 
         last_moving_player = p == Player.OPPONENT ? Player.HUMAN : Player.OPPONENT;
 
         bool player_wins = false;
-        int i;
+        uint8 i;
         for (i = 0; i < BOARD_COLUMNS; i++)
         {
             if (!move(i))
@@ -266,12 +273,12 @@ private class DecisionTree
 
         last_moving_player = old_last_moving_player;
 
-        /* returns -1 if no immediate win for Player p */
-        return player_wins ? i : -1;
+        /* returns uint8.MAX if no immediate win for Player p */
+        return player_wins ? i : uint8.MAX;
     }
 
-    /* returns the column number in which the next move has to be made. Returns -1 if the board is full. */
-    internal int playgame(string vstr)
+    /* returns the column number in which the next move has to be made. Returns uint8.MAX if the board is 
full. */
+    internal uint8 playgame(string vstr)
     {
         /* set the Difficulty level */
         set_level(vstr);
@@ -279,23 +286,22 @@ private class DecisionTree
         /* update DecisionTree::board to reflect the moves made until now */
         update_board(vstr);
 
-        /* if AI can win by making a move immediately, make that move;
-           main.c has indexing beginning from 1 instead of 0, hence, we add 1 */
-        int temp = immediate_win(Player.OPPONENT);
-        if (temp != -1)
-            return temp + 1;
+        /* if AI can win by making a move immediately, make that move */
+        uint8 temp = immediate_win(Player.OPPONENT);
+        if (temp < BOARD_COLUMNS)
+            return temp;
 
         /* if HUMAN can win by making a move immediately,
            we make AI move in that column so as avoid loss */
         temp = immediate_win(Player.HUMAN);
-        if (temp != -1)
-            return temp + 1;
+        if (temp < BOARD_COLUMNS)
+            return temp;
 
         /* call negamax tree on the current state of the board */
         negamax(plies, NEG_INF, -1 * NEG_INF);
 
         /* return the column number in which next move should be made */
-        return next_move_in_column + 1;
+        return next_move_in_column;
     }
 
     /* The evaluation function to be called when we have reached the maximum depth in the DecisionTree */
@@ -335,9 +341,9 @@ private class DecisionTree
 
         last_moving_player = p;
 
-        for (int j = 0; j < BOARD_COLUMNS; j++)
+        for (uint8 j = 0; j < BOARD_COLUMNS; j++)
         {
-            for (int i = 0; i < BOARD_ROWS; i++)
+            for (uint8 i = 0; i < BOARD_ROWS; i++)
             {
                 if (board [i, j] != Player.NOBODY)
                     break;
@@ -358,11 +364,14 @@ private class DecisionTree
     }
 
     /* checks if all adjacent cells to board [i, j] are empty */
-    private inline bool all_adjacent_empty(int i, int j)
+    private inline bool all_adjacent_empty(uint8 _i, uint8 _j)
     {
-        for (int k = -1 ; k <= 1; k++)
+        int8 i = (int8) _i;
+        int8 j = (int8) _j;
+
+        for (int8 k = -1 ; k <= 1; k++)
         {
-            for (int l = -1; l <= 1; l++)
+            for (int8 l = -1; l <= 1; l++)
             {
                 if (k == 0 && l == 0)
                     continue;
@@ -387,7 +396,7 @@ private class DecisionTree
             level = Difficulty.MEDIUM;
             plies = 7;
         }
-        else
+        else // TODO if (vstr [0] == 'c') / else assert_not_reached ();
         {
             level = Difficulty.HARD;
             plies = 7;
@@ -395,21 +404,21 @@ private class DecisionTree
     }
 
     /* utility function for testing purposes */
-    internal int playandcheck(string vstr)
+    internal uint8 playandcheck(string vstr)
     {
         set_level(vstr);
         update_board(vstr);
 
-        int temp = immediate_win(Player.OPPONENT);
-        if (temp != -1)
-            return 1000;
+        uint8 temp = immediate_win(Player.OPPONENT);
+        if (temp < BOARD_COLUMNS)
+            return 100;
 
         temp = immediate_win(Player.HUMAN);
-        if (temp != -1)
-            return temp + 1;
+        if (temp < BOARD_COLUMNS)
+            return temp;
 
         negamax(plies, NEG_INF, -1 * NEG_INF);
 
-        return next_move_in_column + 1;
+        return next_move_in_column;
     }
 }
diff --git a/src/four-in-a-row.vala b/src/four-in-a-row.vala
index 85b482d..cb4fbf3 100644
--- a/src/four-in-a-row.vala
+++ b/src/four-in-a-row.vala
@@ -21,13 +21,6 @@
 
 using Gtk;
 
-// if you want to play, update also the two const in ai.vala
-private const uint8 BOARD_COLUMNS = 7;
-private const uint8 BOARD_COLUMNS_MINUS_ONE = 6;
-private const uint8 BOARD_ROWS = 6;
-private const uint8 BOARD_ROWS_PLUS_ONE = 7;
-private const uint8 BOARD_SIZE = 7; // as long as that is needed, impossible to have n_rows != n_cols - 1
-
 private class FourInARow : Gtk.Application
 {
     private GLib.Settings settings = new GLib.Settings ("org.gnome.Four-in-a-row");
@@ -362,10 +355,8 @@ private class FourInARow : Gtk.Application
         {
             vstr [0] = vlevel [ai_level];
             playgame_timeout = Timeout.add (COMPUTER_INITIAL_DELAY, () => {
-                    int c = playgame ((string) vstr) - 1;
-                    if (c > BOARD_COLUMNS_MINUS_ONE)
-                        assert_not_reached ();
-                    if (c < 0)
+                    uint8 c = playgame ((string) vstr);
+                    if (c >= BOARD_COLUMNS) // c could be uint8.MAX if board is full
                         return Source.REMOVE;
                     process_move ((uint8) c);
                     playgame_timeout = 0;
@@ -527,11 +518,9 @@ private class FourInARow : Gtk.Application
             {
                 playgame_timeout = Timeout.add (COMPUTER_MOVE_DELAY, () => {
                         vstr [0] = vlevel [ai_level];
-                        int col = playgame ((string) vstr) - 1;
-                        if (col < 0)
+                        uint8 col = playgame ((string) vstr);
+                        if (col >= BOARD_COLUMNS)   // c could be uint8.MAX if the board is full
                             set_gameover (true);
-                        else if (col > BOARD_COLUMNS_MINUS_ONE)
-                            assert_not_reached ();
                         var nm = new NextMove ((uint8) col, this);
                         Timeout.add (SPEED_DROP, nm.exec);
                         playgame_timeout = 0;
@@ -779,9 +768,6 @@ private class FourInARow : Gtk.Application
 
     private inline void on_game_hint ()
     {
-        string s;
-        uint8 c;
-
         if (timeout != 0)
             return;
         if (gameover)
@@ -794,10 +780,9 @@ private class FourInARow : Gtk.Application
         set_status_message (_("I’m Thinking…"));
 
         vstr [0] = vlevel [/* strong */ 3];
-        int _c = playgame ((string) vstr) - 1;
-        if (_c < 0 || _c > BOARD_COLUMNS_MINUS_ONE)
-            assert_not_reached ();
-        c = (uint8) _c;
+        uint8 c = playgame ((string) vstr);
+        if (c >= BOARD_COLUMNS)
+            assert_not_reached ();  // c could be uint8.MAX if the board if full
 
         column_moveto = c;
         while (timeout != 0)
@@ -809,8 +794,7 @@ private class FourInARow : Gtk.Application
         blink_tile (0, c, game_board [0, c], /* blink n times */ 3);
 
         /* Translators: text displayed in the headerbar/actionbar, when a hint is requested; the %d is 
replaced by the number of the suggested column */
-        s = _("Hint: Column %d").printf (c + 1);
-        set_status_message (s);
+        set_status_message (_("Hint: Column %d").printf (c + 1));
 
         if (moves <= 0 || (moves == 1 && is_player_human ()))
             window.allow_undo (false);
diff --git a/src/player.vala b/src/player.vala
index c24ce76..c6e36de 100644
--- a/src/player.vala
+++ b/src/player.vala
@@ -18,6 +18,12 @@
    with GNOME Four-in-a-row.  If not, see <https://www.gnu.org/licenses/>.
 */
 
+private const uint8 BOARD_COLUMNS = 7;
+private const uint8 BOARD_COLUMNS_MINUS_ONE = 6;
+private const uint8 BOARD_ROWS = 6;
+private const uint8 BOARD_ROWS_PLUS_ONE = 7;
+private const uint8 BOARD_SIZE = 7; // as long as that is needed, impossible to have n_rows != n_cols - 1
+
 private enum Player
 {
     NOBODY,
diff --git a/src/test-ai.vala b/src/test-ai.vala
index 68c7f86..3d46265 100644
--- a/src/test-ai.vala
+++ b/src/test-ai.vala
@@ -19,9 +19,9 @@
    with GNOME Four-in-a-row.  If not, see <https://www.gnu.org/licenses/>.
 */
 
-private const int NUMBER_GAMES = 5;
-private const int MAXIMUM_GAMES = 100;
-private const int THRESHOLD_DENOMINATOR = 4;
+private const uint8 NUMBER_GAMES = 5;
+private const uint8 MAXIMUM_GAMES = 100;
+private const uint8 THRESHOLD_DENOMINATOR = 4;
 
 private int main (string[] args)
 {
@@ -47,110 +47,110 @@ private int main (string[] args)
 private static inline void test_horizontal_win ()
 {
     /*In the first statement below, the AI has made moves into the 1st, 2nd and 3rd columns. To win, AI must 
move in the 4th column.*/
-    assert (playgame ("a1727370") == 4);
-    assert (playgame ("a7315651311324420") == 6);
-    assert (playgame ("a232225657223561611133440") == 4);
-    assert (playgame ("a242215322574255543341746677453337710") == 1);
+    assert_true (playgame ("a1727370") == 3);
+    assert_true (playgame ("a7315651311324420") == 5);
+    assert_true (playgame ("a232225657223561611133440") == 3);
+    assert_true (playgame ("a242215322574255543341746677453337710") == 0);
 }
 
 /* Tests if the AI makes moves so as to take up immediate vertical wins.*/
 private static inline void test_vertical_win ()
 {
-    assert (playgame ("a1213140") == 1);
-    assert (playgame ("a14456535526613130") == 1);
-    assert (playgame ("a432334277752576710") == 7);
-    assert (playgame ("a547477454544323321712116260") == 2);
+    assert_true (playgame ("a1213140") == 0);
+    assert_true (playgame ("a14456535526613130") == 0);
+    assert_true (playgame ("a432334277752576710") == 6);
+    assert_true (playgame ("a547477454544323321712116260") == 1);
 }
 
 /* Tests if the AI makes moves so as to take up immediate forward diagonal wins.*/
 private static inline void test_forward_diagonal_win ()
 {
-    assert (playgame ("a54221164712446211622157570") == 7);
-    assert (playgame ("a4256424426621271412117175776343330") == 3);
-    assert (playgame ("a132565522322662666775443351131113540") == 4);
-    assert (playgame ("a4571311334541225544112245262577767733360") == 6);
+    assert_true (playgame ("a54221164712446211622157570") == 6);
+    assert_true (playgame ("a4256424426621271412117175776343330") == 2);
+    assert_true (playgame ("a132565522322662666775443351131113540") == 3);
+    assert_true (playgame ("a4571311334541225544112245262577767733360") == 5);
 }
 
 /* Tests if the AI makes moves so as to take up immediate backward diagonal wins.*/
 private static inline void test_backward_diagonal_win ()
 {
-    assert (playgame ("5422327343142110") == 1);    // TODO no "a"?
-    assert (playgame ("a1415113315143220") == 2);
-    assert (playgame ("a547323452213345110") == 1);
-    assert (playgame ("a4256424426621271412117175776343330") == 3);
+    assert_true (playgame ("5422327343142110") == 0);    // TODO no "a"?
+    assert_true (playgame ("a1415113315143220") == 1);
+    assert_true (playgame ("a547323452213345110") == 0);
+    assert_true (playgame ("a4256424426621271412117175776343330") == 2);
 }
 
 /* Tests if the AI makes moves which prevents HUMAN from taking immediate vertical victories. Consider that 
a HUMAN has 3 balls in the
    first column. The AI's next move should be in the 1st column or else, HUMAN will claim victory on his 
next turn.*/
 private static inline void test_avoid_vertical_loss ()
 {
-    assert (playgame ("a42563117273430") == 3);
-    assert (playgame ("a3642571541322340") == 4);
-    assert (playgame ("a144566264475171137750") == 5);
-    assert (playgame ("a54747745454432332171210") == 1);
+    assert_true (playgame ("a42563117273430") == 2);
+    assert_true (playgame ("a3642571541322340") == 3);
+    assert_true (playgame ("a144566264475171137750") == 4);
+    assert_true (playgame ("a54747745454432332171210") == 0);
 }
 
 /* Tests if the AI makes moves which prevents HUMAN from taking immediate forward diagonal victories*/
 private static inline void test_avoid_forward_diagonal_loss ()
 {
-    assert (playgame ("a34256477331566570") == 7);
-    assert (playgame ("a1445662644751711370") == 7);
-    assert (playgame ("a43442235372115113340") == 4);
-    assert (playgame ("a4143525567766443543125411170") == 7);
+    assert_true (playgame ("a34256477331566570") == 6);
+    assert_true (playgame ("a1445662644751711370") == 6);
+    assert_true (playgame ("a43442235372115113340") == 3);
+    assert_true (playgame ("a4143525567766443543125411170") == 6);
 }
 
 /* Tests if the AI makes moves which prevents HUMAN from taking immediate backward diagonal victories*/
 private static inline void test_avoid_backward_diagonal_loss ()
 {
-    assert (playgame ("a47465234222530") == 3);
-    assert (playgame ("a4344223537211510") == 1);
-    assert (playgame ("a4141311525513520") == 2);
-    assert (playgame ("a1445662644751711377553330") == 3);
+    assert_true (playgame ("a47465234222530") == 2);
+    assert_true (playgame ("a4344223537211510") == 0);
+    assert_true (playgame ("a4141311525513520") == 1);
+    assert_true (playgame ("a1445662644751711377553330") == 2);
 
 }
 
 /* Tests if the AI makes moves which prevents HUMAN from taking immediate horizontal victories*/
 private static inline void test_avoid_horizontal_loss ()
 {
-    assert (playgame ("a445360") == 7);
-    assert (playgame ("a745534131117114777720") == 2);
-    assert (playgame ("a243466431217112323350") == 5);
-    assert (playgame ("a24147356465355111336631615240") == 4);
+    assert_true (playgame ("a445360") == 6);
+    assert_true (playgame ("a745534131117114777720") == 1);
+    assert_true (playgame ("a243466431217112323350") == 4);
+    assert_true (playgame ("a24147356465355111336631615240") == 3);
 }
 
 /* Tests if AI can detect full boards, and thus draw games.*/
 private static inline void test_draw ()
 {
-    assert (playgame ("a1311313113652226667224247766737374455445550") == 0);
-    assert (playgame ("a6121151135432322433425566474425617635677770") == 0);
-    assert (playgame ("a4226111412113275256335534443264375577676670") == 0);
-    assert (playgame ("a4212116575717754775221133434432366655342660") == 0);
+    assert_true (playgame ("a1311313113652226667224247766737374455445550") == uint8.MAX);
+    assert_true (playgame ("a6121151135432322433425566474425617635677770") == uint8.MAX);
+    assert_true (playgame ("a4226111412113275256335534443264375577676670") == uint8.MAX);
+    assert_true (playgame ("a4212116575717754775221133434432366655342660") == uint8.MAX);
 }
 
 /* Tests if AI makes valid moves, i.e., between column 1 and column 7*/
 private static inline void test_random ()
 {
-    int x = playgame ("a443256214350");
-    assert (x >= 1 && x <= 7);
+    uint8 x = playgame ("a443256214350");
+    assert_true (x <= 6);
 
     x = playgame ("a241473564653551113366316150");
-    assert (x >= 1 && x <= 7);
+    assert_true (x <= 6);
 
     x = playgame ("a24357315461711177416622623350");
-    assert (x >= 1 && x <= 7);
+    assert_true (x <= 6);
 
     x = playgame ("a1445662644751711377553333665775446110");
-    assert (x >= 1 && x <= 7);
+    assert_true (x <= 6);
 }
 
 /* Pits two AI's of varying difficulty levels against each other and returns the number of games won by 
easier AI.*/
-private static inline int test_ai_vs_ai (string easier, string harder)
+private static inline uint8 test_ai_vs_ai (string easier, string harder)
 {
-    int easier_wins = 0;
-    int draw = 0;
-    int harder_wins = 0;
+    uint8 easier_wins = 0;
+    uint8 draw = 0;
+    uint8 harder_wins = 0;
 
-    for (int i = 0; i < NUMBER_GAMES; i++)
+    for (uint8 i = 0; i < NUMBER_GAMES; i++)
     {
         StringBuilder e = new StringBuilder ();
         e.append (easier);
@@ -160,40 +160,39 @@ private static inline int test_ai_vs_ai (string easier, string harder)
 
         while (true)
         {
-            int move;
             DecisionTree t = new DecisionTree ();
-            move = t.playandcheck (e.str);
-            if (move == 0)
+            uint8 move = t.playandcheck (e.str);
+            if (move == uint8.MAX)
             {
                 draw++;
                 break;
             }
 
-            if (move == 1000)
+            if (move == 100)
             {
                 easier_wins++;
                 break;
             }
 
-            e.insert (e.str.length - 1, move.to_string ());
-            m.insert (m.str.length - 1, move.to_string ());
+            e.insert (e.str.length - 1, (move + 1).to_string ());
+            m.insert (m.str.length - 1, (move + 1).to_string ());
 
             DecisionTree d = new DecisionTree ();
             move = d.playandcheck (m.str);
 
-            if (move == 0)
+            if (move == uint8.MAX)
             {
                 draw++;
                 break;
             }
 
-            if (move == 1000)
+            if (move == 100)
             {
                 harder_wins++;
                 break;
             }
-            e.insert (e.str.length - 1, move.to_string ());
-            m.insert (m.str.length - 1, move.to_string ());
+            e.insert (e.str.length - 1, (move + 1).to_string ());
+            m.insert (m.str.length - 1, (move + 1).to_string ());
         }
     }
     return easier_wins;
@@ -201,7 +200,7 @@ private static inline int test_ai_vs_ai (string easier, string harder)
 
 /* Repeatedly contest between the two AI until either easier win ratio is less than a threshold
    or maximum numbers of contests have been played.*/
-private static inline void repeat_contests (string easier, string harder, out int games_contested, out int 
easy_wins)
+private static inline void repeat_contests (string easier, string harder, out uint8 games_contested, out 
uint8 easy_wins)
 {
     easy_wins = test_ai_vs_ai (easier, harder);
     games_contested = NUMBER_GAMES;
@@ -215,27 +214,27 @@ private static inline void repeat_contests (string easier, string harder, out in
 
 private static inline void test_easy_vs_medium ()
 {
-    int easy_wins;
-    int games_contested;
+    uint8 easy_wins;
+    uint8 games_contested;
     repeat_contests ("a0", "b0", out games_contested, out easy_wins);
 
-    assert (easy_wins <= games_contested/THRESHOLD_DENOMINATOR);
+    assert_true (easy_wins <= games_contested/THRESHOLD_DENOMINATOR);
 }
 
 private static inline void test_easy_vs_hard ()
 {
-    int easy_wins;
-    int games_contested;
+    uint8 easy_wins;
+    uint8 games_contested;
     repeat_contests ("a0", "c0", out games_contested, out easy_wins);
 
-    assert (easy_wins <= games_contested/THRESHOLD_DENOMINATOR);
+    assert_true (easy_wins <= games_contested/THRESHOLD_DENOMINATOR);
 }
 
 private static inline void test_medium_vs_hard ()
 {
-    int medium_wins;
-    int games_contested;
+    uint8 medium_wins;
+    uint8 games_contested;
     repeat_contests ("b0", "c0", out games_contested, out medium_wins);
 
-    assert (medium_wins <= games_contested/THRESHOLD_DENOMINATOR);
+    assert_true (medium_wins <= games_contested/THRESHOLD_DENOMINATOR);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]