[four-in-a-row] AI: code style fixes



commit f873f49f323a24e8f2b943c6634f32389068b856
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date:   Sun Oct 5 01:37:31 2014 +0200

    AI: code style fixes
    
    https://bugzilla.gnome.org/show_bug.cgi?id=737908

 src/ai.vala |  325 ++++++++++++++++++++++-------------------------------------
 1 files changed, 119 insertions(+), 206 deletions(-)
---
diff --git a/src/ai.vala b/src/ai.vala
index a02337b..5c2dc5e 100644
--- a/src/ai.vala
+++ b/src/ai.vala
@@ -15,10 +15,10 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with Four-in-a-row.  If not, see <http://www.gnu.org/licenses/>.*/
+ * along with Four-in-a-row.  If not, see <http://www.gnu.org/licenses/>. */
 
 
-/*Here NEG_INF is supposed to be the lowest possible int value. int.MIN
+/* Here NEG_INF is supposed to be the lowest possible int value. int.MIN
 MAX_HEURIST_VALUE is the maximum value that the heuristic functions can return.
 It is returned when AI wins. -1*MAX_HEURIST_VALUE is returned when Human wins
 MAX_HEURIST_VALUE < NEG_INF/plies */
@@ -31,93 +31,81 @@ enum Difficulty {EASY, MEDIUM, HARD;}
 
 int playgame (string moves_until_now)
 {
-       var t = new DecisionTree();
+       var t = new DecisionTree ();
        return t.playgame (moves_until_now);
 }
 
 public class DecisionTree
 {
-       /* to mantain the status of the board, to be used by the heuristic function, the top left cell is 0,0 
*/
+       /* 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*/
+       /* plies - depth of the DecisionTree */
        private int plies = 8;
-       /* last_moving_player - The player who made the last move, set to Player.NONE if no one has made a 
move yet*/
+       /* last_moving_player - The player who made the last move, set to Player.NONE if no one has made a 
move yet */
        private Player last_moving_player = Player.NONE;
-       /* next_move_in_column - stores the column number in which next move is to be made*/
+       /* next_move_in_column - stores the column number in which next move is to be made */
        private int next_move_in_column = -1;
-       /* stores the difficulty level of the game*/
+       /* stores the difficulty level of the game */
        private Difficulty level;
 
-       /* Initializes an empty board*/
+       /* Initializes an empty board */
        public DecisionTree ()
        {
-               for (int i=0; i < BOARD_ROWS; i++)
-               {
-                       for (int j=0; j < BOARD_COLUMNS; j++)
-                       {
-                               board[i,j] = Player.NONE;
-                       }
-               }
+               for (int i = 0; i < BOARD_ROWS; i++)
+                       for (int j = 0; j < BOARD_COLUMNS; j++)
+                               board [i, j] = Player.NONE;
        }
 
-       /* utility function for debugging purposes, prints a snapshot of current status of the board*/
+       /* utility function for debugging purposes, prints a snapshot of current status of the board */
        public void print_board ()
        {
-               for (int i=0; i< BOARD_ROWS; i++)
+               for (int i = 0; i< BOARD_ROWS; i++)
                {
                        for (int j = 0; j < BOARD_COLUMNS; j++)
-                       {
-                               stdout.printf("%d\t",board[i,j]);
-                       }
-                       stdout.printf("\n");
+                               stdout.printf ("%d\t", board [i, j]);
+                       stdout.printf ("\n");
                }
-               stdout.printf("\n");
+               stdout.printf ("\n");
        }
 
        /* 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.*/
+          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)
        {
-
-               /* 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())
+               /* 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 ())
                {
                        if (last_moving_player == Player.HUMAN)
-                               return heurist();
+                               return heurist ();
                        else if (last_moving_player == Player.AI)
-                               return -1 * heurist();
+                               return -1 * heurist ();
                        else
                                return 0;
                }
 
                /* Local variable that stores the maximum value returned by the node's children so far.
-                None of the children have returned anything so far. Hence, it is initialized with NEG_INF*/
+                  None of the children have returned anything so far. Hence, it is initialized with NEG_INF. 
*/
                int max = NEG_INF;
 
                /* 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.*/
+                  Initialized with -1 because we do not know the column number yet. */
                int next = -1;
 
-               for (int i=0; i < BOARD_COLUMNS; i++)
+               for (int i = 0; i < BOARD_COLUMNS; i++)
                {
-                       /* make a move into the i'th column*/
-                       if (move(i))
+                       /* make a move into the i'th column */
+                       if (move (i))
                        {
-                               int temp;
-
-                               /* victory() checks if making a move in the i'th column results in a victory 
for someone. */
-                               /* Multiply by a height factor to avoid closer threats first */
-                               if (last_moving_player == Player.HUMAN)
-                                       temp = -1 * victory(i) * height;
-                               else
-                                       temp = victory(i) * height;
+                               /* victory() checks if making a move in the i'th column results in a victory 
for someone.
+                                  Multiply by a height factor to avoid closer threats first. */
+                               var temp = victory (i) * height * (last_moving_player == Player.HUMAN ? -1 : 
1);
 
-                               /* if making a move in this column resulted in a victory for someone, 
temp!=0, we do not need to go
-                                  further down the negamax tree*/
+                               /* if making a move in this column resulted in a victory for someone, temp != 
0, we do not need to go
+                                  further down the negamax tree */
                                if (temp == 0)
-                                       temp = -1 * negamax(height - 1, -1 * beta, -1 * alpha);
+                                       temp = -1 * negamax (height - 1, -1 * beta, -1 * alpha);
 
-                               unmove(i);
+                               unmove (i);
 
                                if (temp > max)
                                {
@@ -125,18 +113,11 @@ public class DecisionTree
                                        max = temp;
                                }
 
-
                                if (temp > alpha)
-                               {
                                        alpha = temp;
-                               }
-
 
                                if (alpha >= beta)
-                               {
                                        break;
-                               }
-
                        }
                }
 
@@ -144,7 +125,6 @@ public class DecisionTree
                if (height == plies)
                        next_move_in_column = next;
 
-
                return max;
        }
 
