예제 #1
0
        public Action ChooseAction(Character actor, Party friendlyParty, Party hostileParty)
        {
            this.Actor         = actor;
            this.FriendlyParty = friendlyParty;
            this.HostileParty  = hostileParty;

            Trait groupHealingTrait   = GetGroupHealingTrait();
            int   totalGroupHealth    = friendlyParty.CharacterList.Sum(x => x.Hitpoints);
            int   totalGroupMaxHealth = friendlyParty.CharacterList.Sum(x => x.MaxHitpoints);

            if (groupHealingTrait != null && Actor.Mana >= groupHealingTrait.Mana && totalGroupMaxHealth - totalGroupHealth > 100)
            {
                return(new Action(Actor, friendlyParty, groupHealingTrait));
            }

            Trait     directHealingTrait = GetDirectHealingTrait();
            Character injuredAlly        = FindLowestHPInjuredAlly();

            if (directHealingTrait != null && Actor.Mana >= directHealingTrait.Mana && injuredAlly != null)
            {
                return(new Action(Actor, injuredAlly, directHealingTrait));
            }

            List <Trait> groupBuffTraits = GetGroupBuffTraits();

            foreach (Trait groupBuffTrait in groupBuffTraits)
            {
                if (Actor.Mana >= groupBuffTrait.Mana)
                {
                    foreach (Buff buff in groupBuffTrait.Buffs)
                    {
                        if (friendlyParty.CharacterList.FindAll(x => x.Buffs.Contains(buff)).Count < friendlyParty.CharacterList.Count)
                        {
                            return(new Action(Actor, friendlyParty, groupBuffTrait));
                        }
                    }
                }
            }

            Trait groupDamageTrait  = GetGroupDamageTrait();
            int   aliveEnemiesCount = hostileParty.CharacterList.FindAll(x => x.Alive).Count;

            if (groupDamageTrait != null && Actor.Mana >= groupDamageTrait.Mana && aliveEnemiesCount > 1)
            {
                return(new Action(Actor, hostileParty, groupDamageTrait));
            }

            Trait directDamageTrait = GetDirectDamageTrait();

            if (directDamageTrait != null && Actor.Mana >= directDamageTrait.Mana)
            {
                return(new Action(Actor, FindLowestHPTarget(), directDamageTrait));
            }

            Trait     meleeTrait  = GetMeleeTrait();
            Character meleeTarget = FindLowestHPMeleeTarget();

            if (meleeTrait != null && meleeTarget != null)
            {
                return(new Action(Actor, meleeTarget, meleeTrait));
            }

            return(null);
        }
