예제 #1
0
        private float Heuristic(Board board, PColor color)
        {
            // Distance between two points
            float Dist(float x1, float y1, float x2, float y2)
            {
                return((float)Math.Sqrt(
                           Math.Pow(x1 - x2, 2) + Math.Pow(y1 - y2, 2)));
            }

            // Determine the center row
            float centerRow = board.rows / 2;
            float centerCol = board.cols / 2;

            // Maximum points a piece can be awarded when it's at the center
            float maxPoints = Dist(centerRow, centerCol, 0, 0);

            // Current heuristic value
            float h = 0;

            // Loop through the board looking for pieces
            for (int i = 0; i < board.rows; i++)
            {
                for (int j = 0; j < board.cols; j++)
                {
                    // Get piece in current board position
                    Piece?piece = board[i, j];

                    // Is there any piece there?
                    if (piece.HasValue)
                    {
                        // If the piece is of our color, increment the
                        // heuristic inversely to the distance from the center
                        if (piece.Value.color == color)
                        {
                            h += maxPoints - Dist(centerRow, centerCol, i, j);
                        }
                        // Otherwise decrement the heuristic value using the
                        // same criteria
                        else
                        {
                            h -= maxPoints - Dist(centerRow, centerCol, i, j);
                        }
                        // If the piece is of our shape, increment the
                        // heuristic inversely to the distance from the center
                        if (piece.Value.shape == color.Shape())
                        {
                            h += maxPoints - Dist(centerRow, centerCol, i, j);
                        }
                        // Otherwise decrement the heuristic value using the
                        // same criteria
                        else
                        {
                            h -= maxPoints - Dist(centerRow, centerCol, i, j);
                        }
                    }
                }
            }
            // Return the final heuristic score for the given board
            return(h);
        }
    // Heuristic function
    public float Heuristic(Board board, PColor color)
    {
        // Distance between two points
        float Dist(float x1, float y1, float x2, float y2)
        {
            return((float)Math.Sqrt(
                       Math.Pow(x1 - x2, 2) + Math.Pow(y1 - y2, 2)));
        }

        // Determine the center row
        float centerRow = board.rows / 2;
        float centerCol = board.cols / 2;

        // Maximum points a piece can be awarded when it's at the center
        float maxPoints = Dist(centerRow, centerCol, 0, 0); // 4.61f

        // Current heuristic value
        float h = 0;

        // Loop through the board looking for pieces
        for (int i = 0; i < board.rows; i++)
        {
            for (int j = 0; j < board.cols; j++)
            {
                // Get piece in current board position
                Piece?piece = board[i, j];

                if (!piece.HasValue)
                {
                    continue;
                }

                // Is there any piece there?
                if (piece.HasValue)
                {
                    // // If the piece is of our shape, increment the
                    // // heuristic inversely to the distance from the center
                    if (piece.Value.shape == color.Shape())
                    {
                        h += maxPoints - Dist(centerRow, centerCol, i, j);
                    }
                    else
                    {
                        h -= maxPoints - Dist(centerRow, centerCol, i, j);
                    }

                    if (color.FriendOf(piece.Value))
                    {
                        h += maxPoints - Dist(centerRow, centerCol, i, j);
                    }
                    else
                    {
                        h -= maxPoints - Dist(centerRow, centerCol, i, j);
                    }

                    if (board.piecesInSequence == 3 &&
                        color.FriendOf(piece.Value))
                    {
                        h += maxPoints - Dist(centerRow, centerCol, i, j);
                    }
                    else
                    {
                        h -= maxPoints - Dist(centerRow, centerCol, i, j);
                    }

                    if (i > 0 && j > 0)
                    {
                        // Check if piece bellow
                        if (board[i - 1, j].HasValue && i <= 6)
                        {
                            if (!board[i - 1, j].Value.Is(color, color.Shape()))
                            {
                                h -= maxPoints - Dist(
                                    centerRow, centerCol, i, j);
                            }
                        }

                        // Check piece in collum before
                        if (board[i, j - 1].HasValue && j <= 7)
                        {
                            if (!board[i, j - 1].Value.Is(color, color.Shape()))
                            {
                                h -= maxPoints - Dist(
                                    centerRow, centerCol, i, j);
                            }
                        }

                        // Check piece in collum after
                        if (board[i, j + 1].HasValue && j <= 7)
                        {
                            if (!board[i, j + 1].Value.Is(color, color.Shape()))
                            {
                                h -= maxPoints - Dist(
                                    centerRow, centerCol, i, j);
                            }
                        }
                    }
                }
            }
        }
        // Return the final heuristic score for the given board
        return(h);
    }
