Example #1
0
        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);
        }