@@ -154,23 +134,22 @@ public class DecisionTree
        {
                int cell;
 
-               /* board[cell,i] would now be the cell on which the last move was made */
-               for (cell = 0; cell < BOARD_ROWS && board[cell,i] == Player.NONE; cell++);
+               /* board [cell, i] would now be the cell on which the last move was made */
+               for (cell = 0; cell < BOARD_ROWS && board [cell, i] == Player.NONE; cell++);
 
                int temp = 0;
 
-               temp = vertical_win(cell,i);
+               temp = vertical_win (cell, i);
                if (temp != 0) return temp;
 
-               temp = horizontal_win(cell,i);
+               temp = horizontal_win (cell, i);
                if (temp != 0) return temp;
 
-               temp = backward_diagonal_win(cell,i);
+               temp = backward_diagonal_win (cell, i);
                if (temp != 0) return temp;
 
-               temp = forward_diagonal_win(cell,i);
+               temp = forward_diagonal_win (cell, i);
                return temp;
-
        }
 
        /* all the win functions that follow return 0 is no one wins, MAX_HEURIST_VALUE if AI wins, -1 * 
MAX_HEURIST_VALUE if human wins */
@@ -178,16 +157,11 @@ public class DecisionTree
        {
                int 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 (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++);
 
                if (count >= 4)
-               {
-                       if (last_moving_player == Player.HUMAN)
-                               return -1 * MAX_HEURIST_VALUE;
-                       else
-                               return MAX_HEURIST_VALUE;
-               }
+                       return MAX_HEURIST_VALUE * (last_moving_player == Player.HUMAN ? -1 : 1);
 
                return 0;
        }
@@ -196,16 +170,11 @@ public class DecisionTree
        {
                int count = 0;
 
-               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++);
+               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++);
 
                if (count >= 4)
