示例#1
0
        /// <summary>
        /// Resolves a combat between a group of Hunters and an Opponent
        /// </summary>
        /// <param name="game">The GameState</param>
        /// <param name="huntersInvolved">A list of HunterPlayers involved in the combat</param>
        /// <param name="opponent">The Opponent type</param>
        /// <param name="logic">The artificial intelligence component</param>
        /// <returns>True if the Hunters can continue resolving Encounters</returns>
        private static bool ResolveCombat(GameState game, List<HunterPlayer> huntersInvolved, Opponent opponent,
            DecisionMaker logic)
        {
            var roundsWithoutEscaping = 0;
            var answer = -1;
            do
            {
                Console.WriteLine(
                    "Is anyone playing an Event at the start of this combat? 0= Nobody, {0}= {1}, {2}= {3}, {4}= {5}, {6}= {7}",
                    (int)Hunter.LordGodalming, Hunter.LordGodalming.Name(), (int)Hunter.DrSeward,
                    Hunter.DrSeward.Name(), (int)Hunter.VanHelsing, Hunter.VanHelsing.Name(), (int)Hunter.MinaHarker,
                    Hunter.MinaHarker.Name());
                while (answer == -1)
                {
                    if (int.TryParse(Console.ReadLine(), out answer))
                    {
                        if (answer < 0 || answer > 4)
                        {
                            answer = -1;
                        }
                    }
                }
                if (answer > 0)
                {
                    var line = "";
                    Console.WriteLine("What Event is {0} playing? (cancel to cancel)", ((Hunter)answer).Name());
                    var eventBeingPlayed = Event.None;
                    while (eventBeingPlayed != Event.AdvancePlanning && eventBeingPlayed != Event.EscapeRoute &&
                           eventBeingPlayed != Event.HeroicLeap && line.ToLower() != "cancel")
                    {
                        line = Console.ReadLine();
                        eventBeingPlayed = Enumerations.GetEventFromString(line);
                    }
                    if (line.ToLower() == "cancel")
                    {
                        answer = -1;
                    }
                    else
                    {
                        switch (eventBeingPlayed)
                        {
                            case Event.AdvancePlanning:
                                game.Hunters[answer].DiscardEvent(game, Event.AdvancePlanning);
                                if (!DraculaIsPlayingDevilishPowerToCancelEvent(game, Event.AdvancePlanning, Event.AdvancePlanning, logic, game.Hunters[answer]))
                                {
                                    Console.WriteLine("One participant of your choice has combat rolls at +1 for this combat");
                                    CheckForCardsRevealedForBeingBitten(game);
                                }
                                else
                                {
                                    Console.WriteLine("Advance Planning cancelled");
                                    CheckForCardsRevealedForBeingBitten(game);
                                }
                                break;
                            case Event.EscapeRoute:
                                game.Hunters[answer].DiscardEvent(game, Event.EscapeRoute);
                                if (!DraculaIsPlayingDevilishPowerToCancelEvent(game, Event.EscapeRoute, Event.EscapeRoute, logic, game.Hunters[answer]))
                                {
                                    Console.WriteLine("Combat cancelled", ((Hunter)answer).Name());
                                    CheckForCardsRevealedForBeingBitten(game);
                                    return false;
                                }
                                CheckForCardsRevealedForBeingBitten(game);
                                Console.WriteLine("Escape Route cancelled"); break;
                            case Event.HeroicLeap:
                                game.Hunters[answer].DiscardEvent(game, Event.HeroicLeap);
                                if (!DraculaIsPlayingDevilishPowerToCancelEvent(game, Event.HeroicLeap, Event.HeroicLeap, logic, game.Hunters[answer]))
                                {
                                    Console.WriteLine("Roll a die and enter the result");
                                    var dieRoll = 0;
                                    while (dieRoll == 0)
                                    {
                                        if (int.TryParse(Console.ReadLine(), out dieRoll))
                                        {
                                            if (dieRoll < 1 || dieRoll > 7)
                                            {
                                                dieRoll = 0;
                                            }
                                        }
                                    }
                                    game.Hunters[answer].AdjustHealth(-dieRoll);
                                    game.Dracula.AdjustBlood(-dieRoll);
                                    CheckForHunterDeath(game);
                                    CheckForCardsRevealedForBeingBitten(game);
                                    return false;
                                }
                                Console.WriteLine("Heroic Leap cancelled"); break;
                                CheckForCardsRevealedForBeingBitten(game);
                        }
                    }
                    answer = -1;
                }
            } while (answer != 0);
            answer = -1;
            if (opponent == Opponent.Dracula || opponent == Opponent.NewVampire)
            {
                Console.WriteLine("Is anyone playing Garlic at the start of this combat? 0= Nobody, {0}{1}{2}{3}", huntersInvolved.Find(h => h.Hunter == Hunter.LordGodalming) == null ? "" : "1= Lord Godalming", huntersInvolved.Find(h => h.Hunter == Hunter.DrSeward) == null ? "" : "2= Dr. Seward", huntersInvolved.Find(h => h.Hunter == Hunter.VanHelsing) == null ? "" : "3= Van Helsing", huntersInvolved.Find(h => h.Hunter == Hunter.MinaHarker) == null ? "" : "4= Mina Harker");

                while (answer == -1)
                {
                    if (int.TryParse(Console.ReadLine(), out answer))
                    {
                        if (answer < 0 || answer > 4)
                        {
                            answer = -1;
                        }
                        else if (answer != 0 && huntersInvolved.Find(h => (int)h.Hunter == answer) == null)
                        {
                            answer = -1;
                        }
                    }
                    else
                    {
                        answer = -1;
                    }
                }
                if (answer > 0)
                {
                    game.Hunters[answer].DiscardItem(game, Item.Garlic);
                    CheckForCardsRevealedForBeingBitten(game);
                    roundsWithoutEscaping = 3;
                }
            }
            if (DraculaIsPlayingTrap(game, huntersInvolved, opponent, logic))
            {
                Console.WriteLine("Dracula played Trap. All of his combat rolls are at +1 for this combat");
            }
            var rageTarget = DraculaIsPlayingRageAgainstHunter(game, huntersInvolved, logic);
            if (rageTarget != Hunter.Nobody)
            {
                Console.WriteLine("Dracula played Rage against {0} and must reveal all Items", rageTarget.Name());
                DraculaLooksAtAllHuntersItems(game, game.Hunters[(int)rageTarget]);
                var itemDiscarded = logic.ChooseItemToDiscardWithRage(game, rageTarget);
                game.Hunters[(int)rageTarget].DiscardItem(game, itemDiscarded);
                Console.WriteLine("Dracula discarded {0}", itemDiscarded.Name());
                roundsWithoutEscaping = 3;
            }
            var basicHunterCombatCards = new List<ItemCard>
            {
                new ItemCard(Item.Punch),
                new ItemCard(Item.Dodge),
                new ItemCard(Item.Escape)
            };
            var enemyCombatCards = new List<EnemyCombatCard>();
            switch (opponent)
            {
                case Opponent.MinionWithKnife:
                    enemyCombatCards.Add(EnemyCombatCard.Punch);
                    enemyCombatCards.Add(EnemyCombatCard.Dodge);
                    enemyCombatCards.Add(EnemyCombatCard.Knife); break;
                case Opponent.MinionWithKnifeAndPistol:
                    enemyCombatCards.Add(EnemyCombatCard.Punch);
                    enemyCombatCards.Add(EnemyCombatCard.Dodge);
                    enemyCombatCards.Add(EnemyCombatCard.Knife);
                    enemyCombatCards.Add(EnemyCombatCard.Pistol); break;
                case Opponent.MinionWithKnifeAndRifle:
                    enemyCombatCards.Add(EnemyCombatCard.Punch);
                    enemyCombatCards.Add(EnemyCombatCard.Dodge);
                    enemyCombatCards.Add(EnemyCombatCard.Knife);
                    enemyCombatCards.Add(EnemyCombatCard.Rifle); break;
                case Opponent.Assassin:
                    enemyCombatCards.Add(EnemyCombatCard.Punch);
                    enemyCombatCards.Add(EnemyCombatCard.Dodge);
                    enemyCombatCards.Add(EnemyCombatCard.Knife);
                    enemyCombatCards.Add(EnemyCombatCard.Pistol);
                    enemyCombatCards.Add(EnemyCombatCard.Rifle); break;
                case Opponent.Dracula:
                    enemyCombatCards.Add(EnemyCombatCard.Claws);
                    enemyCombatCards.Add(EnemyCombatCard.Dodge);
                    enemyCombatCards.Add(EnemyCombatCard.EscapeMan);
                    switch (game.TimeOfDay)
                    {
                        case TimeOfDay.Twilight:
                        case TimeOfDay.Midnight:
                        case TimeOfDay.SmallHours:
                            enemyCombatCards.Add(EnemyCombatCard.EscapeBat);
                            enemyCombatCards.Add(EnemyCombatCard.EscapeMist);
                            enemyCombatCards.Add(EnemyCombatCard.Fangs);
                            enemyCombatCards.Add(EnemyCombatCard.Mesmerize);
                            enemyCombatCards.Add(EnemyCombatCard.Strength);
                            break;
                    }
                    break;
                case Opponent.NewVampire:
                    enemyCombatCards.Add(EnemyCombatCard.Claws);
                    enemyCombatCards.Add(EnemyCombatCard.Dodge);
                    switch (game.TimeOfDay)
                    {
                        case TimeOfDay.Twilight:
                        case TimeOfDay.Midnight:
                        case TimeOfDay.SmallHours:
                            enemyCombatCards.Add(EnemyCombatCard.Fangs);
                            enemyCombatCards.Add(EnemyCombatCard.Mesmerize);
                            enemyCombatCards.Add(EnemyCombatCard.Strength);
                            break;
                    }
                    break;
            }
            var firstRound = true;
            var repelled = false;
            var continueCombat = true;
            var sisterAgathaInEffect = (opponent == Opponent.Dracula && game.HunterAlly != null && game.HunterAlly.Event == Event.SisterAgatha);
            var enemyCombatCardChosen = EnemyCombatCard.None;
            var enemyTarget = Hunter.Nobody;
            while (continueCombat)
            {
                foreach (var h in huntersInvolved)
                {
                    var itemUsedByHunterLastRound = h.LastCombatCardChosen;
                    do
                    {
                        Console.WriteLine("Which combat card is {0} using this round?", h.Hunter.Name());
                        h.LastCombatCardChosen = Enumerations.GetItemFromString(Console.ReadLine());
                    } while (h.LastCombatCardChosen == Item.None);

                    if (basicHunterCombatCards.Find(card => card.Item == h.LastCombatCardChosen) == null &&
                        h.ItemsKnownToDracula.Find(item => item.Item == h.LastCombatCardChosen) == null)
                    {
                        var itemDraculaNowKnowsAbout = game.ItemDeck.Find(card => card.Item == h.LastCombatCardChosen);
                        h.ItemsKnownToDracula.Add(itemDraculaNowKnowsAbout);
                        game.ItemDeck.Remove(itemDraculaNowKnowsAbout);
                    }
                    else if (itemUsedByHunterLastRound == h.LastCombatCardChosen && basicHunterCombatCards.Find(card => card.Item == h.LastCombatCardChosen) == null)
                    {
                        var itemDraculaAlreadyKnewAbout =
                            h.ItemsKnownToDracula.Find(card => card.Item == itemUsedByHunterLastRound);
                        if (itemDraculaAlreadyKnewAbout != null)
                        {
                            h.ItemsKnownToDracula.Remove(itemDraculaAlreadyKnewAbout);
                        }
                        if (h.ItemsKnownToDracula.Find(card => card.Item == itemUsedByHunterLastRound) == null)
                        {
                            var itemDraculaNowKnowsAbout =
                                game.ItemDeck.Find(card => card.Item == h.LastCombatCardChosen);
                            h.ItemsKnownToDracula.Add(itemDraculaNowKnowsAbout);
                            game.ItemDeck.Remove(itemDraculaNowKnowsAbout);
                        }
                        h.ItemsKnownToDracula.Add(itemDraculaAlreadyKnewAbout);
                    }
                }
                enemyCombatCardChosen = logic.ChooseCombatCardAndTarget(game, huntersInvolved, enemyCombatCards,
                    firstRound, out enemyTarget, enemyCombatCardChosen, repelled, sisterAgathaInEffect,
                    roundsWithoutEscaping);
                roundsWithoutEscaping--;
                var bloodCost = false;
                if (sisterAgathaInEffect &&
                    (enemyCombatCardChosen == EnemyCombatCard.Fangs ||
                     enemyCombatCardChosen == EnemyCombatCard.EscapeBat ||
                     enemyCombatCardChosen == EnemyCombatCard.EscapeMan ||
                     enemyCombatCardChosen == EnemyCombatCard.EscapeMist))
                {
                    game.Dracula.AdjustBlood(-2);
                    bloodCost = true;
                }
                Console.WriteLine("{0} used {1} against {2}{3}", opponent.Name(), enemyCombatCardChosen.Name(),
                    enemyTarget.Name(), bloodCost ? " at a cost of 2 blood" : "");
                var line = "";
                var index = 0;
                do
                {
                    Console.WriteLine("What was the outcome? 1= Continue 2= Repel 3= Item destroyed or Event discarded 4= End");
                    line = Console.ReadLine();
                    if (int.TryParse(line, out index))
                    {
                        if (index < 1 || index > 4)
                        {
                            index = 0;
                        }
                    }
                } while (index == 0);
                switch (index)
                {
                    case 1: break;
                    case 2:
                        repelled = true; break;
                    case 3:
                        HunterPlayer hunterToDiscardCard = null;
                        if (huntersInvolved.Count == 1)
                        {
                            hunterToDiscardCard = huntersInvolved.First();
                        }
                        else
                        {
                            var hunterIndex = 0;
                            do
                            {
                                Console.Write("Whose card is being discarded? ");
                                foreach (var h in huntersInvolved)
                                {
                                    Console.Write("{0}= {1} ", (int)h.Hunter, h.Hunter.Name());
                                }
                                line = Console.ReadLine();
                                if (int.TryParse(line, out hunterIndex))
                                {
                                    foreach (var h in huntersInvolved)
                                    {
                                        if ((int)h.Hunter == hunterIndex)
                                        {
                                            hunterToDiscardCard = h;
                                            break;
                                        }
                                    }
                                }
                            } while (hunterToDiscardCard == null);
                        }
                        var itemDestroyed = Item.None;
                        var eventDiscarded = Event.None;
                        while (itemDestroyed == Item.None && eventDiscarded == Event.None)
                        {
                            Console.WriteLine("What card was discarded?");
                            line = Console.ReadLine();
                            itemDestroyed = Enumerations.GetItemFromString(line);
                            eventDiscarded = Enumerations.GetEventFromString(line);
                        }
                        if (itemDestroyed != Item.None)
                        {
                            hunterToDiscardCard.DiscardItem(game, itemDestroyed);
                        }
                        else if (eventDiscarded != Event.None)
                        {
                            hunterToDiscardCard.DiscardEvent(game, eventDiscarded);
                        }
                        break;
                    case 4:
                        continueCombat = false; break;
                }
                firstRound = false;
            }
            var health = -1;
            foreach (var h in huntersInvolved)
            {
                Console.WriteLine("How much health does {0} have now?", h.Hunter.Name());
                do
                {
                    if (int.TryParse(Console.ReadLine(), out health))
                    {
                        health = Math.Max(0, Math.Min(h.MaxHealth, health));
                        Console.WriteLine(health);
                    }
                } while (health == -1);
                h.AdjustHealth(health - h.Health);
            }
            if (opponent == Opponent.Dracula)
            {
                Console.WriteLine("How much blood does Dracula have now?");
                do
                {
                    if (int.TryParse(Console.ReadLine(), out health))
                    {
                        health = Math.Max(0, Math.Min(15, health));
                        Console.WriteLine(health);
                    }
                } while (health == -1);
                game.Dracula.AdjustBlood(health - game.Dracula.Blood);
            }
            Console.WriteLine("Did {0} win? (An end result is a no)", huntersInvolved.Count() > 1 ? "the Hunters" : huntersInvolved.First().Hunter.Name());
            string input;
            do
            {
                input = Console.ReadLine();
            } while (!"yes".StartsWith(input.ToLower()) && !"no".StartsWith(input.ToLower()));
            if ("yes".StartsWith(input.ToLower()))
            {
                if (opponent == Opponent.NewVampire)
                {
                    game.AdjustVampires(-1);
                }
                Console.WriteLine("Don't forget to register any cards discarded, such as Great Strength used to prevent health loss, Events due to enemy Knife wounds, Items consumed, etc.");
                return true;
            }
            if (opponent == Opponent.Dracula)
            {
                switch (enemyCombatCardChosen)
                {
                    case EnemyCombatCard.Mesmerize:
                        Console.WriteLine("{0} is bitten and must discard all Items!", enemyTarget.Name());
                        if (!HunterPlayingGreatStrengthToCancelBite(game, enemyTarget, logic))
                        {
                            game.Hunters[(int)enemyTarget].AdjustBites(1);
                        }
                        while (game.Hunters[(int)enemyTarget].ItemCount > 0)
                        {
                            var line = "";
                            var itemDiscarded = Item.None;
                            do
                            {
                                Console.WriteLine("What is the name of the Item being discarded?");
                                line = Console.ReadLine();
                                itemDiscarded = Enumerations.GetItemFromString(line);
                            } while (itemDiscarded == Item.None);
                            game.Hunters[(int)enemyTarget].DiscardItem(game, itemDiscarded);
                        }
                        CheckForHunterDeath(game); break;
                    case EnemyCombatCard.Fangs:
                        Console.WriteLine("{0} is bitten!", enemyTarget.Name());
                        if (!HunterPlayingGreatStrengthToCancelBite(game, enemyTarget, logic))
                        {
                            game.Hunters[(int)enemyTarget].AdjustBites(1);
                        }
                        CheckForHunterDeath(game);
                        goto case EnemyCombatCard.EscapeBat;
                    case EnemyCombatCard.EscapeBat:
                        Console.WriteLine("Dracula escaped in the form of a bat");
                        Location destination = logic.ChooseEscapeAsBatDestination(game);
                        game.Dracula.EscapeAsBat(game, destination);
                        logic.AddEscapeAsBatCardToAllTrails(game);
                        int position = -1;
                        if (game.HuntersAt(destination).Any() || destination == Location.CastleDracula)
                        {
                            position = game.Dracula.RevealCardInTrailWithLocation(destination);
                            logic.EliminateTrailsThatDoNotContainLocationAtPosition(game, destination, position);
                        }
                        else
                        {
                            logic.EliminateTrailsThatHaveHuntersAtPosition(game, game.Dracula.CurrentLocationPosition);
                        }
                        break;
                }
            }
            Console.WriteLine("Don't forget to register any cards discarded, such as Great Strength used to prevent health loss or Items due to enemy Knife wounds");
            foreach (HunterPlayer h in huntersInvolved)
            {
                h.LastCombatCardChosen = Item.None;
            }
            return false;
        }
