예제 #1
0
        private List <StepNode> CreateStepNodes()
        {
            StepNode gameStart               = null,
                     mulligan                = null,
                     untap                   = null,
                     upkeep                  = null,
                     draw                    = null,
                     firstMain               = null,
                     beginOfCombat           = null,
                     declareAttackers        = null,
                     declareBlockers         = null,
                     firstStrikeCombatDamage = null,
                     combatDamage            = null,
                     endofCombat             = null,
                     secondMain              = null,
                     endOfTurn               = null,
                     cleanup                 = null;

            gameStart = NewStep(Step.GameStart,
                                new Action[]
            {
                SelectStartingPlayer,
                ShuffleLibraries,
                DrawStartingHands,
            },
                                next: () => mulligan,
                                getsPriority: false);

            mulligan = NewStep(Step.Mulligan,
                               new Action[] { TakeMulligans },
                               next: () => Players.AnotherMulliganRound ? mulligan : untap,
                               getsPriority: false);

            untap = NewStep(Step.Untap,
                            new Action[]
            {
                () => Turn.NextTurn(),
                () =>
                {
                    foreach (var permanent in Players.Active.Battlefield)
                    {
                        permanent.HasSummoningSickness = false;

                        if (permanent.Has().DoesNotUntap)
                        {
                            continue;
                        }

                        if (permanent.MayChooseNotToUntap)
                        {
                            Enqueue(new ChooseToUntap(
                                        Players.Active,
                                        permanent));
                        }
                        else
                        {
                            permanent.Untap();
                        }
                    }

                    Players.Active.LandsPlayedCount = 0;
                }
            },
                            next: () => upkeep,
                            getsPriority: false);

            upkeep = NewStep(Step.Upkeep,
                             next: () => draw,
                             getsPriority: true);


            draw = NewStep(Step.Draw,
                           new Action[]
            {
                () =>
                {
                    if (Turn.TurnCount != 1)
                    {
                        Players.Active.DrawCard();
                    }
                }
            },
                           next: () => firstMain,
                           getsPriority: true);

            firstMain = NewStep(Step.FirstMain,
                                next: () => beginOfCombat,
                                getsPriority: true);

            beginOfCombat = NewStep(Step.BeginningOfCombat,
                                    next: () => declareAttackers,
                                    getsPriority: true);

            declareAttackers = NewStep(Step.DeclareAttackers,
                                       new Action[]
            {
                DeclareAttackers
            },
                                       next: () => declareBlockers,
                                       getsPriority: true);

            declareBlockers = NewStep(Step.DeclareBlockers,
                                      new Action[]
            {
                DeclareBlockers,
                SetDamageAssignmentOrder,
            },
                                      next: () => Combat.AnyCreaturesWithFirstStrike()
          ? firstStrikeCombatDamage
          : combatDamage,
                                      getsPriority: true);


            firstStrikeCombatDamage = NewStep(Step.FirstStrikeCombatDamage,
                                              new Action[]
            {
                () => Combat.AssignCombatDamage(firstStrike: true),
                DealAssignedCombatDamage,
                () => Players.MoveDeadCreaturesToGraveyard()
            },
                                              next: () => Combat.AnyCreaturesWithNormalStrike()
          ? combatDamage
          : endofCombat,
                                              getsPriority: true);

            combatDamage = NewStep(Step.CombatDamage,
                                   new Action[]
            {
                () => Combat.AssignCombatDamage(),
                DealAssignedCombatDamage,
                () => Players.MoveDeadCreaturesToGraveyard()
            },
                                   next: () => endofCombat,
                                   getsPriority: true);

            endofCombat = NewStep(Step.EndOfCombat,
                                  new Action[]
            {
                () => Combat.RemoveAll()
            },
                                  next: () => secondMain,
                                  getsPriority: true);

            secondMain = NewStep(Step.SecondMain,
                                 next: () => endOfTurn,
                                 getsPriority: true);

            endOfTurn = NewStep(Step.EndOfTurn,
                                next: () => cleanup,
                                getsPriority: true);

            cleanup = NewStep(Step.CleanUp,
                              new Action[]
            {
                () =>
                {
                    Players.RemoveDamageFromPermanents();
                    Players.RemoveRegenerationFromPermanents();

                    DiscardToMaximumHandSize();
                    Publish(new EndOfTurnEvent());
                },
                () => Players.ChangeActivePlayer(),
            },
                              next: () => untap,
                              getsPriority: false);


            var all = new List <StepNode>
            {
                gameStart,
                mulligan,
                untap,
                upkeep,
                draw,
                firstMain,
                beginOfCombat,
                declareAttackers,
                declareBlockers,
                firstStrikeCombatDamage,
                combatDamage,
                endofCombat,
                secondMain,
                endOfTurn,
                cleanup
            };

            return(all);
        }
예제 #2
0
 private void SetDamageAssignmentOrder()
 {
     Combat.SetDamageAssignmentOrder();
 }
예제 #3
0
        public Game(GameParameters p)
        {
            ChangeTracker = new ChangeTracker();
            Stack         = new Stack();
            Turn          = new TurnInfo();
            Ai            = new SearchRunner(p.SearchParameters, this);
            Combat        = new Combat();
            Settings      = p.Settings;

            _decisionQueue = new DecisionQueue();
            _publisher     = new Publisher(changeTracker: ChangeTracker);
            _wasStopped    = new Trackable <bool>();
            _stateMachine  = new StateMachine();

            var player1 = new Player(p.Player1, p.Player1Controller);
            var player2 = new Player(p.Player2, p.Player2Controller);

            Players = new Players(player1, player2);

            _damagePreventions  = new DamagePreventions();
            _damageRedirections = new DamageRedirections();
            _namedGameModifiers = new NamedGameModifiers();
            _costModifiers      = new CostModifiers();
            _scenario           = new Scenario(this);

            if (p.IsSavedGame)
            {
                Random   = new RandomGenerator(p.SavedGame.RandomSeed);
                Recorder = new GameRecorder(this, p.SavedGame.Decisions);
            }
            else
            {
                Random   = new RandomGenerator();
                Recorder = new GameRecorder(this);
            }

            Initialize();

            if (p.IsSavedGame)
            {
                p.SavedGame.Decisions.Position = 0;

                Player looser = null;

                if (p.Looser != null)
                {
                    looser = p.Looser == 0 ? player1 : player2;
                }

                _stateMachine.Start(() =>
                {
                    if (p.RollBack > 0)
                    {
                        return((Turn.StateCount < p.SavedGame.StateCount - p.RollBack) || (_stateMachine.HasPendingDecisions));
                    }

                    return(Turn.StateCount < p.SavedGame.StateCount || Recorder.IsPlayback);
                }, skipPreGame: false, looser: looser);

                Recorder.DiscardUnloadedResults();
                _wasLoaded = true;
            }
        }