コード例 #1
0
        private Node TreePolicy(Node node)
        {
            var state = node.State;

            while (state?.State != State.COMPLETE && node.TurnDepth < TurnDepth)
            {
                if (state == null)
                {
                    return(node);
                }
                if (FullyExpanded(node))
                {
                    var selectionStrategy = SelectionStrategies.GetSelectionStrategy(Selection);
                    var stateRateStrategy = StateRateStrategies.GetStateRateStrategy(StateRate);
                    node  = ChildSelection.SelectBestChild(state, node, EXPLORATION_CONSTANT, player, selectionStrategy, stateRateStrategy);
                    state = state.Simulate(new List <PlayerTask> {
                        node.Action
                    })[node.Action];
                }
                else
                {
                    return(Expand(node, state));
                }
            }

            return(node);
        }
コード例 #2
0
        private float DefaultPolicyHeuristic(Node node)
        {
            float  result           = 0;
            POGame state            = node.State;
            int    currentTurnDepth = node.TurnDepth;

            while (state.State != State.COMPLETE &&
                   (node.Action.PlayerTaskType == PlayerTaskType.END_TURN ?
                    currentTurnDepth < TurnDepth - 1 :
                    currentTurnDepth < TurnDepth))
            {
                Controller        currentPlayer = state.CurrentPlayer;
                List <PlayerTask> actions       = currentPlayer.Options();
                List <PlayerTask> oldActions    = new List <PlayerTask>(actions);
                bool uncertainity = currentPlayer.Options()
                                    .Any(option => option.PlayerTaskType == PlayerTaskType.PLAY_CARD && option.Source.Card.Name == "No Way!");

                // end potential infinite loop of 0 cost spells (happend few times with a mage)
                if (currentPlayer.CardsPlayedThisTurn.Count > 50)
                {
                    break;
                }

                if (uncertainity)
                {
                    // depending on active player choose one:
                    // 1) simulate player's card draw
                    // 2) simulate opponent's possible actions
                    actions = state.CurrentPlayer.PlayerId == player.PlayerId ?
                              ActionEstimator.DrawSimulation(currentPlayer) :
                              ActionEstimator.ActionEstimaton(state, currentPlayer);
                }

                var bestPair = state.Simulate(actions.Any() ? actions : oldActions)
                               .Where(pair => pair.Value != null)
                               .OrderBy(pair => StateRateStrategies.GetStateRateStrategy(StateRateStrategy.Greedy)(pair.Value, currentPlayer))
                               .Last();

                //Console.WriteLine(currentTurnDepth + ", " + bestPair.Key);

                if (bestPair.Key.PlayerTaskType == PlayerTaskType.END_TURN)
                {
                    currentTurnDepth++;
                }

                state = bestPair.Value;

                // this should be redundant.. but, you know.. just in case..
                if (state == null)
                {
                    return(0.5f);
                }
            }

            var firstPlayer = state.CurrentPlayer.PlayerId == player.PlayerId ? state.CurrentPlayer : state.CurrentOpponent;

            result = StateRateStrategies.GetStateRateStrategy(StateRateStrategy.Greedy)(state, firstPlayer);

            return(result);
        }
コード例 #3
0
        private KeyValuePair <int, float> DefaultPolicy(POGame state, Node node)
        {
            KeyValuePair <int, float> result = new KeyValuePair <int, float>(state.CurrentPlayer.PlayerId, 0.5f);

            while (state.State != State.COMPLETE)
            {
                List <PlayerTask> actions    = state.CurrentPlayer.Options();
                List <PlayerTask> oldActions = new List <PlayerTask>(actions);
                bool uncertainity            = state.CurrentPlayer.Options()
                                               .Any(option => option.PlayerTaskType == PlayerTaskType.PLAY_CARD && option.Source.Card.Name == "No Way!");

                Controller currentPlayer = state.CurrentPlayer;

                if (uncertainity)
                {
                    // player's drawn cards are also unknown -> need to simulate
                    actions = state.CurrentPlayer.PlayerId == player.PlayerId ?
                              ActionEstimator.DrawSimulation(currentPlayer) :
                              ActionEstimator.ActionEstimaton(state, currentPlayer);
                }

                var bestPair = state.Simulate(actions.Any() ? actions : oldActions)
                               .Where(pair => pair.Value != null)
                               .OrderBy(pair => StateRateStrategies.GetStateRateStrategy(StateRateStrategy.Greedy)(pair.Value, player))
                               .Last();
                //Console.WriteLine("Choosing: " + bestAction);

                state = bestPair.Value;

                // this should be redundant.. but, you know.. just in case..
                if (state == null)
                {
                    return(new KeyValuePair <int, float>(currentPlayer.PlayerId, 0.5f));
                }
            }

            if (state.CurrentPlayer.PlayState == PlayState.CONCEDED || state.CurrentPlayer.PlayState == PlayState.LOST)
            {
                result = new KeyValuePair <int, float>(state.CurrentPlayer.PlayerId, 0);
            }
            else if (state.CurrentPlayer.PlayState == PlayState.WON)
            {
                result = new KeyValuePair <int, float>(state.CurrentPlayer.PlayerId, 1);
            }
            else if (state.CurrentPlayer.PlayState == PlayState.TIED)
            {
                result = new KeyValuePair <int, float>(state.CurrentPlayer.PlayerId, 0.5f);
            }
            return(result);
        }