示例#2
0
        /// <summary>
        /// Allows Dracula to take his turn
        /// </summary>
        /// <param name="game">The GameState</param>
        /// <param name="logic">The artificial intelligence component</param>
        private static void EndHunterTurn(GameState game, DecisionMaker logic)
        {
            game.AdvanceTimeTracker();
            logic.UpdateStrategy(game);
            bool firstMove = true;
            var power = Power.None;
            Location destination;
            destination = logic.ChooseDestinationAndPower(game, out power);

            var catacombsSlotsCleared = logic.ChooseWhichCatacombsCardsToDiscard(game, destination);
            if (catacombsSlotsCleared.Count() > 0)
            {
                Console.Write("Dracula discarded cards from Catacombs positions: ");
                foreach (var i in catacombsSlotsCleared)
                {
                    Console.Write("{0} ", i + 1);
                }
                Console.WriteLine("");
                game.Dracula.DiscardCatacombsCards(game, catacombsSlotsCleared);
            }
            if (game.DraculaAlly != null && game.DraculaAlly.Event == Event.QuinceyPMorris)
            {
                var victim = logic.ChooseVictimForQuinceyPMorris(game);
                Console.WriteLine("Dracula is targetting {0} with Quincey P. Morris", victim.Name());
                Console.WriteLine("What Item does {0} have? 0= Nothing, 1= Crucifix, 2= Heavenly Host", victim.Name());
                var answer = -1;
                while (answer == -1)
                {
                    if (int.TryParse(Console.ReadLine(), out answer))
                    {
                        if (answer < 0 || answer > 2)
                        {
                            answer = -1;
                        }
                    }
                }
                switch (answer)
                {
                    case 0:
                        Console.WriteLine("{0} loses 1 health", victim.Name());
                        game.Hunters[(int)victim].AdjustHealth(-1);
                        CheckForHunterDeath(game); break;
                    case 1:
                        Console.WriteLine("Health loss cancelled");
                        AddItemCardToDraculaKnownCardsIfNotAlreadyKnown(game, game.Hunters[(int)victim], Item.Crucifix); break;
                    case 2:
                        Console.WriteLine("Health loss cancelled");
                        AddItemCardToDraculaKnownCardsIfNotAlreadyKnown(game, game.Hunters[(int)victim], Item.HeavenlyHost); break;
                }
            }
            var eventPlayed = Event.None;
            var numberOfMoves = 1;
            do
            {
                var devilishPowerTarget = DevilishPowerTarget.None;
                var roadBlock1 = Location.Nowhere;
                var roadBlock2 = Location.Nowhere;
                var roadBlockType = ConnectionType.None;
                eventPlayed = logic.ChooseEventCardToPlayAtStartOfDraculaTurn(game, out devilishPowerTarget,
                    out roadBlock1, out roadBlock2, out roadBlockType);
                if (eventPlayed != Event.None)
                {
                    Console.WriteLine("Dracula played {0}", eventPlayed.Name());
                    game.Dracula.DiscardEvent(eventPlayed, game.EventDiscard);
                    if (HunterPlayingGoodLuckToCancelDraculaEvent(game, eventPlayed, eventPlayed, logic) > 0)
                    {
                        Console.WriteLine("{0} cancelled", eventPlayed.Name());
                    }
                    else
                    {
                        switch (eventPlayed)
                        {
                            case Event.DevilishPower:
                                switch (devilishPowerTarget)
                                {
                                    case DevilishPowerTarget.HeavenlyHost1:
                                        Console.WriteLine("Heavenly Host discarded from {0}", game.HeavenlyHostLocation1);
                                        game.HeavenlyHostLocation1 = Location.Nowhere; break;
                                    case DevilishPowerTarget.HeavenlyHost2:
                                        Console.WriteLine("Heavenly Host discarded from {0}", game.HeavenlyHostLocation2);
                                        game.HeavenlyHostLocation2 = Location.Nowhere; break;
                                    case DevilishPowerTarget.HunterAlly:
                                        Console.WriteLine("{0} discarded from play", game.HunterAlly.Event.Name());
                                        game.EventDiscard.Add(game.HunterAlly);
                                        game.HunterAlly = null; break;
                                }
                                break;
                            case Event.UnearthlySwiftness:
                                numberOfMoves = 2; break;
                            case Event.TimeRunsShort:
                                game.RegressTimeTracker(); break;
                            case Event.Roadblock:
                                game.RoadBlockLocation1 = roadBlock1;
                                game.RoadBlockLocation2 = roadBlock2;
                                game.RoadBlockConnectionType = roadBlockType;
                                Console.WriteLine("Dracula placed the roadblock token on the {0} between {1} and {2}", roadBlockType, roadBlock1, roadBlock2);
                                break;
                        }
                    }
                }
            } while (eventPlayed != Event.None);

            var cardsDroppedOffTrail = new List<DraculaCardSlot>();
            for (var i = 0; i < numberOfMoves; i++)
            {
                if (!firstMove)
                {
                    destination = logic.ChooseDestinationAndPower(game, out power);
                }
                firstMove = false;
                if (destination == Location.Nowhere && power == Power.None)
                {
                    Console.WriteLine("Dracula is cornered by his own trail and has no valid moves");
                    game.Dracula.TakePunishmentForCheating(game);
                    return;
                }
                int doubleBackSlot = -1;
                bool disembarked = game.Map.TypeOfLocation(game.Dracula.CurrentLocation) == LocationType.Sea && game.Map.TypeOfLocation(destination) != LocationType.Sea;
                var cardDroppedOffTrail = game.Dracula.MoveTo(destination, power, out doubleBackSlot);
                if (doubleBackSlot > -1)
                {
                    Console.WriteLine("Dracula Doubled Back to the location in slot {0}", doubleBackSlot + 1);
                    logic.AddDoubleBackToAllPossibleTrails(game, doubleBackSlot);
                }
                if (cardDroppedOffTrail != null)
                {
                    cardsDroppedOffTrail.Add(cardDroppedOffTrail);
                }
                if (power == Power.DarkCall || power == Power.Feed)
                {
                    logic.AddPowerCardToAllPossibleTrails(game, power);
                }
                else if (power == Power.Hide)
                {
                    logic.AddOrangeBackedCardToAllPossibleTrails(game);
                }
                else if (power == Power.WolfForm)
                {
                    logic.AddWolfFormToAllPossibleTrails(game);
                    game.Dracula.AdjustBlood(-1);
                }
                else if (power == Power.None && (game.Map.TypeOfLocation(destination) == LocationType.SmallCity ||
                    game.Map.TypeOfLocation(destination) == LocationType.LargeCity))
                {
                    if (disembarked)
                    {
                        logic.AddDisembarkedCardToAllPossibleTrails(game);
                    }
                    else
                    {
                        logic.AddOrangeBackedCardToAllPossibleTrails(game);
                    }
                }
                if (game.Map.TypeOfLocation(destination) == LocationType.Sea)
                {
                    if (power != Power.DoubleBack)
                    {
                        logic.AddBlueBackedCardToAllPossibleTrails(game);
                    }
                    if ((!game.Dracula.LostBloodFromSeaMovementLastTurn || game.HunterAlly != null && game.HunterAlly.Event == Event.RufusSmith))
                    {
                        game.Dracula.AdjustBlood(-1);
                        game.Dracula.LostBloodFromSeaMovementLastTurn = true;
                    }
                    else
                    {
                        game.Dracula.LostBloodFromSeaMovementLastTurn = false;
                    }
                }
                if (!game.HuntersAt(game.Dracula.CurrentLocation).Any() && game.Map.TypeOfLocation(game.Dracula.CurrentLocation) != LocationType.Sea)
                {
                    logic.EliminateTrailsThatHaveHuntersAtPosition(game, game.Dracula.CurrentLocationPosition);
                }
                else if (game.HuntersAt(game.Dracula.CurrentLocation).Any() && game.Map.TypeOfLocation(game.Dracula.CurrentLocation) != LocationType.Sea)
                {
                    game.Dracula.Trail[0].DraculaCards.First().IsRevealed = true;
                    logic.EliminateTrailsThatDoNotContainLocationAtPosition(game, game.Dracula.Trail[0].DraculaCards.First().Location, 0);
                }
            }
            switch (power)
            {
                case Power.WolfForm:
                    game.Dracula.AdjustBlood(-1); break;
                case Power.Feed:
                    game.Dracula.AdjustBlood(1); break;
                case Power.DarkCall:
                    game.Dracula.AdjustBlood(-2);
                    for (int i = 0; i < 10; i++)
                    {
                        game.Dracula.DrawEncounter(game.EncounterPool);
                    }
                    while (game.Dracula.EncounterHand.Count() > game.Dracula.EncounterHandSize)
                    {
                        game.Dracula.DiscardEncounterTile(game, logic.ChooseEncounterTileToDiscardFromEncounterHand(game));
                    }
                    break;
            }
            if (game.Dracula.CurrentLocation == game.Dracula.LocationWhereHideWasUsed && power == Power.DoubleBack &&
                game.Dracula.LocationWhereHideWasUsed != Location.Nowhere)
            {
                int position = game.Dracula.RevealHideCard();
                Console.WriteLine("Dracula used Double Back to return to the location where he previously used Hide. Hide was at position {0}.", position + 1);
                logic.EliminateTrailsThatDoNotContainHideAtPosition(game, position);
            }
            CheckForJonathanHarker(game, logic);
            if (game.Map.TypeOfLocation(game.Dracula.CurrentLocation) != LocationType.Sea && !game.HuntersAt(game.Dracula.CurrentLocation).Any())
            {
                switch (power)
                {
                    case Power.Hide:
                    case Power.None:
                    case Power.WolfForm:
                        game.Dracula.PlaceEncounterTileOnCard(logic.ChooseEncounterTileToPlaceOnDraculaCardSlot(game, game.Dracula.Trail[0]), game.Dracula.Trail[0]); break;
                    case Power.DoubleBack:
                        if (game.Dracula.Trail[0].EncounterTiles.Count() > 1)
                        {
                            var encounterTileToDiscard = logic.ChooseEncounterTileToDiscardFromDoubleBackedCatacombsLocation(game);
                            game.Dracula.DiscardEncounterTileFromCardSlot(encounterTileToDiscard, game.Dracula.Trail[0], game.EncounterPool);
                        }
                        break;
                    case Power.DarkCall:
                        for (int i = 0; i < 10; i++)
                        {
                            game.Dracula.DrawEncounter(game.EncounterPool);
                        }
                        while (game.Dracula.EncounterHand.Count() > game.Dracula.EncounterHandSize)
                        {
                            game.Dracula.DiscardEncounterTile(game, logic.ChooseEncounterTileToDiscardFromEncounterHand(game));
                        }
                        break;
                }
            }
            else if (game.Map.TypeOfLocation(game.Dracula.CurrentLocation) != LocationType.Sea && game.HuntersAt(game.Dracula.CurrentLocation).Any())
            {
                DrawGameState(game);
                var huntersAttacked = new List<HunterPlayer>();
                foreach (var h in game.Hunters)
                {
                    if (h != null && h.CurrentLocation == game.Dracula.CurrentLocation)
                    {
                        huntersAttacked.Add(h);
                    }
                }
                Console.WriteLine("Dracula attacks {0}{1}!", huntersAttacked.First().Hunter.Name(), huntersAttacked.Count > 1 ? " et al" : "");
                ResolveCombat(game, huntersAttacked, Opponent.Dracula, logic);
            }
            DealWithDroppedOffCardSlots(game, cardsDroppedOffTrail, logic);
            while (game.Dracula.EncounterHand.Count() < game.Dracula.EncounterHandSize)
            {
                game.Dracula.DrawEncounter(game.EncounterPool);
            }
        }
