Beispiel #1
0
        private static List <successor> NewSuccessors(successor s)
        {
            List <successor> list = new List <successor>();

            LoadToStatus(s.board_status);
            Resource.current_player = s.player;
            GamePlay.UpdateAvailableBoxes();
            bool not_available = true;

            for (int i = 0; i < Constant.SIZE; i++)
            {
                for (int j = 0; j < Constant.SIZE; j++)
                {
                    if (Resource.available[i, j])
                    {
                        not_available = false;
                        successor new_successsor = new successor();
                        int[,] backup_board = SaveStatus();
                        // put disk
                        Resource.status[i, j] = Resource.current_player;
                        // convert disk
                        GamePlay.Reverse(i, j);
                        // assign new successor
                        new_successsor.player       = GamePlay.EnemyOf(s.player);
                        new_successsor.board_status = SaveStatus();
                        new_successsor.eval         = 0;
                        new_successsor.evaluated    = false;
                        list.Add(new_successsor);
                        // turn back status
                        LoadToStatus(backup_board);
                    }
                }
            }
            if (not_available)
            {
                successor new_successsor = new successor();
                new_successsor.player       = GamePlay.EnemyOf(s.player);
                new_successsor.board_status = SaveStatus();
                new_successsor.eval         = 0;
                new_successsor.evaluated    = false;
                list.Add(new_successsor);
            }
            return(list);
        }
Beispiel #2
0
        private static successor Opponent(successor node, int depth, double alpha, double beta)
        {
            successor        best_path = new successor();
            List <successor> list      = NewSuccessors(node);

            if (depth == Constant.DEPTH || list.Count == 0)
            {
                node.eval      = Evaluate(node);
                node.evaluated = true;
                best_path      = node;
            }
            else
            {
                foreach (successor s in list)
                {
                    successor result = Player(s, depth + 1, alpha, beta);

                    if (!node.evaluated)
                    {
                        beta           = result.eval;
                        best_path      = s;
                        node.evaluated = true;
                    }
                    else
                    {
                        double new_value = result.eval;
                        if (new_value < beta)
                        {
                            beta      = new_value;
                            best_path = s;
                        }
                    }
                    if (beta <= alpha)
                    {
                        break;
                    }
                }
                best_path.eval      = beta;
                best_path.evaluated = true;
            }
            return(best_path);
        }
Beispiel #3
0
        public static void MinimaxAlgo()
        {
            successor first_node = new successor();

            first_node.board_status = SaveStatus();
            first_node.player       = Resource.player.ai;
            first_node.eval         = 0;
            first_node.evaluated    = false;
            successor result;

            if (!Resource.ab_pruning)
            {
                result = Player(first_node, 0);
            }
            else
            {
                result = Player(first_node, 0, double.NegativeInfinity, double.PositiveInfinity);
            }
            LoadToStatus(result.board_status);
            Resource.current_player = Resource.player.ai;
        }
Beispiel #4
0
        private static successor Opponent(successor node, int depth)
        {
            successor        best_path = new successor();
            List <successor> list      = NewSuccessors(node);

            if (depth == Constant.DEPTH || list.Count == 0)
            {
                node.eval      = Evaluate(node);
                node.evaluated = true;
                best_path      = node;
            }
            else
            {
                double min_score = double.PositiveInfinity;
                foreach (successor s in list)
                {
                    successor result = Player(s, depth + 1);

                    if (!node.evaluated)
                    {
                        min_score      = result.eval;
                        best_path      = s;
                        node.evaluated = true;
                    }
                    else
                    {
                        double new_value = result.eval;
                        if (new_value < min_score)
                        {
                            min_score = new_value;
                            best_path = s;
                        }
                    }
                }
                best_path.eval      = min_score;
                best_path.evaluated = true;
            }
            return(best_path);
        }
