/// <summary>Checks if the sixth card in Dracula's Trail should be revealed by Jonathan Harker</summary> /// <param name="game">The GameState</param> private static void CheckForJonathanHarker(GameState game, DecisionMaker logic) { if (game.HunterAlly != null && game.HunterAlly.Event == Event.JonathanHarker && game.Dracula.Trail[5] != null) { game.Dracula.RevealCardAtPosition(5); if (game.Dracula.Trail[5].DraculaCards.First().Location != Location.Nowhere) { logic.EliminateTrailsThatDoNotContainLocationAtPosition(game, game.Dracula.Trail[5].DraculaCards.First().Location, 5); } } }
/// <summary> /// Resolves the Telegraph Ahead Event /// </summary> /// <param name="game">The GameState</param> /// <param name="hunterPlayingEvent">The Hunter playing the Event</param> /// <param name="logic">The artificial intelligence component</param> private static void PlayTelegraphAhead(GameState game, Hunter hunterPlayingEvent, DecisionMaker logic) { foreach (var loc in game.Map.LocationsConnectedByRoadTo(game.Hunters[(int)hunterPlayingEvent].CurrentLocation)) { if (DraculaIsPlayingSensationalistPressToPreventRevealingLocation(game, loc, logic)) { Console.WriteLine("Dracula prevented a location from being revealed"); } else { int position = game.Dracula.RevealCardInTrailWithLocation(loc); if (position > -1) { Console.WriteLine("{0} revealed", loc.Name()); logic.EliminateTrailsThatDoNotContainLocationAtPosition(game, loc, position); } else { position = game.Dracula.RevealCardInCatacombsWithLocation(loc); if (position > -1) { Console.WriteLine("{0} revealed", loc.Name()); logic.EliminateTrailsThatContainLocation(game, loc); } else { logic.EliminateTrailsThatContainLocation(game, loc); } } } } }
/// <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; }
/// <summary> /// Resolves the Newspaper Reports Event or Resolve ability /// </summary> /// <param name="game">The GameState</param> /// <param name="hunterPlayingEvent">The Hunter playing the Event</param> /// <param name="logic">The artificial intelligence component</param> private static void PlayNewsPaperReports(GameState game, Hunter hunterPlayingEvent, DecisionMaker logic) { for (var i = 5; i > 0; i--) { if (game.Dracula.Trail[i] != null && game.Dracula.Trail[i].DraculaCards.First().Location != Location.Nowhere && game.Dracula.Trail[i].DraculaCards.First().Location != game.Dracula.CurrentLocation && !game.Dracula.Trail[i].DraculaCards.First().IsRevealed) { if (DraculaIsPlayingSensationalistPressToPreventRevealingLocation(game, game.Dracula.Trail[i].DraculaCards.First().Location, logic)) { Console.WriteLine("Dracula prevented a location from being revealed"); } else { game.Dracula.RevealCardAtPosition(i); logic.EliminateTrailsThatDoNotContainLocationAtPosition(game, game.Dracula.Trail[i].DraculaCards.First().Location, i); break; } } } }
/// <summary> /// Resolves the Stormy Seas Event /// </summary> /// <param name="game">The GameState</param> /// <param name="hunterPlayingEvent">The Hunter playing the Event</param> /// <param name="logic">The artificial intelligence component</param> private static void PlayStormySeas(GameState game, Hunter hunterPlayingEvent, DecisionMaker logic) { Console.WriteLine("Where is {0} playing Stormy Seas?", hunterPlayingEvent.Name()); var stormySeasLocation = Location.Nowhere; while (stormySeasLocation == Location.Nowhere || game.Map.TypeOfLocation(stormySeasLocation) != LocationType.Sea) { stormySeasLocation = Enumerations.GetLocationFromString(Console.ReadLine()); } game.StormySeasLocation = stormySeasLocation; game.StormySeasRounds = 2; if (stormySeasLocation == game.Dracula.CurrentLocation) { Console.WriteLine("Dracula was in {0}", stormySeasLocation.Name()); int position = game.Dracula.RevealCardInTrailWithLocation(stormySeasLocation); logic.EliminateTrailsThatDoNotContainLocationAtPosition(game, stormySeasLocation, position); var destination = logic.ChoosePortToGoToAfterStormySeas(game); if (destination == Location.Nowhere) { Console.WriteLine("Dracula cannot make a legal move"); game.Dracula.TakePunishmentForCheating(game); return; } int doubleBackSlot; var cardDroppedOffTrail = game.Dracula.MoveTo(destination, Power.None, out doubleBackSlot); logic.AddDisembarkedCardToAllPossibleTrails(game); if (doubleBackSlot > -1) { Console.WriteLine("Dracula Doubled Back to the location in slot {0}", doubleBackSlot + 1); } var cardsDroppedOffTrail = new List<DraculaCardSlot>(); if (cardDroppedOffTrail != null) { cardsDroppedOffTrail.Add(cardDroppedOffTrail); } if (DraculaIsPlayingSensationalistPressToPreventRevealingLocation(game, destination, logic)) { Console.WriteLine("Dracula prevented a location from being revealed"); } else { game.Dracula.RevealCardInTrailWithLocation(destination); logic.EliminateTrailsThatDoNotContainLocationAtPosition(game, destination, 0); } DealWithDroppedOffCardSlots(game, cardsDroppedOffTrail, logic); CheckForJonathanHarker(game, logic); } else { logic.EliminateTrailsThatContainLocation(game, stormySeasLocation); } }
/// <summary> /// Resolves the Hypnosis Event /// </summary> /// <param name="game">The GameState</param> /// <param name="hunterPlayingEvent">The Hunter playing the Event</param> /// <param name="logic">The artificial intelligence component</param> private static void PlayHypnosis(GameState game, Hunter hunterPlayingEvent, DecisionMaker logic) { 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; } } } switch (dieRoll) { case 1: case 2: Console.WriteLine("No effect"); break; case 3: case 4: case 5: case 6: if (DraculaIsPlayingSensationalistPressToPreventRevealingLocation(game, game.Dracula.CurrentLocation, logic)) { Console.WriteLine("Dracula prevented a location from being revealed"); } else { game.Dracula.RevealCardInTrailWithLocation(game.Dracula.CurrentLocation); logic.EliminateTrailsThatDoNotContainLocationAtPosition(game, game.Dracula.CurrentLocation, game.Dracula.CurrentLocationPosition); } game.Dracula.RevealAllVampires(); var power = Power.None; var advanceMoveLocation = logic.ChooseDestinationAndPower(game, out power); if (advanceMoveLocation == Location.Nowhere && power == Power.None) { Console.WriteLine("Dracula will have no legal moves next turn"); } else { game.Dracula.AdvanceMoveLocation = advanceMoveLocation; game.Dracula.AdvanceMovePower = power; Console.WriteLine("Dracula's next move will be to {0}{1}", game.Dracula.AdvanceMoveLocation, power == Power.None ? "" : " using " + game.Dracula.AdvanceMovePower.Name()); } break; } }
/// <summary> /// Resolves the Money Trail Event /// </summary> /// <param name="game">The GameState</param> /// <param name="hunterPlayingEvent">The Hunter playing the Event</param> /// <param name="logic">The artificial intelligence component</param> private static void PlayMoneyTrail(GameState game, Hunter hunterPlayingEvent, DecisionMaker logic) { for (var i = 5; i > 0; i--) { if (game.Dracula.Trail[i] != null && game.Map.TypeOfLocation(game.Dracula.Trail[i].DraculaCards.First().Location) == LocationType.Sea) { if (DraculaIsPlayingSensationalistPressToPreventRevealingLocation(game, game.Dracula.Trail[i].DraculaCards.First().Location, logic)) { Console.WriteLine("Dracula prevented a location from being revealed"); } else { game.Dracula.RevealCardAtPosition(i); logic.EliminateTrailsThatDoNotContainLocationAtPosition(game, game.Dracula.Trail[i].DraculaCards.First().Location, i); } } } }
/// <summary> /// Resolves the Hired Scouts Event /// </summary> /// <param name="game">The GameState</param> /// <param name="hunterPlayingEvent">The Hunter playing the Event</param> /// <param name="logic">The artificial intelligence component</param> private static void PlayHiredScouts(GameState game, Hunter hunterPlayingEvent, DecisionMaker logic) { Console.WriteLine("Name the first city"); var firstLocationToReveal = Location.Nowhere; while (firstLocationToReveal == Location.Nowhere || (game.Map.TypeOfLocation(firstLocationToReveal) != LocationType.SmallCity && game.Map.TypeOfLocation(firstLocationToReveal) != LocationType.LargeCity)) { firstLocationToReveal = Enumerations.GetLocationFromString(Console.ReadLine()); } var secondLocationToReveal = Location.Nowhere; Console.WriteLine("Name the second city"); secondLocationToReveal = Location.Nowhere; while (secondLocationToReveal == Location.Nowhere || (game.Map.TypeOfLocation(secondLocationToReveal) != LocationType.SmallCity && game.Map.TypeOfLocation(secondLocationToReveal) != LocationType.LargeCity)) { secondLocationToReveal = Enumerations.GetLocationFromString(Console.ReadLine()); } if (DraculaIsPlayingSensationalistPressToPreventRevealingLocation(game, firstLocationToReveal, logic)) { Console.WriteLine("Dracula prevented a location from being revealed"); logic.EliminateTrailsThatDoNotContainLocation(game, firstLocationToReveal); } else { var trailIndex = game.Dracula.RevealCardInTrailWithLocation(firstLocationToReveal); if (trailIndex > -1) { Console.WriteLine("{0} revealed", firstLocationToReveal.Name()); logic.EliminateTrailsThatDoNotContainLocationAtPosition(game, firstLocationToReveal, trailIndex); trailIndex = -2; } else { trailIndex = game.Dracula.RevealCardInCatacombsWithLocation(firstLocationToReveal); } if (trailIndex > -1) { Console.WriteLine("{0} revealed", firstLocationToReveal.Name()); logic.EliminateTrailsThatDoNotContainLocationAtPosition(game, firstLocationToReveal, trailIndex); game.Dracula.RevealEncountersAtPositionInTrail(trailIndex); DrawGameState(game); } else if (trailIndex == -1) { Console.WriteLine("{0} is not in Dracula's trail or Catacombs", firstLocationToReveal.Name()); logic.EliminateTrailsThatContainLocation(game, firstLocationToReveal); } } if (DraculaIsPlayingSensationalistPressToPreventRevealingLocation(game, secondLocationToReveal, logic)) { Console.WriteLine("Dracula prevented a location from being revealed"); logic.EliminateTrailsThatDoNotContainLocation(game, secondLocationToReveal); } else { var trailIndex = game.Dracula.RevealCardInTrailWithLocation(secondLocationToReveal); if (trailIndex > -1) { Console.WriteLine("{0} revealed", secondLocationToReveal.Name()); logic.EliminateTrailsThatDoNotContainLocationAtPosition(game, secondLocationToReveal, trailIndex); trailIndex = -2; } else { trailIndex = game.Dracula.RevealCardInCatacombsWithLocation(secondLocationToReveal); } if (trailIndex > -1) { Console.WriteLine("{0} revealed", secondLocationToReveal.Name()); logic.EliminateTrailsThatDoNotContainLocationAtPosition(game, secondLocationToReveal, trailIndex); game.Dracula.RevealEncountersAtPositionInTrail(trailIndex); DrawGameState(game); } else if (trailIndex == -1) { Console.WriteLine("{0} is not in Dracula's trail or Catacombs", secondLocationToReveal.Name()); logic.EliminateTrailsThatContainLocation(game, secondLocationToReveal); } } }
/// <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]); } }
/// <summary> /// Resolves the Consecrated Ground Event /// </summary> /// <param name="game">The GameState</param> /// <param name="hunterPlayingEvent">The Hunter playing the Event</param> private static void PlayConsecratedGround(GameState game, Hunter hunterPlayingEvent, DecisionMaker logic) { Console.WriteLine("Where would you like to place the Consecrated Ground marker?"); var ground = Location.Nowhere; while (ground == Location.Nowhere || ground == Location.CastleDracula || ground == Location.Galatz || ground == Location.Klausenburg || (game.Map.TypeOfLocation(ground) != LocationType.SmallCity && game.Map.TypeOfLocation(ground) != LocationType.LargeCity)) { ground = Enumerations.GetLocationFromString(Console.ReadLine()); } game.ConsecratedGroundLocation = ground; if (ground == game.Dracula.CurrentLocation) { var index = game.Dracula.RevealCardInTrailWithLocation(ground); logic.EliminateTrailsThatDoNotContainLocationAtPosition(game, ground, index); game.Dracula.RevealEncountersAtPositionInTrail(index); } else { logic.EliminateTrailsThatContainLocationAtPosition(game, ground, game.Dracula.CurrentLocationPosition); } }
/// <summary> /// Handles the entirety of a Hunter's move, including search, Encounters, combat etc. /// </summary> /// <param name="game">The GameState</param> /// <param name="hunterIndex">The index of the Hunter (and group) to move</param> /// <param name="destination">The destination of the move</param> /// <param name="logic">The artificial intelligence component</param> private static void HandleMoveOperation(GameState game, string destination, string hunterIndex, DecisionMaker logic) { var hunterMoved = Hunter.Nobody; Location originatingLocation; var trailIndex = MoveHunter(game, hunterIndex, destination, out hunterMoved, out originatingLocation, logic); if (DraculaIsPlayingCustomsSearch(game, hunterMoved, originatingLocation, logic)) { foreach (var h in game.Hunters[(int)hunterMoved].HuntersInGroup) { Console.WriteLine("{0} must discard all Items", h.Name()); while (game.Hunters[(int)h].ItemCount > 0) { DiscardUnknownItemFromHunter(game, game.Hunters[(int)h]); } } } if (trailIndex > -1 && game.Map.TypeOfLocation(game.Dracula.Trail[trailIndex].DraculaCards.First().Location) != LocationType.Sea) { game.Dracula.RevealCardAtPosition(trailIndex); logic.EliminateTrailsThatDoNotContainLocationAtPosition(game, game.Dracula.Trail[trailIndex].DraculaCards.First().Location, trailIndex); game.Dracula.RevealEncountersAtPositionInTrail(trailIndex); DraculaCardSlot slotBeingRevealed; if (trailIndex < 6) { slotBeingRevealed = game.Dracula.Trail[trailIndex]; } else { slotBeingRevealed = game.Dracula.Catacombs[trailIndex - 6]; } if (slotBeingRevealed.DraculaCards.First().Location == game.Dracula.LocationWhereHideWasUsed) { var positionRevealed = game.Dracula.RevealHideCard(); logic.EliminateTrailsThatDoNotContainHideAtPosition(game, positionRevealed); game.Dracula.RevealEncountersAtPositionInTrail(positionRevealed); } if (slotBeingRevealed.DraculaCards.First().Location == game.Dracula.CurrentLocation) { Console.WriteLine("Dracula is here!"); } else { Console.WriteLine("Dracula has been here"); } DrawGameState(game); var encounterTilesToResolve = new List<EncounterTile>(); foreach (var enc in slotBeingRevealed.EncounterTiles) { encounterTilesToResolve.Add(enc); } var hunterCanContinueToResolveEncounters = true; while (encounterTilesToResolve.Count() > 0 && hunterCanContinueToResolveEncounters) { var encounterTileBeingResolved = logic.ChooseEncounterToResolveOnSearchingHunter(game, encounterTilesToResolve, hunterMoved); hunterCanContinueToResolveEncounters = ResolveEncounterTile(game, encounterTileBeingResolved, game.Hunters[(int)hunterMoved].HuntersInGroup, logic, trailIndex); encounterTilesToResolve.Remove(encounterTileBeingResolved); } if (game.Hunters[(int)hunterMoved].CurrentLocation == game.Dracula.LocationWhereHideWasUsed) { foreach (var enc in game.Dracula.slotWhereHideCardIs().EncounterTiles) { encounterTilesToResolve.Add(enc); } } while (encounterTilesToResolve.Count() > 0 && hunterCanContinueToResolveEncounters) { var encounterTileBeingResolved = logic.ChooseEncounterToResolveOnSearchingHunter(game, encounterTilesToResolve, hunterMoved); hunterCanContinueToResolveEncounters = ResolveEncounterTile(game, encounterTileBeingResolved, game.Hunters[(int)hunterMoved].HuntersInGroup, logic, game.Dracula.PositionWhereHideCardIs()); encounterTilesToResolve.Remove(encounterTileBeingResolved); } if (slotBeingRevealed.DraculaCards.First().Location == game.Dracula.CurrentLocation && hunterCanContinueToResolveEncounters) { Console.WriteLine("Entering combat with Dracula"); if (DraculaIsPlayingWildHorses(game, logic)) { Console.WriteLine("The Wild Horses carry you away"); HandleMoveOperation(game, ((int)hunterMoved).ToString(), logic.ChooseDestinationForWildHorses(game).Name(), logic); } else { var huntersAttacking = new List<HunterPlayer>(); foreach (var h in game.Hunters[(int)hunterMoved].HuntersInGroup) { huntersAttacking.Add(game.Hunters[(int)h]); } ResolveCombat(game, huntersAttacking, Opponent.Dracula, logic); CheckForHunterDeath(game); } } } else { logic.EliminateTrailsThatContainLocation(game, game.Hunters[(int)hunterMoved].CurrentLocation); } }
/// <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); } }