示例#3
0
 /// <summary>
 /// Resolves the Evasion Event card
 /// </summary>
 /// <param name="game">The GameState</param>
 /// <param name="logic">The artificial intelligence component</param>
 private static void PlayEvasion(GameState game, DecisionMaker logic)
 {
     Console.WriteLine("Dracula played Evasion");
     if (HunterPlayingGoodLuckToCancelDraculaEvent(game, Event.Evasion, Event.Evasion, logic) > 0)
     {
         Console.WriteLine("Evasion cancelled");
         return;
     }
     var destination = logic.ChooseWhereToEvadeTo(game);
     int doubleBackSlot = -1;
     var cardDroppedOffTrail = game.Dracula.MoveTo(destination, Power.None, out doubleBackSlot);
     logic.AddEvasionCardToTrail(game);
     if (game.HuntersAt(destination).Any())
     {
         game.Dracula.RevealCardAtPosition(0);
         logic.EliminateTrailsThatDoNotContainLocationAtPosition(game, destination, 0);
     }
     else
     {
         logic.EliminateTrailsThatHaveHuntersAtPosition(game, 0);
     }
     if (doubleBackSlot > -1)
     {
         Console.WriteLine("Dracula Doubled Back to the location in slot {0}", doubleBackSlot + 1);
     }
     if (cardDroppedOffTrail != null)
     {
         DealWithDroppedOffCardSlots(game, new List<DraculaCardSlot> { cardDroppedOffTrail }, logic);
     }
     if (game.Dracula.Trail[0].EncounterTiles.Count == 0 && !game.HuntersAt(destination).Any())
     {
         game.Dracula.PlaceEncounterTileOnCard(
             logic.ChooseEncounterTileToPlaceOnDraculaCardSlot(game, game.Dracula.Trail[0]),
             game.Dracula.Trail[0]);
     }
 }