コード例 #4
0
        public PlayerTask Search()
        {
            List <PlayerTask> options = player.Options();

            if (options.Count == 1 && options[0].PlayerTaskType == PlayerTaskType.END_TURN)
            {
                return(options.First());
            }

            StopWatch.Start();
            var selectionStrategy = SelectionStrategies.GetSelectionStrategy(Selection);
            var stateRateStrategy = StateRateStrategies.GetStateRateStrategy(StateRate);

            while (StopWatch.ElapsedMilliseconds < COMPUTATIONAL_BUDGET)
            {
                POGame state    = InitialState.getCopy();
                Node   lastNode = TreePolicy(Root);
                float  delta    = DefaultPolicyHeuristic(lastNode);
                Backup(lastNode, delta);
            }
            StopWatch.Stop();

            return(ChildSelection.SelectBestChild(InitialState, Root, EXPLORATION_CONSTANT, player, selectionStrategy, stateRateStrategy).Action);
        }
コード例 #5
0
        private List <PlayerTask> ActionEstimaton(POGame state, Controller player)
        {
            // estimate best action for upcoming game state which depends on probability of opponent's actions
            // a.k.a. simulate his possibilities (remove incomplete information) and choose most promising

            //Console.WriteLine("Estimator " + player.PlayerId);
            var         history        = player.PlayHistory;
            List <Card> remainingCards = new List <Card>(DecksDict[deckName]);
            List <Card> playedCards    = history.Select(h => h.SourceCard).ToList();
            int         removed        = 0;

            HashSet <PlayerTask> subactions    = new HashSet <PlayerTask>();
            List <PlayerTask>    resultActions = new List <PlayerTask>();

            //Console.WriteLine(opponent);

            // removing played cards
            foreach (Card playedCard in playedCards)
            {
                remainingCards.Remove(playedCard);
            }

            // removing unknown cards from hand
            for (int i = 0; i < player.HandZone.Count; i++)
            {
                IPlayable handCard = player.HandZone[i];
                if (handCard.Card.Name == "No Way!")
                {
                    player.HandZone.Remove(i);
                    removed++;
                    // performing remove on the iterated object so I need to adjust
                    // the iterator to reflect the object's items count change
                    i--;
                }
                else
                {
                    remainingCards.Remove(handCard.Card);
                }
            }

            //Console.WriteLine(String.Format("Removed {0} unknown cards", removed));

            // adding cards to hand for simualtion
            foreach (Card deckCard in remainingCards)
            {
                if (deckCard.Cost <= player.BaseMana)
                {
                    if (player.HandZone.IsFull)
                    {
                        player.Options()
                        .Where(option => option.PlayerTaskType == PlayerTaskType.PLAY_CARD)
                        .ToList()
                        .ForEach(option => subactions.Add(option));
                        clearHand(player);
                    }

                    player.HandZone.Add(Entity.FromCard(in player, deckCard));
                }
                else
                {
                    player.Options()
                    .Where(option => option.PlayerTaskType == PlayerTaskType.PLAY_CARD)
                    .ToList()
                    .ForEach(option => subactions.Add(option));
                    clearHand(player);
                    break;
                }
            }
            ;

            // choosing best subactions
            resultActions.AddRange(
                subactions
                .Where(action => action.PlayerTaskType == PlayerTaskType.PLAY_CARD)
                .OrderBy(action => StateRateStrategies
                         .GetStateRateStrategy(StateRateStrategy.Greedy)(state, player))
                .TakeLast(removed)
                );

            // adding other tasks such as attack, end turn, etc..
            resultActions.AddRange(player.Options());

            // now adding corresponding cards of chosen best tasks to player's hand
            foreach (PlayerTask task in resultActions)
            {
                if (task.PlayerTaskType == PlayerTaskType.PLAY_CARD && task.HasSource && !player.HandZone.IsFull && !player.HandZone.Contains(task.Source))
                {
                    player.HandZone.Add(task.Source);
                }
            }

            //resultActions.ForEach(action => Console.WriteLine(action));
            //Console.WriteLine();

            return(resultActions.Count > 0 ? resultActions : player.Options());

            void clearHand(Controller pplayer)
            {
                while (pplayer.HandZone.Count() > 0)
                {
                    pplayer.HandZone.Remove(0);
                }
                //Console.WriteLine("Hand cleared: " + pplayer.HandZone.Count());
                //printPlayerHand(pplayer);
            }
        }