public Location ChooseDestinationForWildHorses(GameState game) { var possibleDestination = game.Map.LocationsConnectedByRoadTo(game.Dracula.CurrentLocation); List<int> distances = new List<int>(); int longestDistance = 0; foreach (Location location in possibleDestination) { distances.Add(game.DistanceByRoadOrSeaBetween(location, Location.CastleDracula, false)); if (distances.Last() > longestDistance) { longestDistance = distances.Last(); } } List<Location> shortList = new List<Location>(); int index = -1; foreach (Location location in possibleDestination) { index++; if (distances[index] == longestDistance) { shortList.Add(location); } } return shortList[new Random().Next(0, shortList.Count())]; }
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; }
private Location ChooseSetupForRoadBlock(GameState game, out Location roadBlock2, out ConnectionType roadBlockType) { // if agressive, block nearest hunter's retreat if (Strategy == Strategy.Aggressive) { // choose the closest hunter, or a random one of the closest ones List<HunterPlayer> closestHunters = game.HuntersClosestTo(game.Dracula.CurrentLocation); HunterPlayer target = closestHunters[new Random().Next(0, closestHunters.Count())]; // choose a location connected to that hunter's location by road that is further away from dracula than their current location List<Location> connectedLocations = game.Map.LocationsConnectedByRoadTo(target.CurrentLocation); List<int> distances = new List<int>(); int longestDistance = 0; foreach (Location location in connectedLocations) { distances.Add(game.DistanceByRoadOrSeaBetween(location, game.Dracula.CurrentLocation, false)); if (distances.Last() > longestDistance) { longestDistance = distances.Last(); } } List<Location> shortlist = new List<Location>(); int index = -1; foreach (int dist in distances) { index++; if (dist == longestDistance) { shortlist.Add(connectedLocations[index]); } } // put the roadblock there roadBlock2 = shortlist[new Random().Next(0, shortlist.Count())]; roadBlockType = ConnectionType.Road; return target.CurrentLocation; } else if (Strategy == Strategy.Sneaky && NumberOfPossibleCurrentLocations > 4) { // choose two hunters that are not in the same location int distanceBetweenLordGodalmingAndDrSeward = game.DistanceByRoadBetween(game.Hunters[(int)Hunter.LordGodalming].CurrentLocation, game.Hunters[(int)Hunter.DrSeward].CurrentLocation, true); int distanceBetweenLordGodalmingAndVanHelsing = game.DistanceByRoadBetween(game.Hunters[(int)Hunter.LordGodalming].CurrentLocation, game.Hunters[(int)Hunter.VanHelsing].CurrentLocation, true); int distanceBetweenLordGodalmingAndMinaHarker = game.DistanceByRoadBetween(game.Hunters[(int)Hunter.LordGodalming].CurrentLocation, game.Hunters[(int)Hunter.MinaHarker].CurrentLocation, true); int distanceBetweenDrSewardAndVanHelsing = game.DistanceByRoadBetween(game.Hunters[(int)Hunter.DrSeward].CurrentLocation, game.Hunters[(int)Hunter.VanHelsing].CurrentLocation, true); int distanceBetweenDrSewardAndMinaHarker = game.DistanceByRoadBetween(game.Hunters[(int)Hunter.DrSeward].CurrentLocation, game.Hunters[(int)Hunter.MinaHarker].CurrentLocation, true); int distanceBetweenVanHelsingAndMinaHarker = game.DistanceByRoadBetween(game.Hunters[(int)Hunter.VanHelsing].CurrentLocation, game.Hunters[(int)Hunter.MinaHarker].CurrentLocation, true); HunterPlayer firstHunter = null; HunterPlayer secondHunter = null; int shortestNonZeroDistance = 99; if (distanceBetweenLordGodalmingAndDrSeward > 0 && distanceBetweenLordGodalmingAndDrSeward < shortestNonZeroDistance) { shortestNonZeroDistance = distanceBetweenLordGodalmingAndDrSeward; firstHunter = game.Hunters[(int)Hunter.LordGodalming]; secondHunter = game.Hunters[(int)Hunter.DrSeward]; } if (distanceBetweenLordGodalmingAndVanHelsing > 0 && distanceBetweenLordGodalmingAndVanHelsing < shortestNonZeroDistance) { shortestNonZeroDistance = distanceBetweenLordGodalmingAndVanHelsing; firstHunter = game.Hunters[(int)Hunter.LordGodalming]; secondHunter = game.Hunters[(int)Hunter.VanHelsing]; } if (distanceBetweenLordGodalmingAndMinaHarker > 0 && distanceBetweenLordGodalmingAndMinaHarker < shortestNonZeroDistance) { shortestNonZeroDistance = distanceBetweenLordGodalmingAndMinaHarker; firstHunter = game.Hunters[(int)Hunter.LordGodalming]; secondHunter = game.Hunters[(int)Hunter.MinaHarker]; } if (distanceBetweenDrSewardAndVanHelsing > 0 && distanceBetweenDrSewardAndVanHelsing < shortestNonZeroDistance) { shortestNonZeroDistance = distanceBetweenDrSewardAndVanHelsing; firstHunter = game.Hunters[(int)Hunter.DrSeward]; secondHunter = game.Hunters[(int)Hunter.VanHelsing]; } if (distanceBetweenDrSewardAndMinaHarker > 0 && distanceBetweenDrSewardAndMinaHarker < shortestNonZeroDistance) { shortestNonZeroDistance = distanceBetweenDrSewardAndMinaHarker; firstHunter = game.Hunters[(int)Hunter.DrSeward]; secondHunter = game.Hunters[(int)Hunter.MinaHarker]; } if (distanceBetweenVanHelsingAndMinaHarker > 0 && distanceBetweenVanHelsingAndMinaHarker < shortestNonZeroDistance) { shortestNonZeroDistance = distanceBetweenVanHelsingAndMinaHarker; firstHunter = game.Hunters[(int)Hunter.VanHelsing]; secondHunter = game.Hunters[(int)Hunter.MinaHarker]; } if (firstHunter != null) { // figure out a road that is between them if (shortestNonZeroDistance == 1) { roadBlock2 = secondHunter.CurrentLocation; roadBlockType = ConnectionType.Road; return firstHunter.CurrentLocation; } if (shortestNonZeroDistance == 2) { List<Location> firstHuntersConnections = game.Map.LocationsConnectedByRoadTo(firstHunter.CurrentLocation); List<Location> secondHuntersConnections = game.Map.LocationsConnectedByRoadTo(secondHunter.CurrentLocation); List<Location> overlap = new List<Location>(); foreach (Location location in firstHuntersConnections) { if (secondHuntersConnections.Contains(location)) { overlap.Add(location); } } // block that road roadBlock2 = overlap[new Random().Next(0, overlap.Count())]; roadBlockType = ConnectionType.Road; if (new Random().Next(0, 1) == 0) { return firstHunter.CurrentLocation; } else { return secondHunter.CurrentLocation; } } } } else if ((Strategy == Strategy.Sneaky && NumberOfPossibleCurrentLocations < 5) || Strategy == Strategy.FleeToCastleDracula) { // choose the closest hunter, or a random one of the closest ones List<HunterPlayer> closestHunters = game.HuntersClosestTo(game.Dracula.CurrentLocation); HunterPlayer target = closestHunters[new Random().Next(0, closestHunters.Count())]; // choose a location connected to that hunter's location by road that is closer to dracula than their current location List<Location> connectedLocations = game.Map.LocationsConnectedByRoadTo(target.CurrentLocation); List<int> distances = new List<int>(); int shortestDistance = 100; foreach (Location location in connectedLocations) { distances.Add(game.DistanceByRoadOrSeaBetween(location, game.Dracula.CurrentLocation, false)); if (distances.Last() < shortestDistance) { shortestDistance = distances.Last(); } } List<Location> shortlist = new List<Location>(); int index = -1; foreach (int dist in distances) { index++; if (dist == shortestDistance) { shortlist.Add(connectedLocations[index]); } } // put the roadblock there roadBlock2 = shortlist[new Random().Next(0, shortlist.Count())]; roadBlockType = ConnectionType.Road; return target.CurrentLocation; } var allLocations = Enumerations.GetAllLocations(); var allCities = new List<Location>(); foreach (var loc in allLocations) { if (game.Map.TypeOfLocation(loc) == LocationType.SmallCity || game.Map.TypeOfLocation(loc) == LocationType.LargeCity) { allCities.Add(loc); } } var roadBlock1 = allCities[new Random().Next(0, allCities.Count())]; var citiesConnectedToRoadBlock1ByRoad = game.Map.LocationsConnectedByRoadTo(roadBlock1); var citiesConnectedToRoadBlock1ByTrain = game.Map.LocationsConnectedByTrainTo(roadBlock1); var citiesConnectedToRoadBlock1 = new List<Location>(); citiesConnectedToRoadBlock1.AddRange(citiesConnectedToRoadBlock1ByRoad); citiesConnectedToRoadBlock1.AddRange(citiesConnectedToRoadBlock1ByTrain); roadBlock2 = citiesConnectedToRoadBlock1[new Random().Next(0, citiesConnectedToRoadBlock1.Count())]; if (citiesConnectedToRoadBlock1ByRoad.Contains(roadBlock2)) { if (citiesConnectedToRoadBlock1ByTrain.Contains(roadBlock2)) { if (new Random().Next(0, 2) == 0) { roadBlockType = ConnectionType.Road; } else { roadBlockType = ConnectionType.Rail; } } else { roadBlockType = ConnectionType.Road; } } else { roadBlockType = ConnectionType.Rail; } return roadBlock1; }
public Location ChooseBatsDestination(GameState game, Hunter hunterWithEncounter) { List<Location> possibleDestinations = game.Map.LocationsConnectedByRoadTo(game.Hunters[(int)hunterWithEncounter].CurrentLocation); List<int> distances = new List<int>(); int totalDistanceWeights = 0; foreach (Location location in possibleDestinations) { distances.Add(game.DistanceByRoadOrSeaBetween(location, game.Dracula.CurrentLocation, false)); totalDistanceWeights += distances.Last(); } if (Strategy == Strategy.Sneaky) { int randomNumber = new Random().Next(0, totalDistanceWeights); int count = 0; int index = -1; foreach (int distance in distances) { index++; count += distance; if (count > randomNumber) { return possibleDestinations[index]; } } } else if (Strategy == Strategy.Aggressive) { List<Location> shortList = new List<Location>(); int shortestDistance = distances.First(); foreach (int distance in distances) { if (distance < shortestDistance) { shortestDistance = distance; } } int index = -1; foreach (int distance in distances) { index++; if (distance == shortestDistance) { shortList.Add(possibleDestinations[index]); } } return shortList[new Random().Next(0, shortList.Count())]; } return possibleDestinations[new Random().Next(0, possibleDestinations.Count())]; }
public Location ChoosePortToGoToAfterStormySeas(GameState game) { var validPorts = game.Map.GetPortsAdjacentTo(game.Dracula.CurrentLocation); if (!validPorts.Any()) { return Location.Nowhere; } List<int> distances = new List<int>(); if (Strategy == Strategy.Sneaky) { int totalDistanceWeights = 0; foreach (Location location in validPorts) { int distance = game.GetDistanceToClosestHunter(location, false); distances.Add(distance * distance); totalDistanceWeights += distances.Last(); } int randomNumber = new Random().Next(0, totalDistanceWeights); int count = 0; int index = -1; foreach (int dist in distances) { index++; count += dist; if (count > randomNumber) { return validPorts[index]; } } } else if (Strategy == Strategy.Aggressive) { foreach (Location location in validPorts) { int distance = game.GetDistanceToClosestHunter(location, false); } int shortestDistance = distances.First(); foreach (int dist in distances) { if (dist < shortestDistance) { shortestDistance = dist; } } List<Location> shortList = new List<Location>(); int index = -1; foreach (Location port in validPorts) { index++; if (distances[index] == shortestDistance) { shortList.Add(port); } } return shortList[new Random().Next(0, shortList.Count())]; } else if (Strategy == Strategy.FleeToCastleDracula) { foreach (Location location in validPorts) { int distance = game.DistanceByRoadOrSeaBetween(location, Location.CastleDracula, false); } int shortestDistance = distances.First(); foreach (int dist in distances) { if (dist < shortestDistance) { shortestDistance = dist; } } List<Location> shortList = new List<Location>(); int index = -1; foreach (Location port in validPorts) { index++; if (distances[index] == shortestDistance) { shortList.Add(port); } } return shortList[new Random().Next(0, shortList.Count())]; } return validPorts[new Random().Next(0, validPorts.Count())]; }