public GameResults PlayGame(int games) { GameResults results = new GameResults(Player1.Name, Player2.Name); Player playerToMoveFirst = Player1; for (int index = 0; index < games; index++) { NaughtsAndCrossesGame game = new NaughtsAndCrossesGame(); Player currentPlayer = playerToMoveFirst; GameMove nextMove = currentPlayer.MakeMove(game.GameState); MoveResult moveResult = game.ApplyMove(nextMove); while (moveResult == MoveResult.Success) { // Switch player currentPlayer = currentPlayer == Player1 ? Player2 : Player1; nextMove = currentPlayer.MakeMove(game.GameState); moveResult = game.ApplyMove(nextMove); } if (moveResult == MoveResult.Win) { if (currentPlayer == Player1) { results.PlayerScore1++; } else { results.PlayerScore2++; } } if (moveResult == MoveResult.Draw) { results.Draw++; } if (moveResult == MoveResult.Illegal) { throw new Exception($"An illegal move was made by {currentPlayer.Name}"); } if (AlternateFirstMove) { playerToMoveFirst = playerToMoveFirst == Player1 ? Player2 : Player1; } } return(results); }
private UtilityGameMove MinValue(GameState gs, int alpha, int beta, GameMove lastMove = null, int depth = 0) { //var lastMoveValue = lastMove != null ? $"{lastMove.Location}, ${((lastMove.GameSymbol == GameSymbol.Cross) ? "Cross" : "Naught")}" : "null"; //Console.WriteLine($"Min value is called. Alpha: {alpha}, Beta: {beta}, lastMove: {lastMoveValue}"); var terminalState = PlayerUtilities.GetTerminalState(gs, PlayerSymbol); if (terminalState != PlayerUtilities.TerminalState.Incomplete) { if (lastMove == null) { throw new Exception("Cannot find best move, in terminal state but with no last move"); } var utilityValue = GetUtilityOfTerminalState(terminalState); return(new UtilityGameMove(lastMove.Location, lastMove.GameSymbol, utilityValue)); } var moves = gs.GetMoves(); var v = new UtilityGameMove(moves.First().Location, moves.First().GameSymbol, Int32.MaxValue); foreach (var move in moves) { var copiedGameState = gs.Clone() as GameState; copiedGameState.ApplyMove(move); var u = MaxValue(copiedGameState, alpha, beta, move, ++depth); v = GetMinUtilityMove(v, u); beta = Math.Min(beta, v.Utility); if (alpha >= beta) { if (lastMove != null) { return(new UtilityGameMove(lastMove.Location, lastMove.GameSymbol, v.Utility)); } return(v); } } if (lastMove != null) { return(new UtilityGameMove(lastMove.Location, lastMove.GameSymbol, v.Utility)); } return(v); }
public MoveResult ApplyMove(GameMove move) { if (move.Location >= GameState.GameBoard.Length || GameState.GameBoard[move.Location] != GameSymbol.Blank) { return(MoveResult.Illegal); } GameState.GameBoard[move.Location] = move.GameSymbol; GameState.SwitchSymbol(); GameCompletion gameCompletion = GetGameCompletion(); if (gameCompletion == GameCompletion.Won) { return(MoveResult.Win); } if (gameCompletion == GameCompletion.Draw) { return(MoveResult.Draw); } return(MoveResult.Success); }
public void ApplyMove(GameMove move) { GameBoard[move.Location] = move.GameSymbol; SwitchSymbol(); }
public UtilityGameMove(int location, GameSymbol gameSymbol, int utility) { Utility = utility; GameMove = new GameMove(location, gameSymbol); }