-               {
-                       if (last_moving_player == Player.HUMAN)
-                               return -1 * MAX_HEURIST_VALUE;
-                       else
-                               return MAX_HEURIST_VALUE;
-               }
+                       return MAX_HEURIST_VALUE * (last_moving_player == Player.HUMAN ? -1 : 1);
 
                return 0;
        }
@@ -214,16 +183,11 @@ public class DecisionTree
        {
                int count = 0;
 
-               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++);
+               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++);
 
                if (count >= 4)
-               {
-                       if (last_moving_player == Player.HUMAN)
-                               return -1 * MAX_HEURIST_VALUE;
-                       else
-                               return MAX_HEURIST_VALUE;
-               }
+                       return MAX_HEURIST_VALUE * (last_moving_player == Player.HUMAN ? -1 : 1);
 
                return 0;
        }
@@ -232,138 +196,114 @@ public class DecisionTree
        {
                int count = 0;
 
-               for (int k = i; k < BOARD_ROWS && board[k,j] == last_moving_player; k++ , count++);
+               for (int k = i; k < BOARD_ROWS && board [k, j] == last_moving_player; k++, count++);
 
                if (count >= 4)
-               {
-                       if (last_moving_player == Player.HUMAN)
-                               return -1 * MAX_HEURIST_VALUE;
-                       else
-                               return MAX_HEURIST_VALUE;
-               }
+                       return MAX_HEURIST_VALUE * (last_moving_player == Player.HUMAN ? -1 : 1);
 
                return 0;
        }
 
-       /*returns true if the board is full, false if not*/
+       /* returns true if the board is full, false if not */
        private bool board_full ()
        {
-               bool empty = false;
                for (int i = 0 ; i < BOARD_COLUMNS ; i++)
-               {
-                       if (board[0,i] == Player.NONE)
-                       {
-                               empty = true;
-                               break;
-                       }
-               }
-               return !empty;
+                       if (board [0, i] == Player.NONE)
+                               return false;
+               return true;
        }
 
-       /* makes a move into the i'th column. Returns true if the move was succesful, false if it wasn't*/
+       /* makes a move into the i'th column. Returns true if the move was succesful, false if it wasn't */
        private bool move (int i)
        {
                int cell;
 
-               for(cell = BOARD_ROWS - 1; cell >= 0 && board[cell,i] != Player.NONE; cell -= 1);
+               for (cell = BOARD_ROWS - 1; cell >= 0 && board [cell, i] != Player.NONE; cell--);
 
-               if(cell < 0)
+               if (cell < 0)
                        return false;
 
-               /*if it is AI's first move or the last move was made by human */
+               /* if it is AI's first move or the last move was made by human */
                if (last_moving_player == Player.NONE || last_moving_player == Player.HUMAN)
                {
-                       board[cell,i] = Player.AI;
+                       board [cell, i] = Player.AI;
                        last_moving_player = Player.AI;
                }
                else
                {
-                       board[cell,i] = Player.HUMAN;
+                       board [cell, i] = Player.HUMAN;
                        last_moving_player = Player.HUMAN;
                }
 
                return true;
        }
 
-       /* unmove the last move made in the i'th column.*/
+       /* unmove the last move made in the i'th column */
        private void unmove (int i)
        {
                int cell;
 
-               for (cell = BOARD_ROWS - 1; cell >= 0 && board[cell,i] != Player.NONE; cell -= 1);
+               for (cell = BOARD_ROWS - 1; cell >= 0 && board [cell, i] != Player.NONE; cell--);
 
-               board[cell + 1,i] = Player.NONE;
+               board [cell + 1, i] = Player.NONE;
 
                if (last_moving_player == Player.AI)
                        last_moving_player = Player.HUMAN;
                else if (last_moving_player == Player.HUMAN)
                        last_moving_player = Player.AI;
-
        }
 
