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); }
// 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); }
// 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); }