Beispiel #5
0
        private static double Evaluate(successor s)
        {
            // rel_i & rel_j are used to check boxes neighboring to a specific box
            int[] rel_i = { -1, -1, 0, 1, 1, 1, 0, -1 };
            int[] rel_j = { 0, 1, 1, 1, 0, -1, -1, -1 };
            // FACTOR 1: different of the number of disks
            int    player_cnt = 0;
            int    enemy_cnt  = 0;
            double p;

            // FACTOR 2: adv_point is a matrix of point which show the advantage of the position
            int[,] adv_point = { { 20, -3, 11,  8,  8, 11, -3, 20 },
                                 { -3, -7, -4,  1,  1, -4, -7, -3 },
                                 { 11, -4,  2,  2,  2,  2, -4, 11 },
                                 {  8,  1,  2, -3, -3,  2,  1,  8 },
                                 {  8,  1,  2, -3, -3,  2,  1,  8 },
                                 { 11, -4,  2,  2,  2,  2, -4, 11 },
                                 { -3, -7, -4,  1,  1, -4, -7, -3 },
                                 { 20, -3, 11,  8,  8, 11, -3, 20 } };
            double d = 0;
            // FACTOR 3: number of empty neighboring box is included in evaluation
            int    player_empty_boxes = 0;
            int    enemy_empty_boxes  = 0;
            double f = 0;

            for (int i = 0; i < Constant.SIZE; i++)
            {
                for (int j = 0; j < Constant.SIZE; j++)
                {
                    if (s.board_status[i, j] == s.player)
                    {
                        d += adv_point[i, j];
                        player_cnt++;
                    }
                    else if (s.board_status[i, j] == GamePlay.EnemyOf(s.player))
                    {
                        d -= adv_point[i, j];
                        enemy_cnt++;
                    }
                    if (s.board_status[i, j] != (int)Constant.STATUS.BLANK)
                    {
                        for (int k = 0; k < 8; k++)
                        {
                            int x = i + rel_i[k];
                            int y = j + rel_j[k];
                            if (x >= 0 && x < Constant.SIZE &&
                                y >= 0 && y < Constant.SIZE &&
                                s.board_status[x, y] == (int)Constant.STATUS.BLANK)
                            {
                                if (s.board_status[i, j] == s.player)
                                {
                                    player_empty_boxes++;
                                }
                                else
                                {
                                    enemy_empty_boxes++;
                                }
                                break;
                            }
                        }
                    }
                }
            }
            if (player_cnt > enemy_cnt)
            {
                p = (100.0 * player_cnt) / (player_cnt + enemy_cnt);
            }
            else if (player_cnt < enemy_cnt)
            {
                p = -(100.0 * enemy_cnt) / (player_cnt + enemy_cnt);
            }
            else
            {
                p = 0;
            }

            if (player_empty_boxes > enemy_empty_boxes)
            {
                f = -(100.0 * player_empty_boxes) / (player_empty_boxes + enemy_empty_boxes);
            }
            else if (player_empty_boxes < enemy_empty_boxes)
            {
                f = (100.0 * enemy_empty_boxes) / (player_empty_boxes + enemy_empty_boxes);
            }
            else
            {
                f = 0;
            }

            // FACTOR 4: Corner occupancy
            player_cnt = 0;
            enemy_cnt  = 0;
            double c;

            if (s.board_status[0, 0] == s.player)
            {
                player_cnt++;
            }
            else if (s.board_status[0, 0] == GamePlay.EnemyOf(s.player))
            {
                enemy_cnt++;
            }
            if (s.board_status[0, 7] == s.player)
            {
                player_cnt++;
            }
            else if (s.board_status[0, 7] == GamePlay.EnemyOf(s.player))
            {
                enemy_cnt++;
            }
            if (s.board_status[7, 0] == s.player)
            {
                player_cnt++;
            }
            else if (s.board_status[7, 0] == GamePlay.EnemyOf(s.player))
            {
                enemy_cnt++;
            }
            if (s.board_status[7, 7] == s.player)
            {
                player_cnt++;
            }
            else if (s.board_status[7, 7] == GamePlay.EnemyOf(s.player))
            {
                enemy_cnt++;
            }
            c = 25 * (player_cnt - enemy_cnt);

            // FACTOR 5: Corner closeness
            player_cnt = 0;
            enemy_cnt  = 0;
            double l;

            if (s.board_status[0, 0] == (int)Constant.STATUS.BLANK)
            {
                if (s.board_status[0, 1] == s.player)
                {
                    player_cnt++;
                }
                else if (s.board_status[0, 1] == GamePlay.EnemyOf(s.player))
                {
                    enemy_cnt++;
                }
                if (s.board_status[1, 1] == s.player)
                {
                    player_cnt++;
                }
                else if (s.board_status[1, 1] == GamePlay.EnemyOf(s.player))
                {
                    enemy_cnt++;
                }
                if (s.board_status[1, 0] == s.player)
                {
                    player_cnt++;
                }
                else if (s.board_status[1, 0] == GamePlay.EnemyOf(s.player))
                {
                    enemy_cnt++;
                }
            }
            if (s.board_status[0, 7] == (int)Constant.STATUS.BLANK)
            {
                if (s.board_status[0, 6] == s.player)
                {
                    player_cnt++;
                }
                else if (s.board_status[0, 6] == GamePlay.EnemyOf(s.player))
                {
                    enemy_cnt++;
                }
                if (s.board_status[1, 6] == s.player)
                {
                    player_cnt++;
                }
                else if (s.board_status[1, 6] == GamePlay.EnemyOf(s.player))
                {
                    enemy_cnt++;
                }
                if (s.board_status[1, 7] == s.player)
                {
                    player_cnt++;
                }
                else if (s.board_status[1, 7] == GamePlay.EnemyOf(s.player))
                {
                    enemy_cnt++;
                }
            }
            if (s.board_status[7, 0] == (int)Constant.STATUS.BLANK)
            {
                if (s.board_status[7, 1] == s.player)
                {
                    player_cnt++;
                }
                else if (s.board_status[7, 1] == GamePlay.EnemyOf(s.player))
                {
                    enemy_cnt++;
                }
                if (s.board_status[6, 1] == s.player)
                {
                    player_cnt++;
                }
                else if (s.board_status[6, 1] == GamePlay.EnemyOf(s.player))
                {
                    enemy_cnt++;
                }
                if (s.board_status[6, 0] == s.player)
                {
                    player_cnt++;
                }
                else if (s.board_status[6, 0] == GamePlay.EnemyOf(s.player))
                {
                    enemy_cnt++;
                }
            }
            if (s.board_status[7, 7] == (int)Constant.STATUS.BLANK)
            {
                if (s.board_status[6, 7] == s.player)
                {
                    player_cnt++;
                }
                else if (s.board_status[6, 7] == GamePlay.EnemyOf(s.player))
                {
                    enemy_cnt++;
                }
                if (s.board_status[6, 6] == s.player)
                {
                    player_cnt++;
                }
                else if (s.board_status[6, 6] == GamePlay.EnemyOf(s.player))
                {
                    enemy_cnt++;
                }
                if (s.board_status[7, 6] == s.player)
                {
                    player_cnt++;
                }
                else if (s.board_status[7, 6] == GamePlay.EnemyOf(s.player))
                {
                    enemy_cnt++;
                }
            }
            l = -12.5 * (player_cnt - enemy_cnt);

            // FACTOR 6: Mobility, number of available boxes
            player_cnt = 0;
            enemy_cnt  = 0;
            double m = 0;

            LoadToStatus(s.board_status);
            Resource.current_player = s.player;
            GamePlay.UpdateAvailableBoxes();
            player_cnt = GamePlay.CountAvailableBoxes();
            Resource.current_player = GamePlay.EnemyOf(s.player);
            GamePlay.UpdateAvailableBoxes();
            enemy_cnt = GamePlay.CountAvailableBoxes();
            if (player_cnt > enemy_cnt)
            {
                m = (100.0 * player_cnt) / (player_cnt + enemy_cnt);
            }
            else if (player_cnt < enemy_cnt)
            {
                m = -(100.0 * enemy_cnt) / (player_cnt + enemy_cnt);
            }
            else
            {
                m = 0;
            }

            // Final weighted score
            double score = (10 * p) + (801.724 * c) + (382.026 * l) + (78.922 * m) + (74.396 * f) + (10 * d);

            return(score);
        }