private static void CreateNodes(int width, int height, ConcreteGraph graph, IPassability passability) { for (var top = 0; top < height; ++top) { for (var left = 0; left < width; ++left) { var nodeId = GetNodeIdFromPos(left, top, width); var position = new Position(left, top); int movementCost; var isObstacle = !passability.CanEnter(position, out movementCost); var info = new ConcreteNodeInfo(isObstacle, movementCost, new Position(left, top)); graph.AddNode(nodeId, info); } } }
private static void CreateEdges(ConcreteGraph graph, int width, int height, TileType tileType) { for (var top = 0; top < height; ++top) { for (var left = 0; left < width; ++left) { var nodeId = GetNodeByPos(graph, left, top, width).NodeId; AddEdge(graph, nodeId, left, top - 1, width, height); AddEdge(graph, nodeId, left, top + 1, width, height); AddEdge(graph, nodeId, left - 1, top, width, height); AddEdge(graph, nodeId, left + 1, top, width, height); if (tileType == TileType.Octile) { AddEdge(graph, nodeId, left + 1, top + 1, width, height, true); AddEdge(graph, nodeId, left - 1, top + 1, width, height, true); AddEdge(graph, nodeId, left + 1, top - 1, width, height, true); AddEdge(graph, nodeId, left - 1, top - 1, width, height, true); } else if (tileType == TileType.OctileUnicost) { AddEdge(graph, nodeId, left + 1, top + 1, width, height); AddEdge(graph, nodeId, left - 1, top + 1, width, height); AddEdge(graph, nodeId, left + 1, top - 1, width, height); AddEdge(graph, nodeId, left - 1, top - 1, width, height); } else if (tileType == TileType.Hex) { if (left % 2 == 0) { AddEdge(graph, nodeId, left + 1, top - 1, width, height); AddEdge(graph, nodeId, left - 1, top - 1, width, height); } else { AddEdge(graph, nodeId, left + 1, top + 1, width, height); AddEdge(graph, nodeId, left - 1, top + 1, width, height); } } } } }
static void Main(string[] args) { IEnumerable <Bag> rules = File.ReadLines("../../../input.txt") .Select(Bag.Parse); ConcreteGraph <string> contains = new ConcreteGraph <string>(); foreach (Bag bag in rules) { foreach (string content in bag.Contents) { contains.AddEdge(bag.Colour, content); } } ConcreteGraph <string> containedIn = contains.ReverseGraph(); int possibilities = 0; containedIn.BfsFrom("shiny gold", (container, _) => possibilities++); Console.WriteLine(possibilities - 1); // "shiny gold" alone is included in the count from BFS }
public static ConcreteNode GetNodeByPos(ConcreteGraph graph, int x, int y, int width) { return(graph.GetNode(GetNodeIdFromPos(x, y, width))); }