Пример #1
0
        /// <summary>
        /// Recursively expand the current move, or evaluate it if it is at the leaf level
        /// </summary>
        /// <param name="scenario"></param>
        /// <param name="childMoveLevel"></param>
        /// <returns>Either null if no suitable decision could be found, or the best result for the decision maker at this level</returns>
        public MoveResult ExpandAndEvaluate(Scenario scenario, int childMoveLevel)
        {
            MoveGenerator[] moveGenerators = scenario.GetMoveGeneratorsByMoveTreeLevel();
            if (childMoveLevel == moveGenerators.Length)
            {
                // At the leaf level, so evaluate the scenario:
                return(scenario.EvaluateLeafNodeMove(this));
            }

            MoveGenerator moveGen = moveGenerators[childMoveLevel];

            Move[] childMoves = moveGen.Generate(scenario, parentMove: this);

            int        bestSlackForDecisionMaker;
            MoveResult bestResultForDecisionMaker = null;

            bestSlackForDecisionMaker = int.MaxValue;
            foreach (Move childMove in childMoves)
            {
                if (childMove == null)
                {
                    continue;
                }
                MoveResult childMoveResult = childMove.ExpandAndEvaluate(scenario, childMoveLevel + 1);

                if (childMoveResult == null)
                {
                    continue;
                }

                if (childMoveResult.EvaluationOutcome != ScenarioEvaluationOutcome.Invalid)
                {
                    if ( // Player p wants to minimize slack:
                        ((moveGen.DecisionMaker == ScenarioDecisionMaker.p) && (childMoveResult.Slack < bestSlackForDecisionMaker))
                        // Player pBar wants to maximize slack:
                        || (moveGen.DecisionMaker == ScenarioDecisionMaker.pBar) && (childMoveResult.Slack > bestSlackForDecisionMaker))
                    {
                        bestResultForDecisionMaker = childMoveResult;
                        bestSlackForDecisionMaker  = childMoveResult.Slack;
                    }
                }
                else
                {
                    // Return an invalid result rather than null if possible:
                    if (bestResultForDecisionMaker == null)
                    {
                        bestResultForDecisionMaker = childMoveResult;
                    }
                }
            }

            return(bestResultForDecisionMaker);
        }
Пример #2
0
        public static MoveResult[] EvaluateScenario(Scenario scenario)
        {
#if DEBUG
            System.Diagnostics.Stopwatch swatch = System.Diagnostics.Stopwatch.StartNew();
#endif

            MoveGenerator[] moveGenerators       = scenario.GetMoveGeneratorsByMoveTreeLevel();
            MoveGenerator   initialMoveGenerator = moveGenerators[0];
            Move[]          initialMoves         = initialMoveGenerator.Generate(scenario, null);
            MoveResult[]    moveResults          = new MoveResult[initialMoves.Length];
            for (int i = 0; i < moveResults.Length; i++)
            {
                Move       initialMove = initialMoves[i];
                MoveResult moveResult  = initialMove.ExpandAndEvaluate(scenario, 1);
                moveResults[i] = moveResult;
            }
#if DEBUG
            swatch.Stop();
            AndrewTweddle.BattleCity.Core.Helpers.DebugHelper.LogDebugMessage(
                "ScenarioEvaluator", "Duration to expand moves for scenario {0}: {1}",
                scenario.GetType().Name, swatch.Elapsed);
#endif
            return(moveResults);
        }