예제 #1
0
파일: Program.cs 프로젝트: UncleGus/dracula
        /// <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);
            }
        }