private UtilityGameMove GetMinUtilityMove(UtilityGameMove originalMove, UtilityGameMove nextMove) { if (originalMove.Utility <= nextMove.Utility) { return(originalMove); } return(nextMove); }
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); }