private void MoveDroidToSecurityCheckpoint(Droid droid, ShipGraph shipGraph) { var(path, _) = GraphSearch.Dijkstra(shipGraph, droid.Room, "== Security Checkpoint =="); foreach (var nextRoom in path) { droid.TakeDoor((Direction)shipGraph.GetDoorDirection(droid.Room, nextRoom)); } }
private ShipGraph ExploreAndTakeItems(Droid droid) { var shipGraph = new ShipGraph(); shipGraph.AddRoom(droid); var unexploredRooms = new HashSet <string> { droid.Room }; var path = new List <Direction>(); while (unexploredRooms.Any()) { var lastRoom = droid.Room; if (unexploredRooms.Contains(droid.Room)) { droid.TakeItems(droid.FloorItems.Except(blacklistItems)); foreach (var door in shipGraph.GetUnexploredDoorsOf(droid.Room)) { droid.TakeDoor(door); if (droid.Room != lastRoom) { if (!shipGraph.ContainsNode(droid.Room)) { shipGraph.AddRoom(droid); unexploredRooms.Add(droid.Room); } shipGraph.AddDoorKnowledge(lastRoom, droid.Room, door); droid.TakeDoor(door.Opposite()); } } unexploredRooms.Remove(lastRoom); } else { var neighbours = shipGraph.Neighbours(droid.Room).Select(node => node.nb); var unexploredNextToCurrent = unexploredRooms.Intersect(neighbours); Direction door; if (unexploredNextToCurrent.Any()) { var nextRoom = unexploredNextToCurrent.First(); var direction = shipGraph.GetDoorDirection(droid.Room, nextRoom); door = (Direction)direction; path.Add(door); } else { door = path.Last().Opposite(); path.RemoveAt(path.Count - 1); } droid.TakeDoor(door); } } return(shipGraph); }
public void SetConnectableObjects(List <GameObject> objects) { shipGraph = new ShipGraph(); shipGraph.Initialize(objects); }
private string BreachSecurity(Droid droid, ShipGraph shipGraph) { var pressurePlate = shipGraph.GetUnexploredDoorsOf(droid.Room).First(); string password = "******"; var allItems = droid.Inventory; droid.DropItems(allItems); //Try each item individually //Remember items that are too heavy these are useless var uselessItems = new HashSet <string>(); foreach (var item in allItems) { droid.TakeItem(item); var weightAdjustment = TryBreach(); if (weightAdjustment == RequiredWeightAdjustment.None) { return(password); } else if (weightAdjustment == RequiredWeightAdjustment.Lighter) { uselessItems.Add(item); } droid.DropItem(item); } var remainingItems = allItems.Except(uselessItems); droid.TakeItems(remainingItems); //Try removing each item individually //Remember which items make the droid too light when dropped (these are essential) var essentialItems = new HashSet <string>(); foreach (var item in remainingItems) { droid.DropItem(item); var weightAdjustment = TryBreach(); if (weightAdjustment == RequiredWeightAdjustment.None) { return(password); } else if (weightAdjustment != RequiredWeightAdjustment.Lighter) { essentialItems.Add(item); } droid.TakeItem(item); } var undecidedItems = remainingItems.Except(essentialItems); droid.DropItems(undecidedItems); //Try all combinations of remaining items //(if this is an extremely large number of combinations I suggest using a priori algorithm instead, but in practice this is not needed) var itemCombinations = SetHelper.Subsets(undecidedItems); foreach (var combination in itemCombinations) { droid.TakeItems(combination); var weightAdjustment = TryBreach(); if (weightAdjustment == RequiredWeightAdjustment.None) { return(password); } droid.DropItems(combination); } RequiredWeightAdjustment TryBreach() { droid.TakeDoor(pressurePlate); var responseLines = droid.LastResponse.Split('\n', StringSplitOptions.RemoveEmptyEntries); var weightMessage = responseLines[4]; if (weightMessage == "A loud, robotic voice says \"Alert! Droids on this ship are heavier than the detected value!\" and you are ejected back to the checkpoint.") { return(RequiredWeightAdjustment.Heavier); } if (weightMessage == "A loud, robotic voice says \"Alert! Droids on this ship are lighter than the detected value!\" and you are ejected back to the checkpoint.") { return(RequiredWeightAdjustment.Lighter); } password = responseLines[6].Split(' ')[11]; return(RequiredWeightAdjustment.None); } throw new Exception("breach failed"); }
public void SetConnectableObjects(List<GameObject> objects) { shipGraph = new ShipGraph(); shipGraph.Initialize (objects); }