/// <summary> /// Resolves an Encounter of Ambush for a group of Hunters /// </summary> /// <param name="game">The GameState</param> /// <param name="huntersInvolved">A list of Hunters involved in the Encounter</param> /// <param name="logic">The artificial intelligence component</param> /// <returns>True if the Hunters can continue resolving Encounters</returns> private static bool ResolveAmbush(GameState game, List<Hunter> huntersInvolved, DecisionMaker logic) { game.Dracula.DrawEncounter(game.EncounterPool); game.Dracula.DiscardEncounterTile(game, logic.ChooseEncounterTileToDiscardFromEncounterHand(game)); return true; }
/// <summary> /// Resolves an Encounter on a group of Hunters /// </summary> /// <param name="game">The GameState</param> /// <param name="encounterTileBeingResolved">The Encounter being resolved</param> /// <param name="trailIndex">The Index of the Trail slot (0-5), or Catacombs slot (6-8) where the Encounter is being resolved, or -1 if being resolved from Dracula's hand</param> /// <returns>True if the Hunters can continue resolving Encounters</returns> private static bool ResolveEncounterTile(GameState game, EncounterTile encounterTileBeingResolved, List<Hunter> huntersInvolved, DecisionMaker logic, int trailIndex) { Console.WriteLine("Resolving {0} with {1}{2}", encounterTileBeingResolved.Encounter.Name(), huntersInvolved.First().Name(), huntersInvolved.Count() > 1 ? " and his group" : ""); var continueEncounters = true; var discardEncounterTile = true; foreach (var h in huntersInvolved) { Console.WriteLine("Will {0} play Secret Weapon?", h.Name()); var line = ""; do { line = Console.ReadLine(); } while (!"yes".StartsWith(line.ToLower()) && !"no".StartsWith(line.ToLower())); if ("yes".StartsWith(line.ToLower())) { game.Hunters[(int)h].DiscardEvent(game, Event.SecretWeapon); if (DraculaIsPlayingDevilishPowerToCancelEvent(game, Event.SecretWeapon, Event.SecretWeapon, logic, game.Hunters[(int)h])) { Console.WriteLine("Secret Weapon cancelled"); } else { DiscardUnknownItemFromHunter(game, game.Hunters[(int)h]); Console.WriteLine("What is the name of the Item being retrieved from the discard pile?"); var itemRetrieved = Item.None; while (itemRetrieved == Item.None) { itemRetrieved = Enumerations.GetItemFromString(Console.ReadLine()); } var itemCardRetrieved = game.ItemDiscard.Find(card => card.Item == itemRetrieved); game.ItemDiscard.Remove(itemCardRetrieved); game.Hunters[(int)h].ItemsKnownToDracula.Add(itemCardRetrieved); game.Hunters[(int)h].DrawItemCard(); } } } foreach (var h in huntersInvolved) { Console.WriteLine("Will {0} play Forewarned?", h.Name()); var line = ""; do { line = Console.ReadLine(); } while (!"yes".StartsWith(line.ToLower()) && !"no".StartsWith(line.ToLower())); if ("yes".StartsWith(line.ToLower())) { game.Hunters[(int)h].DiscardEvent(game, Event.Forewarned); if (DraculaIsPlayingDevilishPowerToCancelEvent(game, Event.SecretWeapon, Event.SecretWeapon, logic, game.Hunters[(int)h])) { Console.WriteLine("Forewarned cancelled"); } else { Console.WriteLine("Encounter cancelled"); game.EncounterPool.Add(encounterTileBeingResolved); if (trailIndex > -1) { game.Dracula.Trail[trailIndex].EncounterTiles.Remove(encounterTileBeingResolved); } return true; } } } switch (encounterTileBeingResolved.Encounter) { case Encounter.Ambush: continueEncounters = ResolveAmbush(game, huntersInvolved, logic); break; case Encounter.Assassin: continueEncounters = ResolveAssassin(game, huntersInvolved, logic); break; case Encounter.Bats: discardEncounterTile = false; game.Hunters[(int)huntersInvolved.First()].EncountersInFrontOfPlayer.Add(encounterTileBeingResolved); if (trailIndex > -1) { game.Dracula.Trail[trailIndex].EncounterTiles.Remove(encounterTileBeingResolved); } else { game.Dracula.EncounterHand.Remove(encounterTileBeingResolved); } return false; case Encounter.DesecratedSoil: continueEncounters = ResolveDesecratedSoil(game, huntersInvolved, logic); break; case Encounter.Fog: discardEncounterTile = false; game.Hunters[(int)huntersInvolved.First()].EncountersInFrontOfPlayer.Add(encounterTileBeingResolved); if (trailIndex > -1) { game.Dracula.Trail[trailIndex].EncounterTiles.Remove(encounterTileBeingResolved); } else { game.Dracula.EncounterHand.Remove(encounterTileBeingResolved); } return false; case Encounter.MinionWithKnife: continueEncounters = ResolveMinionWithKnife(game, huntersInvolved, logic); break; case Encounter.MinionWithKnifeAndPistol: continueEncounters = ResolveMinionWithKnifeAndPistol(game, huntersInvolved, logic); break; case Encounter.MinionWithKnifeAndRifle: continueEncounters = ResolveMinionWithKnifeAndRifle(game, huntersInvolved, logic); break; case Encounter.Hoax: continueEncounters = ResolveHoax(game, huntersInvolved); break; case Encounter.Lightning: continueEncounters = ResolveLightning(game, huntersInvolved); break; case Encounter.Peasants: continueEncounters = ResolvePeasants(game, huntersInvolved); break; case Encounter.Plague: continueEncounters = ResolvePlague(game, huntersInvolved); break; case Encounter.Rats: continueEncounters = ResolveRats(game, huntersInvolved); break; case Encounter.Saboteur: continueEncounters = ResolveSaboteur(game, huntersInvolved); break; case Encounter.Spy: continueEncounters = ResolveSpy(game, huntersInvolved); break; case Encounter.Thief: continueEncounters = ResolveThief(game, huntersInvolved, logic); break; case Encounter.NewVampire: var seductionPlayed = false; continueEncounters = ResolveNewVampire(game, huntersInvolved, logic, out discardEncounterTile, out seductionPlayed); if (seductionPlayed) { game.Dracula.EncounterHand.Add(encounterTileBeingResolved); while (game.Dracula.EncounterHand.Count() > game.Dracula.EncounterHandSize) { game.Dracula.DiscardEncounterTile(game, logic.ChooseEncounterTileToDiscardFromEncounterHand(game)); } if (trailIndex > -1) { game.Dracula.Trail[trailIndex].EncounterTiles.Remove(encounterTileBeingResolved); } else { game.Dracula.EncounterHand.Remove(encounterTileBeingResolved); } } break; case Encounter.Wolves: continueEncounters = ResolveWolves(game, huntersInvolved); break; default: return false; } if (discardEncounterTile) { game.EncounterPool.Add(encounterTileBeingResolved); if (trailIndex > -1) { game.Dracula.Trail[trailIndex].EncounterTiles.Remove(encounterTileBeingResolved); } else { game.Dracula.EncounterHand.Remove(encounterTileBeingResolved); } } return continueEncounters; }
/// <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); } }