示例#4
0
        public Location ChooseDestinationAndPower(GameState game, out Power power)
        {
            Location destination;
            if ((game.Dracula.AdvanceMoveLocation != Location.Nowhere && !game.LocationIsBlocked(game.Dracula.AdvanceMoveLocation)) || game.Dracula.AdvanceMovePower != Power.None)
            {
                power = game.Dracula.AdvanceMovePower;
                destination = game.Dracula.AdvanceMoveLocation;
                game.Dracula.AdvanceMoveLocation = Location.Nowhere;
                game.Dracula.AdvanceMovePower = Power.None;
                return destination;
            }
            var currentNumberOfPossibleCurrentLocations = NumberOfPossibleCurrentLocations;
            var currentActualTrail = GetActualTrail(game);
            var possibleMoves = GetPossibleMovesFromTrail(game, currentActualTrail);
            var possibleCurrentOrangeBackedLocations = new List<Location>();
            foreach (var trail in PossibilityTree)
            {
                possibleCurrentOrangeBackedLocations.AddRange(GetPossibleCurrentLocationsFromPossibilityTree(AddOrangeBackedCardToTrail(game, trail)));
            }
            var possibleCurrentBlueBackedLocations = new List<Location>();
            foreach (var trail in PossibilityTree)
            {
                possibleCurrentBlueBackedLocations.AddRange(GetPossibleCurrentLocationsFromPossibilityTree(AddBlueBackedCardToTrail(game, trail)));
            }
            var possibleWolfFormLocations = new List<Location>();
            foreach (var trail in PossibilityTree)
            {
                possibleCurrentBlueBackedLocations.AddRange(GetPossibleCurrentLocationsFromPossibilityTree(AddWolfFormCardToTrail(game, trail)));
            }
            var uniquePossibleCurrentOrangeBackedLocations = new List<Location>();
            var uniquePossibleCurrentBlueBackedLocations = new List<Location>();
            var uniquePossibleWolfFormLocations = new List<Location>();
            foreach (var location in possibleCurrentOrangeBackedLocations)
            {
                if (!uniquePossibleCurrentOrangeBackedLocations.Contains(location))
                {
                    uniquePossibleCurrentOrangeBackedLocations.Add(location);
                }
            }
            foreach (var location in possibleCurrentBlueBackedLocations)
            {
                if (!uniquePossibleCurrentBlueBackedLocations.Contains(location))
                {
                    uniquePossibleCurrentBlueBackedLocations.Add(location);
                }
            }
            foreach (var location in possibleWolfFormLocations)
            {
                if (!uniquePossibleWolfFormLocations.Contains(location))
                {
                    uniquePossibleWolfFormLocations.Add(location);
                }
            }

            var numberOfPossibleOrangeBackedLocationsThatWouldBeRevealed = uniquePossibleCurrentOrangeBackedLocations.Count(loc => game.HuntersAt(loc).Any());

            var numberOfPossibleLocationsAfterMove = new List<int>();
            foreach (var move in possibleMoves)
            {
                if ((game.HuntersAt(move.Location).Any() && game.Map.TypeOfLocation(move.Location) != LocationType.Sea) || move.Location == Location.CastleDracula)
                {
                    numberOfPossibleLocationsAfterMove.Add(1);
                }
                else
                {
                    if (move.Power == Power.None || move.Power == Power.Hide)
                    {
                        if (move.CardBack == CardBack.Orange)
                        {
                            numberOfPossibleLocationsAfterMove.Add(uniquePossibleCurrentOrangeBackedLocations.Count() - numberOfPossibleOrangeBackedLocationsThatWouldBeRevealed);
                        }
                        else if (move.CardBack == CardBack.Blue)
                        {
                            numberOfPossibleLocationsAfterMove.Add(uniquePossibleCurrentBlueBackedLocations.Count());
                        }
                    }
                    else if (move.Power == Power.Feed || move.Power == Power.DarkCall)
                    {
                        numberOfPossibleLocationsAfterMove.Add(currentNumberOfPossibleCurrentLocations);
                    }
                    else if (move.Power == Power.DoubleBack)
                    {
                        var doubleBackSlot = GetIndexOfLocationInTrail(move.Location, currentActualTrail);
                        var uniquePossibleDoubleBackLocations = new List<Location>();
                        foreach (var trail in PossibilityTree)
                        {
                            if (DoubleBackToPositionIsValidForTrail(game, trail, doubleBackSlot) && !uniquePossibleDoubleBackLocations.Contains(trail[doubleBackSlot].Location))
                            {
                                uniquePossibleDoubleBackLocations.Add(trail[doubleBackSlot].Location);
                            }
                        }
                        numberOfPossibleLocationsAfterMove.Add(uniquePossibleDoubleBackLocations.Count() - uniquePossibleDoubleBackLocations.Count(loc => game.HuntersAt(loc).Any()));
                    }
                    else if (move.Power == Power.WolfForm)
                    {
                        numberOfPossibleLocationsAfterMove.Add(uniquePossibleWolfFormLocations.Count() - uniquePossibleWolfFormLocations.Count(loc => game.HuntersAt(loc).Any()));
                    }
                }
            }

            var numberOfMovesUntilDeadEnd = new List<int>();
            var deadEndMoves = GetPossibleMovesThatLeadToDeadEnds(game, currentActualTrail, possibleMoves, numberOfMovesUntilDeadEnd);
            int turnsUntilTrailCleared = GetNumberOfTurnsUntilTrailCleared(game);
            int index;
            int randomNumber;
            List<PossibleTrailSlot> shortList;
            switch (Strategy)
            {
                case Strategy.Sneaky:
                    var distancesFromNearestHunter = new List<int>();
                    var currentDistanceFromHunters = game.GetDistanceToClosestHunter(game.Dracula.CurrentLocation, true);
                    foreach (var move in possibleMoves)
                    {
                        if (move.Location != Location.Nowhere)
                        {
                            distancesFromNearestHunter.Add(game.GetDistanceToClosestHunter(move.Location, true));
                            GC.Collect();
                        }
                        else
                        {
                            distancesFromNearestHunter.Add(currentDistanceFromHunters);
                        }
                    }
                    var chancesToSelectMove = new List<int>();
                    index = -1;
                    foreach (var move in possibleMoves)
                    {
                        index++;
                        var deadEndIndex = deadEndMoves.FindIndex(m => m.Location == move.Location && m.Power == move.Power);
                        if (deadEndIndex > -1 && turnsUntilTrailCleared > numberOfMovesUntilDeadEnd[deadEndIndex])
                        {
                            chancesToSelectMove.Add(1);
                        }
                        else
                        {
                            chancesToSelectMove.Add((int)(Math.Pow(numberOfPossibleLocationsAfterMove[index] * distancesFromNearestHunter[index], CHANCETOSELECTSCALAR) * PercentageDifferenceInLikelihoodOfDraculaDeath(game.Dracula.Blood, move.Power)));
                        }
                    }
                    int totalCombinations = 0;
                    foreach (int i in chancesToSelectMove)
                    {
                        totalCombinations += i;
                    }
                    randomNumber = new Random().Next(0, totalCombinations);
                    index = -1;
                    int count = 0;
                    foreach (int i in chancesToSelectMove)
                    {
                        index++;
                        count += i;
                        if (count > randomNumber)
                        {
                            power = possibleMoves[index].Power;
                            return possibleMoves[index].Location;
                        }
                    }
                    power = possibleMoves[0].Power;
                    return possibleMoves[0].Location;
                case Strategy.Aggressive:
                    var distancesFromVictim = new List<int>();
                    var currentDistanceFromVictim = game.GetDistanceToHunter(victim);
                    foreach (var move in possibleMoves)
                    {
                        if (move.Location != Location.Nowhere)
                        {
                            distancesFromVictim.Add(game.GetDistanceToHunter(victim));
                            GC.Collect();
                        }
                        else
                        {
                            distancesFromVictim.Add(currentDistanceFromVictim);
                        }
                    }
                    int shortestDistanceToVictim = distancesFromVictim.First();
                    foreach (var i in distancesFromVictim)
                    {
                        if (i < shortestDistanceToVictim)
                        {
                            shortestDistanceToVictim = i;
                        }
                    }
                    shortList = new List<PossibleTrailSlot>();
                    index = -1;
                    foreach (PossibleTrailSlot move in possibleMoves)
                    {
                        index++;
                        if (distancesFromVictim[index] == shortestDistanceToVictim)
                        {
                            shortList.Add(move);
                        }
                    }
                    randomNumber = new Random().Next(0, shortList.Count());
                    power = shortList[randomNumber].Power;
                    return shortList[randomNumber].Location;
                case Strategy.FleeToCastleDracula:
                    var distancesToCastleDracula = new List<int>();
                    var currentDistanceFromCastleDracula = game.DistanceByRoadOrSeaBetween(game.Dracula.CurrentLocation, Location.CastleDracula, false);
                    foreach (var move in possibleMoves)
                    {
                        if (move.Location != Location.Nowhere)
                        {
                            distancesToCastleDracula.Add(game.DistanceByRoadOrSeaBetween(move.Location, Location.CastleDracula, false));
                            GC.Collect();
                        }
                        else
                        {
                            distancesToCastleDracula.Add(currentDistanceFromCastleDracula);
                        }
                    }
                    int shortestDistanceToCastleDracula = distancesToCastleDracula.First();
                    foreach (int i in distancesToCastleDracula)
                    {
                        if (i < shortestDistanceToCastleDracula)
                        {
                            shortestDistanceToVictim = i;
                        }
                    }
                    shortList = new List<PossibleTrailSlot>();
                    index = -1;
                    foreach (PossibleTrailSlot move in possibleMoves)
                    {
                        index++;
                        if (distancesToCastleDracula[index] == shortestDistanceToCastleDracula)
                        {
                            shortList.Add(move);
                        }
                    }
                    randomNumber = new Random().Next(0, shortList.Count());
                    power = shortList[randomNumber].Power;
                    return shortList[randomNumber].Location;

            }

            int rand = new Random().Next(0, possibleMoves.Count());
            power = possibleMoves[rand].Power;
            return possibleMoves[rand].Location;
        }