예제 #3
0
        // Heuristic that iterates win corridors and changes its score
        // based on the pieces in each of those corridors.
        // Aditionally, this version also gives extra value to absolute sequences
        // (sequences of pieces with same color and shape).
        private float Heuristic(Board board, PColor turn)
        {
            // Heuristic score.
            float score = 0;

            // Iterate every win corridor in the board.
            foreach (IEnumerable <Pos> corridor in board.winCorridors)
            {
                // Stores sequence of pieces found.
                float sequence = 0, range = 0;

                // Iterate every position in the corridor.
                foreach (Pos pos in corridor)
                {
                    // Try to get piece in current board position.
                    Piece?piece = board[pos.row, pos.col];

                    range += 1;

                    // Check if there is a piece.
                    if (piece.HasValue)
                    {
                        // Has same shape and color as player.
                        if (piece.Value.shape == turn.Shape() &&
                            piece.Value.color == turn)
                        {
                            // Add 2 points.
                            score += 2;

                            sequence += 1;
                        }

                        // Has same shape but different color as player.
                        else if (piece.Value.shape == turn.Shape() &&
                                 piece.Value.color != turn)
                        {
                            // Add 1 point.
                            score += 1;
                        }

                        // Has different shape but same color as player.
                        else if (piece.Value.shape != turn.Shape() &&
                                 piece.Value.color == turn)
                        {
                            // Remove 1 point.
                            score -= 1;
                        }

                        // Has different shape and color as player.
                        else if (piece.Value.shape != turn.Shape() &&
                                 piece.Value.color != turn)
                        {
                            // Remove 2 points.
                            score -= 2;

                            if (range < WinSequence)
                            {
                                sequence = 0;
                            }

                            range = 0;
                        }
                    }

                    if (range == WinSequence)
                    {
                        if (sequence == WinSequence)
                        {
                            score += 50;
                        }

                        if (sequence == (WinSequence - 1))
                        {
                            score += 10;
                        }

                        if (sequence == (WinSequence - 2))
                        {
                            score += 5;
                        }
                    }
                }
            }

            // Return the final heuristic score.
            return(score);
        }
예제 #4
0
        // Heuristic function
        /// <summary>
        /// Heuristic for the Bee AI agent
        /// </summary>
        /// <param name="board"> Current game Board</param>
        /// <param name="color"> Color to do the heuristic for</param>
        /// <returns> Heuristic value of the board</returns>
        public static float Honeycomb(Board board, PColor color)
        {
            // Max points the ai can hold
            float h = START_VALUE;
            bool  enemyCheckFound = false;
            Board boardCop        = board.Copy();
            int   lasCol          = boardCop.UndoMove().col;

            // Run through every win corridor
            foreach (IEnumerable <Pos> line in board.winCorridors)
            {
                float Dist(float x1, float y1, float x2, float y2)
                {
                    return((float)Math.Sqrt(
                               Math.Pow(x1 - x2, 2) + Math.Pow(y1 - y2, 2)));
                }

                // Set defaults
                int  allyPiecesInLine  = 0;
                int  enemyPiecesInLine = 0;
                bool canUseLine        = true;
                bool enemyCanUseLine   = true;
                // Distance between two points

                // Determine the center row
                float centerRow = board.rows / 2;
                float centerCol = board.cols / 2;

                // Maximum points a piece can be awarded when it's at the center
                float maxPoints = Dist(centerRow, centerCol, 0, 0);

                // Check every position on the win corridor
                foreach (Pos pos in line)
                {
                    // If there is no piece there
                    if (!board[pos.row, pos.col].HasValue)
                    {
                        continue;
                    }

                    Piece p = board[pos.row, pos.col].Value;

                    // Check if the piece is friendly towards the given piece
                    if (color.FriendOf(p))
                    {
                        // Is the color different
                        if (color != p.color)
                        {
                            h -= AMOUNT_COLOR;
                        }
                        // Is the shape different
                        if (color.Shape() != p.shape)
                        {
                            h -= AMOUNT_SHAPE;
                        }

                        // The line is not corrupted
                        if (canUseLine)
                        {
                            allyPiecesInLine++;
                        }

                        h += Dist(centerRow, centerCol, pos.row, pos.col);

                        enemyCanUseLine = false;
                    }
                    // The line is unusable
                    else
                    {
                        canUseLine = false;
                        h         -= AMOUNT_PIECE;

                        if (enemyCanUseLine)
                        {
                            enemyPiecesInLine++;
                        }

                        h -= Dist(centerRow, centerCol, pos.row, pos.col) / 2;
                    }
                }

                // Do we have a winning sequence?
                if (allyPiecesInLine == board.piecesInSequence - 1)
                {
                    return(WIN_VALUE);
                }
                // Does the enemy have a winning sequence?
                if (enemyPiecesInLine == board.piecesInSequence - 1)
                {
                    enemyCheckFound = true;
                }

                // Ome final uneven point
                h -= enemyPiecesInLine - allyPiecesInLine;
            }

            // Can the enemy win next turn
            return(enemyCheckFound ? float.NegativeInfinity : h);
        }