public Searchspace GenerateSolution(SolutionParameters parameters) { if (parameters == null) { throw new ArgumentNullException("parameters"); } var result = new Searchspace(new Vector2(parameters.Width, parameters.Height)); var buildings = parameters.BuildingPositions.Select((kvp) => new ProductionBuilding(kvp.Key.Recipe, kvp.Key.Amount, kvp.Key.Building, kvp.Value.Item1, kvp.Value.Item2)); foreach (var building in buildings) { result = result.AddComponent(building); } var belts = new Dictionary <Item, List <RoutingCoordinate> >(); List <Tuple <IStep, Item, bool> > todo = parameters.Connections.ToList(); while (todo.Count != 0) { Preview = result; var connection = todo[0]; todo.RemoveAt(0); var isDestination = connection.Item3; var prev = result; if (belts.ContainsKey(connection.Item2)) { IEnumerable <RoutingCoordinate> sources = new RoutingCoordinate[] { }; IEnumerable <RoutingCoordinate> destinations = new RoutingCoordinate[] { }; //TODO: fix itemAmount //TODO: fix fluids if (connection.Item2.ItemType == ItemType.Solid) { if (isDestination) { sources = belts[connection.Item2]; destinations = BuildingToPlaceables(connection.Item1, parameters); } else { sources = BuildingToPlaceables(connection.Item1, parameters); destinations = belts[connection.Item2]; } result = SolidRouter.Route(new ItemAmount(connection.Item2, 1), result, sources, destinations); } } else { var firstMatching = todo.Where((t) => t.Item2 == connection.Item2 && t.Item3 != connection.Item3).First(); todo.Remove(firstMatching); var both = new Tuple <IStep, Item, bool>[] { connection, firstMatching }; var source = both.Where((c) => c.Item3 == false).First(); var destination = both.Where((c) => c.Item3 == true).First(); if (connection.Item2.ItemType == ItemType.Solid) { var sources = BuildingToPlaceables(source.Item1, parameters); var destinations = BuildingToPlaceables(destination.Item1, parameters); result = SolidRouter.Route(new ItemAmount(connection.Item2, 1), result, sources, destinations); } if (connection.Item2.ItemType == ItemType.Fluid) { var sources = BuildingToPipes(source.Item1, parameters, connection.Item2); var destinations = BuildingToPipes(destination.Item1, parameters, connection.Item2); result = FluidRouter.Route(new ItemAmount(connection.Item2, 1), result, sources, destinations); } } if (!belts.ContainsKey(connection.Item2)) { belts[connection.Item2] = new List <RoutingCoordinate>(); } belts[connection.Item2].AddRange(RoutesToCoords(prev, result)); } return(result); }