示例#5
0
 public void InitialisePossibilityTree(GameState game)
 {
     PossibilityTree.Clear();
     List<Location> allLocations = Enumerations.GetAllLocations();
     foreach (Location location in allLocations)
     {
         if (!game.HuntersAt(location).Any() && game.Map.TypeOfLocation(location) != LocationType.Sea && game.Map.TypeOfLocation(location) != LocationType.Castle && game.Map.TypeOfLocation(location) != LocationType.Hospital)
         {
             PossibilityTree.Add(new PossibleTrailSlot[6] { new PossibleTrailSlot(location, Power.None, game.TimeOfDay, game.Map.TypeOfLocation(location) == LocationType.Sea ? CardBack.Blue : CardBack.Orange), null, null, null, null, null });
         }
     }
 }
示例#6
0
 public void AddEvasionCardToTrail(GameState game)
 {
     List<PossibleTrailSlot[]> newPossibilityTree = new List<PossibleTrailSlot[]>();
     List<Location> allCities = new List<Location>();
     List<Location> allLocations = Enumerations.GetAllLocations();
     foreach (Location loc in allLocations)
     {
         if (game.Map.TypeOfLocation(loc) == LocationType.SmallCity || game.Map.TypeOfLocation(loc) == LocationType.LargeCity)
         {
             allCities.Add(loc);
         }
     }
     foreach (PossibleTrailSlot[] trail in PossibilityTree)
     {
         foreach (Location location in allCities)
         {
             if (!game.HuntersAt(location).Any() && !TrailContainsLocation(trail, location) && !game.CatacombsContainsLocation(location))
             {
                 PossibleTrailSlot[] newPossibleTrail = new PossibleTrailSlot[6];
                 for (int i = 5; i > 0; i--)
                 {
                     newPossibleTrail[i] = trail[i - 1];
                 }
                 newPossibleTrail[0] = new PossibleTrailSlot(location, Power.None, game.TimeOfDay, CardBack.Orange);
                 newPossibilityTree.Add(newPossibleTrail);
             }
         }
     }
     PossibilityTree = newPossibilityTree;
     if (PossibilityTree.Count() == 0)
     {
         Console.WriteLine("Dracula stopped believing he exists after running AddEvasionCardToTrail");
         PossibilityTree.Add(GetActualTrail(game));
     }
 }
