private KeyValuePair <double, KeyValuePair <int, int> > BestOptionOfSubtreeWithCuts(GameBoard gameBoard, int maxDepth, int currentDepth, double parentBest) { var currentMultiplier = 1.0 / currentDepth; var ownBest = -gameBoard.Turn * (double.MaxValue - 1) * currentMultiplier; var bestSlot = new KeyValuePair <int, int>(); if (gameBoard.EmptySlots.Count != 0) { bestSlot = gameBoard.EmptySlots[0]; } if (gameBoard.IsComplete() || currentDepth == maxDepth) { var evaluation = EvaluateGameBoard(gameBoard) * currentMultiplier; if (gameBoard.Turn * ownBest < gameBoard.Turn * evaluation) { ownBest = evaluation; } } else { foreach (var emptySlot in gameBoard.EmptySlots) { var tempBoard = (GameBoard)gameBoard.Clone(); tempBoard.Step(emptySlot); var evaluation = BestOptionOfSubtreeWithCuts(tempBoard, maxDepth, currentDepth + 1, ownBest); if (gameBoard.Turn * ownBest < gameBoard.Turn * evaluation.Key) { ownBest = evaluation.Key; bestSlot = emptySlot; } if (gameBoard.Turn * ownBest >= gameBoard.Turn * parentBest) { return(new KeyValuePair <double, KeyValuePair <int, int> >(ownBest, bestSlot)); } } } return(new KeyValuePair <double, KeyValuePair <int, int> >(ownBest, bestSlot)); }
private static KeyValuePair <int, KeyValuePair <int, int> > BestOptionOfSubtree(GameBoard gameBoard) { var bestOption = new KeyValuePair <int, KeyValuePair <int, int> >(-2, new KeyValuePair <int, int>()); foreach (var emptySlot in gameBoard.EmptySlots) { var tempBoard = (GameBoard)gameBoard.Clone(); tempBoard.Step(emptySlot); if (tempBoard.IsComplete()) { return(new KeyValuePair <int, KeyValuePair <int, int> >(tempBoard.Winner, emptySlot)); } var option = BestOptionOfSubtree(tempBoard).Key; if (option == gameBoard.Turn) { return(new KeyValuePair <int, KeyValuePair <int, int> >(option, emptySlot)); } if (bestOption.Key == -gameBoard.Turn || bestOption.Key == -2) { bestOption = new KeyValuePair <int, KeyValuePair <int, int> >(option, emptySlot); } } return(bestOption); }
public static double EvaluateSecondaryDiagonalsWithRestriction(GameBoard gameBoard) { var evaluationScore = 0.0; for (var row = Math.Min(gameBoard.TableSize - gameBoard.SlotsToWin, gameBoard.RowMax + gameBoard.SlotsToWin); row >= Math.Max(0, gameBoard.RowMin - gameBoard.SlotsToWin); row--) { for (var j = Math.Max(0, gameBoard.ColumnMin - gameBoard.SlotsToWin); j < Math.Min(gameBoard.TableSize - row - gameBoard.SlotsToWin + 1, gameBoard.ColumnMax + gameBoard.SlotsToWin); j++) { var ownCounter = 0; var zeroCounter = 0; var enemyCounter = 0; for (var k = j; k < j + gameBoard.SlotsToWin; k++) { if (gameBoard.Table[row + k, gameBoard.TableSize - 1 - k] == 1) { ownCounter++; } else if (gameBoard.Table[row + k, gameBoard.TableSize - 1 - k] == 0) { zeroCounter++; } else { enemyCounter++; } } if (enemyCounter == 0 && zeroCounter != gameBoard.SlotsToWin) { evaluationScore += Math.Pow(10.0, ownCounter); } else if (ownCounter == 0 && zeroCounter != gameBoard.SlotsToWin) { evaluationScore -= Math.Pow(10.0, enemyCounter); } } } for (var column = Math.Max(1, gameBoard.ColumnMin - gameBoard.SlotsToWin); column < Math.Min(gameBoard.TableSize - gameBoard.SlotsToWin, gameBoard.ColumnMax + gameBoard.SlotsToWin); column++) { for (var j = Math.Max(0, gameBoard.ColumnMin - gameBoard.SlotsToWin); j < Math.Min(gameBoard.TableSize - column - gameBoard.SlotsToWin + 1, gameBoard.ColumnMax + gameBoard.SlotsToWin); j++) { var ownCounter = 0; var zeroCounter = 0; var enemyCounter = 0; for (var k = j; k < j + gameBoard.SlotsToWin; k++) { if (gameBoard.Table[k, column + k] == 1) { ownCounter++; } else if (gameBoard.Table[k, column + k] == 0) { zeroCounter++; } else { enemyCounter++; } } if (enemyCounter == 0 && zeroCounter != gameBoard.SlotsToWin) { evaluationScore += Math.Pow(10.0, ownCounter); } else if (ownCounter == 0 && zeroCounter != gameBoard.SlotsToWin) { evaluationScore -= Math.Pow(10.0, enemyCounter); } } } return(evaluationScore); }
public static double EvaluateSecondaryDiagonals(GameBoard gameBoard) { var evaluationScore = 0.0; for (var row = gameBoard.TableSize - gameBoard.SlotsToWin; row >= 0; row--) { for (var j = 0; j < gameBoard.TableSize - row - gameBoard.SlotsToWin + 1; j++) { var ownCounter = 0; var zeroCounter = 0; var enemyCounter = 0; for (var k = j; k < j + gameBoard.SlotsToWin; k++) { if (gameBoard.Table[row + k, gameBoard.TableSize - 1 - k] == 1) { ownCounter++; } else if (gameBoard.Table[row + k, gameBoard.TableSize - 1 - k] == 0) { zeroCounter++; } else { enemyCounter++; } } if (enemyCounter == 0 && zeroCounter != gameBoard.SlotsToWin) { evaluationScore += Math.Pow(10.0, ownCounter); } else if (ownCounter == 0 && zeroCounter != gameBoard.SlotsToWin) { evaluationScore -= Math.Pow(10.0, enemyCounter); } } } for (var column = 1; column < gameBoard.TableSize - gameBoard.SlotsToWin; column++) { for (var j = 0; j < gameBoard.TableSize - column - gameBoard.SlotsToWin + 1; j++) { var ownCounter = 0; var zeroCounter = 0; var enemyCounter = 0; for (var k = j; k < j + gameBoard.SlotsToWin; k++) { if (gameBoard.Table[k, column + k] == 1) { ownCounter++; } else if (gameBoard.Table[k, column + k] == 0) { zeroCounter++; } else { enemyCounter++; } } if (enemyCounter == 0 && zeroCounter != gameBoard.SlotsToWin) { evaluationScore += Math.Pow(10.0, ownCounter); } else if (ownCounter == 0 && zeroCounter != gameBoard.SlotsToWin) { evaluationScore -= Math.Pow(10.0, enemyCounter); } } } return(evaluationScore); }