예제 #2
0
        public Party Duel(List <Party> parties)
        {
            // Initialize Combatants
            string output        = "";
            int    longestString = 0;

            for (var i = 0; i < parties.Count; i++)
            {
                foreach (var character in parties[i].CharacterList)
                {
                    character.PartyId = i;
                    this.combatants.Add(character);
                }
                string currentString = String.Format("{0}: total point cost is {1}\n", parties[i].Name, parties[i].PointCost());
                if (currentString.Length > longestString)
                {
                    longestString = currentString.Length;
                }
                output += currentString;
            }
            Console.WriteLine(new String('=', longestString));
            Console.Write(output);
            Console.WriteLine(new String('=', longestString));

            // Round
            Party winner     = null;
            int   roundCount = 1;

            while (winner == null)
            {
                Random rand = new Random();
                Console.WriteLine("*** ROUND " + roundCount.ToString() + " ***");
                // Roll Initiative
                foreach (var combatant in combatants)
                {
                    int maxInitiative = combatant.Stats[Stat.Dexterity] * 5;
                    combatant.Initiative = rand.Next(maxInitiative);
                }
                // Sort Combatants by Initiative
                combatants.Sort();
                // Loop through combatants
                foreach (var combatant in combatants)
                {
                    if (!combatant.Alive)
                    {
                        continue;
                    }

                    if (combatant.Effects.Contains(Effect.Poison))
                    {
                        Trait  poisonDamage = Trait.GetTrait("poison_damage");
                        Action poisonAction = new Action(combatant, combatant, poisonDamage);
                        int    minDamage    = 1;
                        int    maxDamage    = poisonAction.Trait.Power;
                        DoSingleDamage(poisonAction, minDamage, maxDamage, rand);
                    }

                    if (!combatant.Alive)
                    {
                        continue;
                    }

                    if (combatant.Mana < combatant.MaxMana)
                    {
                        combatant.Mana += combatant.ManaRegen;
                    }

                    Party friendlyParty = null;
                    Party hostileParty  = null;
                    for (var i = 0; i < parties.Count; i++)
                    {
                        if (i == combatant.PartyId)
                        {
                            friendlyParty = parties[i];
                        }
                        else
                        {
                            hostileParty = parties[i];
                        }
                    }

                    // Do an action
                    Action action = combatant.AI.ChooseAction(combatant, friendlyParty, hostileParty);

                    if (action == null)
                    {
                        continue;
                    }

                    if (action.Trait.Mana > 0)
                    {
                        action.Actor.Mana -= action.Trait.Mana;
                    }

                    switch (action.Trait.Type)
                    {
                    case TraitType.Melee:
                        int minDamage = combatant.Stats[Stat.Strength];
                        int maxDamage = combatant.Stats[Stat.Strength] + action.Trait.Power;
                        DoSingleDamage(action, minDamage, maxDamage, rand);
                        break;

                    case TraitType.DirectDamage:
                        minDamage = action.Trait.Power;
                        maxDamage = combatant.Stats[Stat.Intelligence] + action.Trait.Power;
                        DoSingleDamage(action, minDamage, maxDamage, rand);
                        break;

                    case TraitType.DirectHealing:
                        int minHeal = action.Trait.Power;
                        int maxHeal = combatant.Stats[Stat.Wisdom] + action.Trait.Power;
                        DoSingleHealing(action, minHeal, maxHeal, rand);
                        break;

                    case TraitType.GroupDamage:
                        foreach (Character target in hostileParty.CharacterList)
                        {
                            Action targetedAction = new Action(action.Actor, target, action.Trait);
                            minDamage = (combatant.Stats [Stat.Intelligence] / 4);
                            maxDamage = combatant.Stats [Stat.Intelligence] + action.Trait.Power;
                            DoSingleDamage(targetedAction, minDamage, maxDamage, rand);
                        }
                        break;

                    case TraitType.GroupHealing:
                        foreach (Character target in friendlyParty.CharacterList)
                        {
                            if (!target.Alive)
                            {
                                continue;
                            }
                            Action targetedAction = new Action(action.Actor, target, action.Trait);
                            minHeal = action.Trait.Power;
                            maxHeal = combatant.Stats[Stat.Wisdom] + action.Trait.Power;
                            DoSingleHealing(targetedAction, minHeal, maxHeal, rand);
                        }
                        break;

                    case TraitType.GroupBuff:
                        foreach (Character target in friendlyParty.CharacterList)
                        {
                            Action targetedAction = new Action(action.Actor, target, action.Trait);
                            DoSingleBuff(targetedAction);
                        }
                        break;
                    }

                    // Check for victory
                    List <Party> deadPartyList = new List <Party> ();
                    foreach (var party in parties)
                    {
                        if (party.CharacterList.Find(x => x.Hitpoints > 0) == null)
                        {
                            deadPartyList.Add(party);
                        }
                    }
                    if (deadPartyList.Count == parties.Count - 1)
                    {
                        foreach (var party in parties)
                        {
                            if (deadPartyList.Contains(party))
                            {
                                continue;
                            }
                            Console.ForegroundColor = ConsoleColor.Green;
                            Console.BackgroundColor = ConsoleColor.White;
                            Console.Write("The winner is " + party.Name);
                            Console.ResetColor();
                            Console.Write("\n");
                            winner = party;
                            DisplayMatchup(parties);
                            return(winner);
                        }
                    }
                    else if (deadPartyList.Count == parties.Count)
                    {
                        Console.WriteLine("The match is a draw");
                        DisplayMatchup(parties);
                        winner = new Party();
                        return(winner);
                    }
                }

                DisplayMatchup(parties);

                roundCount++;
                // TODO: make Round Limit configurable
                if (roundCount == 500)
                {
                    Console.WriteLine("Round limit hit");
                    return(new Party());
                }
            }

            return(winner);
        }
예제 #3
0
        public Character(string name, string raceName, Row row, List <String> traits)
        {
            var racePath = "data/races/";

            this.Name = name;

            raceName = raceName.ToLower();

            var yaml         = File.ReadAllText(racePath + raceName + ".yaml");
            var deserializer = new DeserializerBuilder()
                               .WithNamingConvention(new CamelCaseNamingConvention())
                               .Build();

            var race = deserializer.Deserialize <Race>(yaml);

            this.Race        = race.Name;
            this.Size        = race.Size;
            this.BaseStats   = race.Stats;
            this.BaseResists = race.Resists;
            this.PointCost  += race.Points;
            this.Traits      = new List <Trait>();
            this.Effects     = new List <Effect>();
            this.Buffs       = new List <Buff>();
            this.Alive       = true;
            this.Row         = row;
            this.ManaRegen   = 0;

            //TODO: load AI choice
            this.AI = new GeneralAI();

            foreach (var t in race.Traits)
            {
                Trait trait = LoadTrait(t);
                this.Traits.Add(trait);
            }

            foreach (var t in traits)
            {
                Trait trait = LoadTrait(t);
                this.Traits.Add(trait);
                this.PointCost += trait.PointCost;
            }

            this.Resists = this.BaseResists;
            this.Stats   = this.BaseStats;

            foreach (var t in this.Traits)
            {
                if (t.Type != TraitType.StatChange)
                {
                    continue;
                }

                if (t.Stat == Stat.AC)
                {
                    this.AC += t.Power;
                }

                if (this.Stats.ContainsKey(t.Stat))
                {
                    this.Stats[t.Stat] += t.Power;
                }
            }

            this.MaxHitpoints = (this.Stats[Stat.Constitution] * 4) + 50;
            this.Hitpoints    = this.MaxHitpoints;
            this.MaxMana      = (this.Stats[Stat.Intelligence] * 2) + (this.Stats[Stat.Wisdom] * 2) + 25;
            this.Mana         = MaxMana;
            this.ManaRegen   += (int)Math.Round((double)(this.Stats[Stat.Wisdom] / 10));
            this.AC          += this.Stats[Stat.Dexterity] / 4;
        }