示例#7
0
 public void EliminateTrailsThatHaveHuntersAtPosition(GameState game, int position)
 {
     var newPossibilityTree = new List<PossibleTrailSlot[]>();
     foreach (var trail in PossibilityTree)
     {
         if (!game.HuntersAt(trail[position].Location).Any())
         {
             newPossibilityTree.Add(trail);
         }
     }
     PossibilityTree = newPossibilityTree;
     if (PossibilityTree.Count() == 0)
     {
         Console.WriteLine("Dracula stopped believing he exists after running EliminateTrailsThatHaveHuntersAtPosition");
         PossibilityTree.Add(GetActualTrail(game));
     }
 }
示例#8
0
 public Location ChooseWhereToEvadeTo(GameState game)
 {
     var allLocations = Enumerations.GetAllLocations();
     List<Location> locationsToExclude = new List<Location>();
     foreach (Location location in allLocations)
     {
         if ((game.Map.TypeOfLocation(location) != LocationType.SmallCity && game.Map.TypeOfLocation(location) != LocationType.LargeCity) || game.HuntersAt(location).Any() || game.Dracula.TrailContains(location))
         {
             locationsToExclude.Add(location);
         }
     }
     foreach (Location location in locationsToExclude)
     {
         allLocations.Remove(location);
     }
     List<int> distancesToNearestHunter = new List<int>();
     foreach (Location location in allLocations)
     {
         distancesToNearestHunter.Add(game.GetDistanceToClosestHunter(location, true));
     }
     int totalDistanceWeights = 0;
     for (int i = 0; i < distancesToNearestHunter.Count(); i++)
     {
         distancesToNearestHunter[i] *= distancesToNearestHunter[i];
         totalDistanceWeights += distancesToNearestHunter[i];
     }
     int randomNumber = new Random().Next(0, totalDistanceWeights);
     int count = 0;
     int index = -1;
     foreach (int distance in distancesToNearestHunter)
     {
         index++;
         count += distance;
         if (count > randomNumber)
         {
             break;
         }
     }
     return allLocations[index];
 }