/// <summary> /// Run the Minimax algorithm with alpha-beta prunning to determine in which column we play. /// </summary> /// <param name="p_GameGrid"> The grid to consider. </param> /// <returns> The calculation details (time and number of iterations) </returns> public override string[] Play(GameGrid p_GameGrid) { Play(p_GameGrid, MinimaxAlgorithm.GetInWhichColumnPlay(p_GameGrid, m_MaxDepth, this, m_Opponent)); return(new string[2] { MinimaxAlgorithm.ElapsedTime, MinimaxAlgorithm.IterationNumber.ToString() }); }
public void TestProvided_BENreturned() { var expected = "ben"; var evaluator = new TestCase1.Evaluator(); var generator = new TestCase1.Generator(); var applier = new TestCase1.Applier(); var algorithm = new MinimaxAlgorithm <TestCase1.State, TestCase1.Move>(evaluator, generator, applier); algorithm.MaxDepth = int.MaxValue; var sb = new StringBuilder(); var state = new TestCase1.State(1, 0); var move = algorithm.Calculate(state); sb.Append(move.Label); state = applier.Apply(state, move); move = algorithm.Calculate(state); sb.Append(move.Label); state = applier.Apply(state, move); move = algorithm.Calculate(state); sb.Append(move.Label); var actual = sb.ToString(); Assert.Equal(expected, actual); }
public void MaxLevel1(int depth) { var evaluator = new TestCase1.Evaluator(); var generator = new TestCase1.Generator(); var applier = new TestCase1.Applier(); var algorithm1 = new MinimaxAlgorithm <TestCase1.State, TestCase1.Move>(evaluator, generator, applier) { MaxDepth = depth }; var algorithm2 = new MinimaxAverageAlgorithm <TestCase1.State, TestCase1.Move>(evaluator, generator, applier) { MaxDepth = depth, MaxLevelAverageDepth = 1, MinLevelAverageDepth = 1 }; var algorithm3 = new AlphaBetaAlgorithm <TestCase1.State, TestCase1.Move>(evaluator, generator, applier) { MaxDepth = 1 }; var state = new TestCase1.State(0, 0); var move1 = algorithm1.Calculate(state); var move2 = algorithm2.Calculate(state); var move3 = algorithm3.Calculate(state); Assert.Equal(move1, move2); Assert.Equal(move2, move3); Assert.Equal(move3, move1); }
public override void PerformMove(Game game, GameState gameState) { MinimaxAlgorithm minimax = new MinimaxAlgorithm(game, heuristics); GameState bestMove = minimax.Minimax(gameState, depth); Logger.LogDebug("MinimaxPlayer move from " + gameState.GetStateHashCode() + " to " + bestMove.GetStateHashCode() + "."); game.PerformMove(bestMove); }
public void GetMinimumValue_WithTerminalState_ReturnsUtilityValue() { var objectUnderTest = new MinimaxAlgorithm <float>( new GenericGameDescription <float>( o => true, o => o, o => Enumerable.Empty <IMove <float> >())); float result = objectUnderTest.GetMinimumValue(4.0f).Value; result.Should().BeApproximately(4.0f, float.Epsilon); }
private IAlgorithm <ChessRepresentation, BaseMove> GetAlgorithm(Type algorithmType, Type evaluatorType) { var generator = new MoveGenerator(_mechanism); var applier = new MoveApplier(_mechanism); var evaluator = (IEvaluator <ChessRepresentation>)Activator.CreateInstance(evaluatorType, new[] { _mechanism }); // TODO : A bit hacky, refactor later! if (algorithmType == typeof(MinimaxAlgorithm <ChessRepresentation, BaseMove>)) { var minimax = new MinimaxAlgorithm <ChessRepresentation, BaseMove>(evaluator, generator, applier) { MaxDepth = (int)numericUpDown1.Value }; return(minimax); } if (algorithmType == typeof(AlphaBetaAlgorithm <ChessRepresentation, BaseMove>)) { var ab = new AlphaBetaAlgorithm <ChessRepresentation, BaseMove>(evaluator, generator, applier) { MaxDepth = (int)numericUpDown1.Value }; return(ab); } if (algorithmType == typeof(MinimaxAverageAlgorithm <ChessRepresentation, BaseMove>)) { var minimaxAvg = new MinimaxAverageAlgorithm <ChessRepresentation, BaseMove>(evaluator, generator, applier) { MaxDepth = (int)numericUpDown1.Value }; return(minimaxAvg); } if (algorithmType == typeof(GreedyAlgorithm <ChessRepresentation, BaseMove>)) { var greedy = new GreedyAlgorithm <ChessRepresentation, BaseMove>(evaluator, generator, applier); return(greedy); } if (algorithmType == typeof(RandomAlgorithm <ChessRepresentation, BaseMove>)) { var randomAlgorithm = new RandomAlgorithm <ChessRepresentation, BaseMove>(generator); return(randomAlgorithm); } throw new ArgumentOutOfRangeException(nameof(algorithmType)); }
public void GetMinimumValue_WithNonTerminalState_ReturnsMinimumValueOfSuccessorState() { var objectUnderTest = new MinimaxAlgorithm <float>( new GenericGameDescription <float>( o => o >= 1.0, o => o, o => new IMove <float>[] { new FloatMove(6.0f), new FloatMove(3.0f), new FloatMove(7.0f), new FloatMove(1.2f) })); float result = objectUnderTest.GetMinimumValue(.0f).Value; result.Should().BeApproximately(1.2f, float.Epsilon); }
public void startGame(int boardSize, int depth, int player1, int player2, int algorithm1, int algorithm2, int boardHeuristic1, int boardHeuristic2, int nodeHeuristic1, int nodeHeuristic2) { this.boardSize = boardSize; gameBoard = new int[boardSize, boardSize]; this.depth = depth; currentPlayer = 0; isPlayer1AI = player1 == 1; isPlayer2AI = player2 == 1; proceedAutomatically = !isPlayer1AI || !isPlayer2AI; if (isPlayer1AI) { Algorithm player1Algorithm; if (algorithm1 == 0) { player1Algorithm = new MinimaxAlgorithm(); } else { player1Algorithm = new AlphaBetaAlgorithm(); } BoardStateEvaluationHeuristic player1BoardStateEvaluationHeuristic; if (boardHeuristic1 == 0) { player1BoardStateEvaluationHeuristic = new OwnAdjacentSymbolsBoardStateEvaluationHeuristic(); } else if (boardHeuristic1 == 1) { player1BoardStateEvaluationHeuristic = new NoAdjacentOpponentSymbolsBoardStateEvaluationHeuristic(); } else { player1BoardStateEvaluationHeuristic = new OwnSymbolsInCompletedLinesBoardStateEvaluationHeuristic(); } NodeSelectionHeuristic player1NodeSelectionHeuristic; if (nodeHeuristic1 == 0) { player1NodeSelectionHeuristic = null; } else if (nodeHeuristic1 == 1) { player1NodeSelectionHeuristic = new CentralNodeSelectionHeuristic(); } else { player1NodeSelectionHeuristic = new BorderNodeSelectionHeuristic(); } player1Strategy = new Strategy(player1Algorithm, player1BoardStateEvaluationHeuristic, player1NodeSelectionHeuristic); } if (isPlayer2AI) { Algorithm player2Algorithm; if (algorithm2 == 0) { player2Algorithm = new MinimaxAlgorithm(); } else { player2Algorithm = new AlphaBetaAlgorithm(); } BoardStateEvaluationHeuristic player2BoardStateEvaluationHeuristic; if (boardHeuristic2 == 0) { player2BoardStateEvaluationHeuristic = new OwnAdjacentSymbolsBoardStateEvaluationHeuristic(); } else if (boardHeuristic2 == 1) { player2BoardStateEvaluationHeuristic = new NoAdjacentOpponentSymbolsBoardStateEvaluationHeuristic(); } else { player2BoardStateEvaluationHeuristic = new OwnSymbolsInCompletedLinesBoardStateEvaluationHeuristic(); } NodeSelectionHeuristic player2NodeSelectionHeuristic; if (nodeHeuristic2 == 0) { player2NodeSelectionHeuristic = null; } else if (nodeHeuristic2 == 1) { player2NodeSelectionHeuristic = new CentralNodeSelectionHeuristic(); } else { player2NodeSelectionHeuristic = new BorderNodeSelectionHeuristic(); } player2Strategy = new Strategy(player2Algorithm, player2BoardStateEvaluationHeuristic, player2NodeSelectionHeuristic); } player1Score = 0; player2Score = 0; freeFields = boardSize * boardSize; nextMove = null; stopwatch = new Stopwatch(); turnNumber = 0; startNewTurn(); UIController.instance.setCooldownOnRestartButton(); }