-       /* vstr is the sequence of moves made until now. We update DecisionTree::board to reflect these 
sequence of moves.*/
+       /* vstr is the sequence of moves made until now. We update DecisionTree::board to reflect these 
sequence of moves. */
        public void update_board (string vstr)
        {
                next_move_in_column = -1;
 
-               /* AI will make the first move, nothing to add to the board*/
+               /* AI will make the first move, nothing to add to the board */
                if (vstr.length == 2) return;
 
-               Player move;
-
-               if (vstr.length % 2 == 0)
-                       move = Player.AI;
-               else
-                       move = Player.HUMAN;
+               var move = vstr.length % 2 == 0 ? Player.AI : Player.HUMAN;
 
                for (int i = 1; i < vstr.length - 1; i++)
                {
-                       int column = int.parse(vstr[i].to_string()) -1;
-
+                       int column = int.parse (vstr [i].to_string ()) - 1;
                        int cell;
 
-                       for (cell = BOARD_ROWS - 1; cell >= 0 && board[cell,column] != Player.NONE; cell -= 
1);
+                       for (cell = BOARD_ROWS - 1; cell >= 0 && board [cell, column] != Player.NONE; cell--);
 
-                       board[cell, column] = move;
+                       board [cell, column] = move;
 
-                       if (move == Player.HUMAN)
-                               move = Player.AI;
-                       else
-                               move = Player.HUMAN;
+                       move = move == Player.HUMAN ? Player.AI : Player.HUMAN;
                }
 
                last_moving_player = Player.HUMAN;
        }
 
-       /* check for immediate win of AI/HUMAN. It checks the current state of the board. Returns -1 if no 
immediate win for Player P.
-        Otherwise returns the column number in which Player P should move to win.*/
+       /* Check for immediate win of AI/HUMAN. It checks the current state of the board. Returns -1 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)
        {
                Player old_last_moving_player = last_moving_player;
 
-               if (p == Player.AI)
-                       last_moving_player = Player.HUMAN;
-               else
-                       last_moving_player = Player.AI;
+               last_moving_player = p == Player.AI ? Player.HUMAN : Player.AI;
 
                for (int i = 0; i < BOARD_COLUMNS; i++)
                {
-                       if (move(i))
-                       {
-                               if (victory(i) != 0)
-                               {
-                                       unmove(i);
-                                       last_moving_player = old_last_moving_player;
-                                       return i;
-                               }
+                       if (!move (i))
+                               continue;
 
-                               unmove(i);
+                       if (victory (i) != 0)
+                       {
+                               unmove (i);
+                               last_moving_player = old_last_moving_player;
+                               return i;
                        }
+
+                       unmove (i);
                }
 
                last_moving_player = old_last_moving_player;
 
-               /* returns -1 if no immediate win for Player p*/
+               /* returns -1 if no immediate win for Player p */
                return -1;
        }
 
@@ -371,75 +311,59 @@ public class DecisionTree
        public int playgame (string vstr)
        {
                /* set the Difficulty level */
-               set_level(vstr);
+               set_level (vstr);
 
-               /* update DecisionTree::board to reflect the moves made until now*/
-               update_board(vstr);
+               /* update DecisionTree::board to reflect the moves made until now */
+               update_board (vstr);
 
-               /* check if AI can win by making a move immediately*/
+               /* 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.AI);
-
-               /* if the AI can win, then make that move. main.c has indexing beginning from 1 instead of 0, 
hence, we add 1.*/
                if (temp != -1)
                        return temp + 1;
 
-               /*check if HUMAN can win by making a move immediately*/
+               /* 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 the HUMAN can win, we make AI move in that column so as avoid loss.*/
                if (temp != -1)
                        return temp + 1;
 
-               /*call negamax tree on the current state of the board.*/
-               negamax(plies,  NEG_INF, -1 * NEG_INF);
+               /* 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 the column number in which next move should be made */
                return next_move_in_column + 1;
-
        }
 
