/// <summary> /// A BoardQualityEvaluator that calculates how "open" the board is. /// </summary> public static float Openness(FastBoard board) { int total = 0; for (int x = 0; x < FastBoard.Width; x++) { for (int y = 0; y < FastBoard.Height; y++) { ulong cardIndex = board.GetCardIndex(x, y); if (cardIndex == 0) { // 2 points for an empty cell. total += 2; } else { ulong leftCardIndex = x > 0 ? board.GetCardIndex(x - 1, y) : 0; ulong rightCardIndex = x < FastBoard.Width - 1 ? board.GetCardIndex(x + 1, y) : 0; ulong upCardIndex = y > 0 ? board.GetCardIndex(x, y - 1) : 0; ulong downCardIndex = y < FastBoard.Height - 1 ? board.GetCardIndex(x, y + 1) : 0; // 1 point for each adjacent card we can merge with. if (leftCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, leftCardIndex)) { total += 1; } if (rightCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, rightCardIndex)) { total += 1; } if (upCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, upCardIndex)) { total += 1; } if (downCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, downCardIndex)) { total += 1; } // -1 point if we're trapped between higher-valued cards, either horizontally or vertically. if ((x == 0 || (leftCardIndex >= 3 && cardIndex < leftCardIndex)) && (x == FastBoard.Width - 1 || (rightCardIndex >= 3 && cardIndex < rightCardIndex))) { total -= 1; } if ((y == 0 || (upCardIndex >= 3 && cardIndex < upCardIndex)) && (y == FastBoard.Height - 1 || (downCardIndex >= 3 && cardIndex < downCardIndex))) { total -= 1; } // 1 point if next to at least one card twice our value. if (cardIndex >= 3) { if ((leftCardIndex != 0 && leftCardIndex == cardIndex + 1) || (rightCardIndex != 0 && rightCardIndex == cardIndex + 1) || (upCardIndex != 0 && upCardIndex == cardIndex + 1) || (downCardIndex != 0 && downCardIndex == cardIndex + 1)) { total += 1; } } } } } return(total); }
/// <summary> /// A BoardQualityEvaluator that calculates how "open" the board is. /// </summary> public static float OpennessMatthew(FastBoard board) { var maxIndex = board.GetMaxCardIndex(); int total = 0; for (int x = 0; x < FastBoard.Width; x++) { for (int y = 0; y < FastBoard.Height; y++) { ulong cardIndex = board.GetCardIndex(x, y); if (cardIndex == 0) { // 2 points for an empty cell. total += 3; } else { ulong leftCardIndex = x > 0 ? board.GetCardIndex(x - 1, y) : 0; ulong rightCardIndex = x < FastBoard.Width - 1 ? board.GetCardIndex(x + 1, y) : 0; ulong upCardIndex = y > 0 ? board.GetCardIndex(x, y - 1) : 0; ulong downCardIndex = y < FastBoard.Height - 1 ? board.GetCardIndex(x, y + 1) : 0; // for each adjacent card we can merge with. if (leftCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, leftCardIndex)) { total += 2; } if (rightCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, rightCardIndex)) { total += 2; } if (upCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, upCardIndex)) { total += 2; } if (downCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, downCardIndex)) { total += 2; } // negative if we're trapped between higher-valued cards, either horizontally or vertically. if ((x == 0 || (leftCardIndex >= 3 && cardIndex < leftCardIndex)) && (x == FastBoard.Width - 1 || (rightCardIndex >= 3 && cardIndex < rightCardIndex))) { total -= 5; } if ((y == 0 || (upCardIndex >= 3 && cardIndex < upCardIndex)) && (y == FastBoard.Height - 1 || (downCardIndex >= 3 && cardIndex < downCardIndex))) { total -= 5; } // point if next to at least one card twice our value. if (cardIndex >= 3) { if ((leftCardIndex != 0 && leftCardIndex == cardIndex + 1) || (rightCardIndex != 0 && rightCardIndex == cardIndex + 1) || (upCardIndex != 0 && upCardIndex == cardIndex + 1) || (downCardIndex != 0 && downCardIndex == cardIndex + 1)) { total += 2; } } if (maxIndex > 4) { // for each wall we're touching if we're the biggest card if (cardIndex == maxIndex) { if (x == 0 || x == 3) { total += 3; } if (y == 0 || y == 3) { total += 3; } } // for sticking next to the biggest piece if (cardIndex == maxIndex - 1) { int testX, testY; if (NeighborsWith(board, x, y, maxIndex, out testX, out testY)) { total += 1; // and a bonus if we're also along a wall if (x == 0 || x == 3) { total += 1; } if (y == 0 || y == 3) { total += 1; } } } // if we're two below if (cardIndex == maxIndex - 2) { // and we're neighbors with a 1-below int testX, testY; if (NeighborsWith(board, x, y, maxIndex - 1, out testX, out testY)) { // who is also neighbors with the max if (NeighborsWith(board, testX, testY, maxIndex, out testX, out testY)) { total += 1; } } } } } } } return(total); }