예제 #1
0
        public ClanBossBattle(ClanBoss.Level level, List <ChampionInBattle> championsInBattle)
        {
            ClanBossInBattle clanBoss = new ClanBossInBattle(ClanBoss.Get(level));

            this.initialState  = new CBBState(new List <ChampionInBattle>(championsInBattle), clanBoss);
            this.GetStunTarget = FindSlowBoi;
        }
예제 #2
0
 private void PrintTurnMeters(CBBState state)
 {
     foreach (IBattleParticipant bp in state.BattleParticipants)
     {
         Console.WriteLine("  {0} turn meter {1}", bp.Name, bp.TurnMeter);
     }
 }
예제 #3
0
 public CBBState(CBBState other)
 {
     this.BattleParticipants = new List <IBattleParticipant>();
     foreach (IBattleParticipant bp in other.BattleParticipants)
     {
         this.BattleParticipants.Add(bp.Clone());
     }
     this.Results = new List <ClanBossBattleResult>(other.Results);
 }
예제 #4
0
        private IEnumerable <List <ClanBossBattleResult> > Run(bool exploreAllSequences, bool failOnKill)
        {
            Queue <CBBState> battleStates = new Queue <CBBState>();

            battleStates.Enqueue(this.initialState);

            // While the queue isn't empty
            // run all possible next turns for the head of the queue state and enqueue those states
            // If someone is killed after the last unkillable turn, the run fails (no more enqueues)
            // If clan boss has turn 50, the run succeeds (return the result)
            while (battleStates.Count > 0)
            {
                CBBState state         = battleStates.Dequeue();
                bool     returnResults = false;

                // Advance turn meter for each battle participant
                foreach (IBattleParticipant participant in state.BattleParticipants)
                {
                    participant.ClockTick();
                }

                // See who has the most turn meter
                double maxTurnMeter = double.MinValue;
                foreach (IBattleParticipant participant in state.BattleParticipants)
                {
                    maxTurnMeter = Math.Max(maxTurnMeter, participant.TurnMeter);
                }

                // See if anybody has a full turn meter
                if (maxTurnMeter <= Constants.TurnMeter.Full)
                {
                    // Nothing to do this time, re-enqueue this state.
                    battleStates.Enqueue(state);
                }
                else
                {
                    // Champion with the fullest turn meter takes a turn!
                    IBattleParticipant maxTMChamp = state.BattleParticipants.First(bp => bp.TurnMeter == maxTurnMeter);

                    foreach (Skill passive in maxTMChamp.GetPassiveSkills())
                    {
                        if (passive.TurnAction.EffectsToApply != null)
                        {
                            foreach (EffectToApply effect in passive.TurnAction.EffectsToApply)
                            {
                                if (effect.WhenToApply == Constants.TimeInTurn.Beginning)
                                {
                                    if (effect.Target == Constants.Target.Self)
                                    {
                                        maxTMChamp.ApplyEffect(effect.Effect);
                                    }
                                    else if (effect.Target == Constants.Target.AllAllies)
                                    {
                                        foreach (IBattleParticipant bp in state.BattleParticipants.Where(p => !p.IsClanBoss && p != maxTMChamp))
                                        {
                                            bp.ApplyEffect(effect.Effect);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    IEnumerable <Skill> skillsToRun;
                    Skill nextAISkill = maxTMChamp.NextAISkill();
                    if (exploreAllSequences && state.BattleParticipants.Where(bp => bp.IsClanBoss).First().TurnCount < AutoAfterClanBossTurn)
                    {
                        skillsToRun = maxTMChamp.AllAvailableSkills();
                    }
                    else
                    {
                        skillsToRun = new List <Skill>()
                        {
                            maxTMChamp.NextAISkill()
                        };
                    }

                    CBBState currentState = state;
                    foreach (Skill skill in skillsToRun)
                    {
                        state = new CBBState(currentState);
                        IBattleParticipant champ = state.BattleParticipants.Where(bp => bp.Name == maxTMChamp.Name).First();
                        List <ClanBossBattleResult.Attack> additionalAttacks = new List <ClanBossBattleResult.Attack>();

                        champ.TakeTurn(skill);

                        if (!champ.IsClanBoss)
                        {
                            TurnAction action = skill.TurnAction;
                            additionalAttacks = ApplyTurnActions(
                                skill,
                                champ,
                                state.BattleParticipants.Where(p => !p.IsClanBoss && p != champ),
                                state.BattleParticipants.Where(p => !p.IsClanBoss),
                                state.BattleParticipants.Where(p => p.IsClanBoss),
                                state.BattleParticipants.Where(p => p.IsClanBoss).First()
                                );

                            battleStates.Enqueue(state);
                        }
                        else
                        {
                            // Clan boss turn!
                            TurnAction action          = skill.TurnAction;
                            bool       enqueueNewState = true;
                            List <IBattleParticipant> additionalAttackers = new List <IBattleParticipant>();

                            if (action.AttackTarget == Constants.Target.AllEnemies)
                            {
                                foreach (IBattleParticipant bp in state.BattleParticipants.Where(p => !p.IsClanBoss))
                                {
                                    bp.GetAttacked(action.AttackCount);

                                    if (bp.ActiveBuffs.ContainsKey(Constants.Buff.Counterattack) &&
                                        !bp.ActiveDebuffs.ContainsKey(Constants.Debuff.Stun))
                                    {
                                        additionalAttackers.Add(bp);
                                    }

                                    if (champ.TurnCount > LastKillableTurn && !bp.ActiveBuffs.ContainsKey(Constants.Buff.Unkillable))
                                    {
                                        enqueueNewState = !failOnKill;
                                    }
                                }
                            }
                            else if (action.AttackTarget == Constants.Target.OneEnemy)
                            {
                                IBattleParticipant stunTarget = this.GetStunTarget(state.BattleParticipants);

                                stunTarget.GetAttacked(action.AttackCount);

                                if (champ.TurnCount > LastKillableTurn && !stunTarget.ActiveBuffs.ContainsKey(Constants.Buff.Unkillable))
                                {
                                    enqueueNewState = !failOnKill;
                                }

                                if (action.DebuffsToApply != null)
                                {
                                    stunTarget.ApplyDebuff(action.DebuffsToApply.First());
                                }

                                if (stunTarget.ActiveBuffs.ContainsKey(Constants.Buff.Counterattack) &&
                                    !stunTarget.ActiveDebuffs.ContainsKey(Constants.Debuff.Stun))
                                {
                                    additionalAttackers.Add(stunTarget);
                                }
                            }

                            foreach (IBattleParticipant bp in additionalAttackers)
                            {
                                bp.AdditionalAttack();
                                additionalAttacks.Add(new ClanBossBattleResult.Attack(bp.Name, bp.TurnCount, bp.TurnMeter, Constants.SkillId.A1, bp.GetA1().Name, Constants.SkillId.A1));
                            }

                            if (champ.TurnCount == MaxClanBossTurns)
                            {
                                // End of the run!
                                enqueueNewState = false;
                                returnResults   = true;
                            }

                            if (enqueueNewState)
                            {
                                battleStates.Enqueue(state);
                            }
                        }

                        List <ClanBossBattleResult.BattleParticipantStats> bpStats = new List <ClanBossBattleResult.BattleParticipantStats>();
                        foreach (IBattleParticipant bp in state.BattleParticipants)
                        {
                            ClanBossBattleResult.BattleParticipantStats bpStat = new ClanBossBattleResult.BattleParticipantStats(bp.Name, bp.IsClanBoss, bp.TurnMeter, new Dictionary <Constants.Buff, int>(bp.ActiveBuffs), new Dictionary <Constants.Debuff, int>(bp.ActiveDebuffs), bp.GetSkillToCooldownMap());
                            bpStats.Add(bpStat);
                        }

                        ClanBossBattleResult.Attack attackDetails = new ClanBossBattleResult.Attack(champ.Name, champ.TurnCount, maxTurnMeter, skill.Id, skill.Name, nextAISkill.Id);
                        ClanBossBattleResult        result        = new ClanBossBattleResult(state.BattleParticipants.First(p => p.IsClanBoss).TurnCount, attackDetails, bpStats, additionalAttacks);
                        state.Results.Add(result);

                        if (returnResults)
                        {
                            yield return(state.Results);
                        }
                    }
                }
            }
        }