-       /* The evaluation function to be called when we have reached the maximum depth in the DecisionTree*/
+       /* The evaluation function to be called when we have reached the maximum depth in the DecisionTree */
        private int heurist ()
        {
                if (level == Difficulty.EASY)
-                       return heurist_easy();
-
+                       return heurist_easy ();
                else if (level == Difficulty.MEDIUM)
-                       return heurist_medium();
-
+                       return heurist_medium ();
                else
-                       return heurist_hard();
-
+                       return heurist_hard ();
        }
 
        private int heurist_easy ()
        {
-               return -1 * heurist_hard();
+               return -1 * heurist_hard ();
        }
 
        private int heurist_medium ()
        {
-               return Random.int_range(1,49);
+               return Random.int_range (1, 49);
        }
 
        private int heurist_hard ()
        {
-               int count = 0;
-
-               count = count_3_in_a_row(Player.AI);
-
-               count -= count_3_in_a_row(Player.HUMAN);
-
-               count = count*100;
-
-               if (count == 0)
-                       count = Random.int_range(1,49);
-
-               return count;
+               var count = count_3_in_a_row (Player.AI) - count_3_in_a_row (Player.HUMAN);
+               return count == 0 ? Random.int_range (1, 49) : count * 100;
        }
 
        /* Count the number of threes in a row for Player P. It counts all those 3 which have an empty cell 
in the vicinity to make it
-        four in a row*/
+          four in a row. */
        private int count_3_in_a_row (Player p)
        {
                int count = 0;
@@ -452,55 +376,50 @@ public class DecisionTree
                {
                        for (int i = 0; i < BOARD_ROWS; i++)
                        {
-                               if (board[i,j] != Player.NONE)
+                               if (board [i, j] != Player.NONE)
                                        break;
 
-                               if (all_adjacent_empty(i,j))
+                               if (all_adjacent_empty (i, j))
                                        continue;
 
-                               board[i,j] = p;
+                               board [i, j] = p;
 
-                               if (victory(j) != 0)
+                               if (victory (j) != 0)
                                        count++;
 
-                               board[i,j] = Player.NONE;
-
+                               board [i, j] = Player.NONE;
                        }
                }
                last_moving_player = old_last_moving_player;
                return count;
        }
 
-       /* checks if all adjacent cells to board[i,j] are empty*/
+       /* checks if all adjacent cells to board [i, j] are empty */
        private bool all_adjacent_empty (int i, int j)
        {
                for (int k = -1 ; k <= 1; k++)
                {
-                       for (int l = -1; l <=1; l++)
+                       for (int l = -1; l <= 1; l++)
                        {
                                if (k == 0 && l == 0)
                                        continue;
-                               if ((i+k) >= 0 && (i+k) < BOARD_ROWS && (j+l) >= 0 && (j+l) < BOARD_COLUMNS)
-                               {
-                                       if(board[i+k,j+l] != Player.NONE)
-                                               return false;
-                               }
+                               if (i + k >= 0 && i + k < BOARD_ROWS && j + l >= 0 && j + l < BOARD_COLUMNS 
&& board [i + k, j + l] != Player.NONE)
+                                       return false;
                        }
                }
 
                return true;
        }
 
-       /* set the number of plies and the difficulty level*/
+       /* set the number of plies and the difficulty level */
        private void set_level (string vstr)
        {
-
-               if (vstr[0] == 'a')
+               if (vstr [0] == 'a')
                {
                        level = Difficulty.EASY;
                        plies = 4;
                }
-               else if (vstr[0] == 'b')
+               else if (vstr [0] == 'b')
                {
                        level = Difficulty.MEDIUM;
                        plies = 7;
@@ -512,29 +431,23 @@ public class DecisionTree
                }
        }
 
-       /* utility function for testing purposes*/
+       /* utility function for testing purposes */
        public int playandcheck (string vstr)
        {
-               set_level(vstr);
-
-               update_board(vstr);
+               set_level (vstr);
+               update_board (vstr);
 
                int temp = immediate_win (Player.AI);
-
                if (temp != -1)
-               {
                        return 1000;
-               }
 
                temp = immediate_win (Player.HUMAN);
-
                if (temp != -1)
                        return temp + 1;
 
-               negamax(plies,  NEG_INF, -1 * NEG_INF);
+               negamax (plies, NEG_INF, -1 * NEG_INF);
 
                return next_move_in_column + 1;
-
        }
 }
 


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