public GameState() { Hunters = new HunterPlayer[5] { null, new HunterPlayer(Hunter.LordGodalming, 12, 0, 2), new HunterPlayer(Hunter.DrSeward, 10, 0, 2), new HunterPlayer(Hunter.VanHelsing, 8, 0, 3), new HunterPlayer(Hunter.MinaHarker, 8, 1, 2) }; Dracula = new Dracula(); ItemDiscard = new List<ItemCard>(); EventDiscard = new List<EventCard>(); Resolve = -1; Vampires = -1; }
/// <summary> /// Checks if a given Event card is already known by Dracula to be in a given Hunter's hand and adds it if not /// </summary> /// <param name="game">The GameState</param> /// <param name="hunterRevealingCard">The Hunter revealing the card</param> /// <param name="eventBeingRevealed">The Event being revealed</param> /// <returns>The card corresponding to the Event revealed</returns> private static EventCard AddEventCardToDraculaKnownCardsIfNotAlreadyKnown(GameState game, HunterPlayer hunterRevealingCard, Event eventBeingRevealed) { var eventCardBeingRevealed = hunterRevealingCard.EventsKnownToDracula.Find(card => card.Event == eventBeingRevealed); if (eventCardBeingRevealed == null) { eventCardBeingRevealed = game.EventDeck.Find(card => card.Event == eventBeingRevealed); game.EventDeck.Remove(eventCardBeingRevealed); hunterRevealingCard.EventsKnownToDracula.Add(eventCardBeingRevealed); } return eventCardBeingRevealed; }
/// <summary> /// Handles the situation when a Hunter must reveal all Items to Dracula /// </summary> /// <param name="game">The GameState</param> /// <param name="victim">The Hunter revealing Items</param> private static void DraculaLooksAtAllHuntersItems(GameState game, HunterPlayer victim) { game.ItemDeck.AddRange(victim.ItemsKnownToDracula); victim.ItemsKnownToDracula.Clear(); for (var i = 0; i < victim.ItemCount; i++) { Console.WriteLine("What is the name of the Item being revealed?"); var itemRevealed = Item.None; while (itemRevealed == Item.None) { itemRevealed = Enumerations.GetItemFromString(Console.ReadLine()); } AddItemCardToDraculaKnownCards(game, victim, itemRevealed); } }
/// <summary> /// Handles the situation when a Hunter must reveal all Event cards to Dracula /// </summary> /// <param name="game">The GameState</param> /// <param name="victim">The Hunter revealing Event cards</param> private static void DraculaLooksAtAllHuntersEvents(GameState game, HunterPlayer victim) { game.EventDeck.AddRange(victim.EventsKnownToDracula); victim.EventsKnownToDracula.Clear(); for (var i = 0; i < victim.EventCount; i++) { Console.WriteLine("What is the name of the Event being revealed?"); var eventRevealed = Event.None; while (eventRevealed == Event.None) { eventRevealed = Enumerations.GetEventFromString(Console.ReadLine()); } AddEventCardToDraculaKnownCards(game, victim, eventRevealed); } }
/// <summary> /// Determines if Dracula is playing Devilish Power to cancel an Event played by a Hunter /// </summary> /// <param name="game">The GameState</param> /// <param name="eventBeingPlayedNow">The Event being played now</param> /// <param name="eventInitiallyPlayed">The Event initially played at the beginning of this exchange</param> /// <param name="logic">The artificial intelligence component</param> /// <returns>True if Dracula successfully plays Devilish Power</returns> private static bool DraculaIsPlayingDevilishPowerToCancelEvent(GameState game, Event eventBeingPlayedNow, Event eventInitiallyPlayed, DecisionMaker logic, HunterPlayer hunterPlayingEvent) { if (logic.ChooseToCancelEventWithDevilishPower(game, eventBeingPlayedNow, eventInitiallyPlayed, hunterPlayingEvent)) { Console.WriteLine("Dracula is playing Devilish Power to cancel {0}", eventBeingPlayedNow.Name()); game.Dracula.DiscardEvent(Event.DevilishPower, game.EventDiscard); if (HunterPlayingGoodLuckToCancelDraculaEvent(game, Event.DevilishPower, eventInitiallyPlayed, logic) > 0) { return false; } return true; } return false; }
/// <summary> /// Adds an Event card to the list of cards known to Dracula /// </summary> /// <param name="game">The GameState</param> /// <param name="victim">The Hunter who has revealed an Event</param> /// <param name="eventRevealed">The Event revealed by the Hunter</param> private static void AddEventCardToDraculaKnownCards(GameState game, HunterPlayer victim, Event eventRevealed) { var eventCardRevealed = game.EventDeck.Find(card => card.Event == eventRevealed); victim.EventsKnownToDracula.Add(eventCardRevealed); game.EventDeck.Remove(eventCardRevealed); }
public CardType ChooseToDiscardItemFromHunterInsteadOfEvent(HunterPlayer hunterDiscardingCard) { int chanceOfDiscardingGoodLuck; int chanceOfDiscardingForewarned; int chanceOfDiscardingHeroicLeap; int chanceOfDiscardingStake; int chanceOfDiscardingCrucifix; int chanceOfDiscardingHeavenlyHost; if (hunterDiscardingCard.EventCount == 0) { chanceOfDiscardingGoodLuck = 0; chanceOfDiscardingForewarned = 0; chanceOfDiscardingHeroicLeap = 0; } else { chanceOfDiscardingGoodLuck = hunterDiscardingCard.NumberOfKnownEventsOfType(Event.GoodLuck) / hunterDiscardingCard.EventCount; chanceOfDiscardingForewarned = hunterDiscardingCard.NumberOfKnownEventsOfType(Event.Forewarned) / hunterDiscardingCard.EventCount; chanceOfDiscardingHeroicLeap = hunterDiscardingCard.NumberOfKnownEventsOfType(Event.HeroicLeap) / hunterDiscardingCard.EventCount; } if (hunterDiscardingCard.ItemCount == 0) { chanceOfDiscardingStake = 0; chanceOfDiscardingCrucifix = 0; chanceOfDiscardingHeavenlyHost = 0; } else { chanceOfDiscardingStake = hunterDiscardingCard.NumberOfKnownItemsOfType(Item.Stake) / hunterDiscardingCard.ItemCount; chanceOfDiscardingCrucifix = hunterDiscardingCard.NumberOfKnownItemsOfType(Item.Crucifix) / hunterDiscardingCard.ItemCount; chanceOfDiscardingHeavenlyHost = hunterDiscardingCard.NumberOfKnownItemsOfType(Item.HeavenlyHost) / hunterDiscardingCard.ItemCount; } if (chanceOfDiscardingCrucifix + chanceOfDiscardingForewarned + chanceOfDiscardingGoodLuck + chanceOfDiscardingHeavenlyHost + chanceOfDiscardingHeroicLeap + chanceOfDiscardingStake > 0) { if (chanceOfDiscardingCrucifix + chanceOfDiscardingHeavenlyHost + chanceOfDiscardingStake > chanceOfDiscardingForewarned + chanceOfDiscardingGoodLuck + chanceOfDiscardingHeroicLeap) { return CardType.Item; } else { return CardType.Event; } } if (hunterDiscardingCard.ItemCount > 0) { if (hunterDiscardingCard.EventCount > 0) { if (new Random().Next(0, 2) == 0) { return CardType.Item; } return CardType.Event; } return CardType.Item; } if (hunterDiscardingCard.EventCount > 0) { return CardType.Event; } return CardType.None; }
public int GetDistanceToHunter(HunterPlayer victim) { return DistanceByRoadOrSeaBetween(Dracula.CurrentLocation, victim.CurrentLocation, false); }
/// <summary> /// Handles the situation when a Hunter must reveal their next move /// </summary> /// <param name="game">The GameState</param> /// <param name="victim">The Hunter revealing their move</param> private static void HunterDeclaresNextMove(GameState game, HunterPlayer victim) { Console.WriteLine("What will be {0}'s destination next turn?", victim.Hunter.Name()); var destination = Location.Nowhere; while (destination == Location.Nowhere) { destination = Enumerations.GetLocationFromString(Console.ReadLine()); } Console.WriteLine("What will be {0}'s means of travel next turn?", victim.Hunter.Name()); var methodOfTravel = ConnectionType.None; while (methodOfTravel == ConnectionType.None) { methodOfTravel = Enumerations.GetConnectionTypeFromString(Console.ReadLine()); } victim.SetNextMoveDestination(destination); victim.SetNextMoveConnectionType(methodOfTravel); }
/// <summary> /// Checks if a given Item card is already known by Dracula to be in a given Hunter's hand and adds it if not /// </summary> /// <param name="game">The GameState</param> /// <param name="hunterRevealingCard">The Hunter revealing the card</param> /// <param name="itemBeingRevealed">The Item being revealed</param> /// <returns>The card corresponding to the Item revealed</returns> private static ItemCard AddItemCardToDraculaKnownCardsIfNotAlreadyKnown(GameState game, HunterPlayer hunterRevealingCard, Item itemBeingRevealed) { var itemCardBeingRevealed = hunterRevealingCard.ItemsKnownToDracula.Find(card => card.Item == itemBeingRevealed); if (itemCardBeingRevealed == null) { itemCardBeingRevealed = game.ItemDeck.Find(card => card.Item == itemBeingRevealed); game.ItemDeck.Remove(itemCardBeingRevealed); hunterRevealingCard.ItemsKnownToDracula.Add(itemCardBeingRevealed); } return itemCardBeingRevealed; }
/// <summary> /// Adds an Item to a Hunter's list of Items known to Dracula /// </summary> /// <param name="game">The GameState</param> /// <param name="victim">The Hunter revealing an Item</param> /// <param name="itemRevealed">The Item revealed</param> private static void AddItemCardToDraculaKnownCards(GameState game, HunterPlayer victim, Item itemRevealed) { var itemCardRevealed = game.ItemDeck.Find(card => card.Item == itemRevealed); victim.ItemsKnownToDracula.Add(itemCardRevealed); game.ItemDeck.Remove(itemCardRevealed); }
private float LikelihoodOfHunterDeath(GameState game, HunterPlayer hunter) { int numberOfBitesUntilDeath = hunter.BitesRequiredToKill - hunter.BiteCount; return Math.Max(75 / hunter.Health + 3, numberOfBitesUntilDeath == 1 ? 50 : 0); }
private bool HunterIsWorthFighting(GameState game, HunterPlayer h) { if (h.ItemsKnownToDracula.Any(card => card.Item == Item.Stake) && LikelihoodOfHunterDeath(game, h) < 75) { return false; } if (h.ItemsKnownToDracula.Any(card => card.Item == Item.Crucifix) && LikelihoodOfHunterDeath(game, h) < 50) { return false; } return true; }
public void UpdateStrategy(GameState game) { int turnsUntilDark = 0; int turnsUntilLight = 0; if ((int)game.TimeOfDay > 3) { turnsUntilLight = 7 - (int)game.TimeOfDay; } if ((int)game.TimeOfDay < 4) { turnsUntilDark = 4 - (int)game.TimeOfDay; } // if there are any hunters in range var potentialVictims = game.HuntersWithinDistanceOf(game.Dracula.CurrentLocation, turnsUntilLight); var victimsToEliminate = new List<HunterPlayer>(); foreach (HunterPlayer h in potentialVictims) { // eliminate any that have a stake if (h.LikelihoodOfHavingItemOfType(game, Item.Stake) > 0.5) { // unless they only have 1 and I have a rage card that can discard it if (h.LikelihoodOfHavingItemOfType(game, Item.Stake) < 2 && game.Dracula.EventHand.Any(card => card.Event == Event.Rage)) { // but if someone can cancel my rage card and I can't cancel their good luck if (game.Dracula.EventHand.Count(card => card.Event == Event.DevilishPower) - game.LikelihoodOfAnyHunterHavingEventOfType(Event.GoodLuck) < 0.5) { victimsToEliminate.Add(h); continue; } } else { victimsToEliminate.Add(h); continue; } } // elminate any that have Heavenly Host if (h.LikelihoodOfHavingItemOfType(game, Item.HeavenlyHost) > 0.75) { // unless they only have 1 and I have a rage card that can discard it if (h.LikelihoodOfHavingItemOfType(game, Item.HeavenlyHost) < 2 && game.Dracula.EventHand.Any(card => card.Event == Event.Rage)) { // but if someone can cancel my rage card and I can't cancel their good luck if (game.Dracula.EventHand.Count(card => card.Event == Event.DevilishPower) - game.LikelihoodOfAnyHunterHavingEventOfType(Event.GoodLuck) < 0.5) { victimsToEliminate.Add(h); continue; } } else { victimsToEliminate.Add(h); continue; } } } foreach (HunterPlayer h in victimsToEliminate) { potentialVictims.Remove(h); } potentialVictims.Clear(); // if there are any that are in the same location as someone who is not a potential victim, I don't want to attack them both foreach (HunterPlayer h in potentialVictims) { for (int i = 1; i < 5; i++) { if (!potentialVictims.Contains(game.Hunters[i]) && h.CurrentLocation == game.Hunters[i].CurrentLocation) { victimsToEliminate.Add(h); } } } foreach (HunterPlayer h in victimsToEliminate) { potentialVictims.Remove(h); } if (potentialVictims.Any()) { // if it's worth breaking cover to attack if ((NumberOfPossibleCurrentLocations < 6 && potentialVictims.Any(hunter => LikelihoodOfHunterDeath(game, hunter) > LikelihoodOfDraculaDeath(game.Dracula.Blood))) || (game.Vampires > 3 && potentialVictims.Any(hunter => LikelihoodOfHunterDeath(game, hunter) > 25))) { float highestLikelihoodOfDeath = 0; foreach (HunterPlayer hunter in potentialVictims) { if (LikelihoodOfHunterDeath(game, hunter) > highestLikelihoodOfDeath) { victim = hunter; highestLikelihoodOfDeath = LikelihoodOfHunterDeath(game, hunter); } } if (victim != null) { Strategy = Strategy.Aggressive; return; } } } if (game.Dracula.Blood < 6) { Strategy = Strategy.FleeToCastleDracula; victim = null; return; } Strategy = Strategy.Sneaky; victim = null; }
public void BeforeAll() { vanHelsing = new HunterPlayer(Hunter.VanHelsing, 10, 0, 2); }
/// <summary> /// Asks the user to name an Event and then discards it from that Hunter /// </summary> /// <param name="game">The GameState</param> /// <param name="hunter">The Hunter discarding an Event</param> private static void DiscardUnknownEventFromHunter(GameState game, HunterPlayer hunter) { Console.WriteLine("Name the Event being discarded"); var eventBeingDiscarded = Event.None; while (eventBeingDiscarded == Event.None) { eventBeingDiscarded = Enumerations.GetEventFromString(Console.ReadLine()); } hunter.DiscardEvent(game, eventBeingDiscarded); }
/// <summary> /// Asks the user to name an Item and then discards it from that Hunter /// </summary> /// <param name="game">The GameState</param> /// <param name="hunter">The Hunter discarding an Item</param> private static bool DiscardUnknownItemFromHunter(GameState game, HunterPlayer hunter) { Console.WriteLine("Name the Item being discarded (cancel to cancel)"); var itemBeingDiscarded = Item.None; var line = ""; while (itemBeingDiscarded == Item.None && line.ToLower() != "cancel") { line = Console.ReadLine(); itemBeingDiscarded = Enumerations.GetItemFromString(line); } if (line.ToLower() != "cancel") { hunter.DiscardItem(game, itemBeingDiscarded); return true; } else { Console.WriteLine("No Item discarded"); return false; } }
public float IndividualCombatScore(HunterPlayer hunter) { float individualCombatScore = 0; for (int i = 1; i < 13; i++) { individualCombatScore += hunter.LikelihoodOfHavingItemOfType(this, (Item)i) * CombatWorthOfItem((Item)i); } switch (hunter.BitesRequiredToKill - hunter.BiteCount) { case 1: individualCombatScore -= 8; break; case 3: individualCombatScore += 4; break; } return individualCombatScore; }
public bool ChooseToCancelEventWithDevilishPower(GameState game, Event eventBeingPlayedNow, Event eventInitiallyPlayed, HunterPlayer hunterPlayingEvent) { if (game.Dracula.EventHand.Find(card => card.Event == Event.DevilishPower) != null) { int randomChances = 4; if (eventInitiallyPlayed == Event.DevilishPower && game.HunterAlly != null & game.HunterAlly.Event == Event.SisterAgatha) { randomChances = 0; } switch (eventInitiallyPlayed) { case Event.Evasion: randomChances = (NumberOfPossibleCurrentLocations / 3); break; case Event.NewspaperReports: if (game.OldestUnrevealedLocationInTrail() == game.Dracula.CurrentLocation) { return false; } else { randomChances = (NumberOfPossibleCurrentLocations / 3); } break; case Event.TimeRunsShort: randomChances = 3; break; case Event.GoodLuck: randomChances = 2; break; case Event.HiredScouts: randomChances = (int)((0.75 * (NumberOfPossibleCurrentLocations - 5)) * (0.75 * (NumberOfPossibleCurrentLocations - 5))); break; } if (new Random().Next(0, randomChances) == 0) { return true; } } return false; }