public double GetWins(GameState gameState, int repeats) { var result = PlayerUtilities.GetTerminalState(gameState, PlayerSymbol); switch (result) { case PlayerUtilities.TerminalState.Win: return(repeats); case PlayerUtilities.TerminalState.Draw: return(50); case PlayerUtilities.TerminalState.Lose: return(0); } double wins = 0; int countWins = 0; int countLoss = 0; for (int gamesPlayed = 0; gamesPlayed < repeats; gamesPlayed++) { var gs = gameState.Clone() as GameState; var player = SmarterOpponent; gs.ApplyMove(player.MakeMove(gs)); result = PlayerUtilities.GetTerminalState(gs, PlayerSymbol); while (result == PlayerUtilities.TerminalState.Incomplete) { var gameMove = player.MakeMove(gs); gs.ApplyMove(gameMove); result = PlayerUtilities.GetTerminalState(gs, PlayerSymbol); player = player == SmarterOpponent ? RandomMe : SmarterOpponent; } if (result == PlayerUtilities.TerminalState.Win) { wins += 1; countWins++; } else if (result == PlayerUtilities.TerminalState.Draw) { wins += 0.5; countLoss++; } result = PlayerUtilities.TerminalState.Incomplete; } return(wins); }
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); }