public static Image Draw(this Searchspace space) { int cellSize = 32; Bitmap result = new Bitmap((int)space.Size.X * cellSize, (int)space.Size.Y * cellSize); using (var g = Graphics.FromImage(result)) { g.Clear(Color.Black); using (var buildingBrush = new SolidBrush(Color.LightGray)) using (var flowPen = new Pen(Color.Red)) using (var hiddenFlow = new Pen(Color.LightSalmon)) using (var rotationPen = new Pen(Color.DarkGreen)) { foreach (var item in space.Buildings.Where((i) => !(i is PlacedItem))) { var center = (item.Position + item.Size / 2) * cellSize; var currentFlowPen = hiddenFlow; if (item.Building.IconPath != null) { var destination = new Rectangle((int)item.Position.X * cellSize, (int)item.Position.Y * cellSize, (int)item.Size.X * cellSize, (int)item.Size.Y * cellSize); g.FillRectangle(buildingBrush, destination); var icon = Image.FromFile(item.Building.IconPath); g.DrawImage(icon, destination); var direction = item.Rotation.ToVector() / 2 * cellSize + center; g.DrawLine(rotationPen, (float)center.X, (float)center.Y, (float)direction.X, (float)direction.Y); currentFlowPen = flowPen; } foreach (var prev in item.Previous) { var building = prev as IPhysicalBuilding; if (building != null) { var from = (building.Position + building.Size / 2) * cellSize; g.DrawLine(currentFlowPen, (float)from.X, (float)from.Y, (float)center.X, (float)center.Y); } } } } } return(result); }
public void RouteSink() { SolidRouter r = new SolidRouter( new Building("belt"), new Building("beltground3"), new Building("beltground2"), new Building("beltground1"), new Building("inserter1"), new Building("inserter2"), new Building("longInserter"), new Building("basic-splitter"), new SolutionGrader() ); Building assembler = new Building("assembler"); assembler.Size = new Vector2(3, 3); assembler.IngredientCount = 3; assembler.ProductionSpeed = 1; assembler.AddCraftingCategory("test"); Recipe recipe = new Recipe("dummy"); recipe.CraftingCategory = "test"; Item item = new Item("dummy"); Library l = new Library(); l.AddBuilding(assembler); l.AddItem(item); l.AddRecipe(recipe); l.Initialize(); Searchspace s = new Searchspace(new Vector2(13, 10)); var physical = new ProductionBuilding(recipe, 1, assembler, new Vector2(7, 3), BuildingRotation.North); s = s.AddComponent(physical); var dict = new Dictionary <ProductionStep, Tuple <Vector2, BuildingRotation> >(); dict.Add(physical, new Tuple <Vector2, BuildingRotation>(physical.Position, physical.Rotation)); var param = new SolutionParameters(13, 10, ImmutableDictionary <SourceStep, Vector2> .Empty, ImmutableDictionary <SinkStep, Vector2> .Empty, dict.ToImmutableDictionary(), ImmutableList <Tuple <IStep, Item, bool> > .Empty); var dests = SolutionGenerator.BuildingToPlaceables(physical, param); var result = r.Route(new ItemAmount(item, 0.01), s, dests, new RoutingCoordinate[] { new RoutingCoordinate(new Vector2(7, 9), RoutingCoordinate.CoordinateType.Belt, BuildingRotation.South) }); }
public void SearchstateCollisions() { var state = new Searchspace(new Vector2(4, 4)); var item = new Item("test"); var building = new Building("test"); building.Size = 2 * Vector2.One; var flow = new FlowBuilding(new ItemAmount(item, 1), building, Vector2.One, BuildingRotation.North); var newState = state.AddRoute(flow); Assert.AreEqual(0, state.CalculateCollisions(Vector2.One).Count()); Assert.AreEqual(1, newState.CalculateCollisions(Vector2.One).Count()); Assert.AreEqual(0, newState.CalculateCollisions(Vector2.Zero).Count()); Assert.AreEqual(1, newState.CalculateCollisions(Vector2.One, 2 * Vector2.One).Count()); }
public double CalculateCost(Searchspace space, SolutionGrader grader) { var cost = base.CalculateCost(space, grader); var pipeBuilding = Building; BuildingRotation[] rotations = new BuildingRotation[] { BuildingRotation.North, BuildingRotation.East, BuildingRotation.South, BuildingRotation.West }; foreach (var rotation in rotations) { var neighbors = space.CalculateCollisions(Position + rotation.ToVector()); var misMatch = neighbors.Where((b) => b.Building == pipeBuilding && b is FlowBuilding).Cast <FlowBuilding>() .Where((f) => f.Item.Item != Item.Item); cost += misMatch.Count() * grader.TouchLeakCost; } return(cost); }
public void UndergroundCollisions() { var item = new Item("test"); var lib = new Library(); lib.AddItem(item); lib.Initialize(); var flow = new UndergroundFlow(new ItemAmount(item, 1), Vector2.One, Depth.Normal, BuildingRotation.South); var grader = new SolutionGrader(); var space = new Searchspace(new Vector2(4, 4)); space = space.AddRoute(flow); Assert.AreEqual(0, flow.CalculateCost(space, grader)); var flow2 = new UndergroundFlow(new ItemAmount(item, 1), Vector2.One, Depth.Fast, BuildingRotation.South); var newSpace = space.AddRoute(flow2); Assert.AreEqual(0, flow.CalculateCost(newSpace, grader)); flow2 = new UndergroundFlow(new ItemAmount(item, 1), Vector2.One, Depth.Normal, BuildingRotation.South); newSpace = space.AddRoute(flow2); Assert.IsTrue(flow.CalculateCost(newSpace, grader) > 0); flow2 = new UndergroundFlow(new ItemAmount(item, 1), Vector2.One, Depth.Normal, BuildingRotation.North); newSpace = space.AddRoute(flow2); Assert.IsTrue(flow.CalculateCost(newSpace, grader) > 0); flow2 = new UndergroundFlow(new ItemAmount(item, 1), Vector2.One, Depth.Normal, BuildingRotation.East); newSpace = space.AddRoute(flow2); Assert.AreEqual(0, flow.CalculateCost(newSpace, grader)); var building = new PhysicalFlowBuilding(new ItemAmount(item, 1), new Building("test1"), Vector2.One, BuildingRotation.North); newSpace = space.AddRoute(building); Assert.AreEqual(0, flow.CalculateCost(newSpace, grader)); }
public static IEnumerable <FlowBuilding> SolidPointLeaks(this FlowBuilding building, Vector2 offset, Searchspace space) { var forward = space.CalculateCollisions(building.Position + building.Rotation.ToVector()).ToList(); var belts = forward.OfType <Belt>(); var splitters = forward.OfType <Splitter>(); var ground = forward.OfType <GroundToUnderground>().Where((g) => g.FlowDepth != Depth.Fluid); var filteredBelts = belts.Where((b) => b.Item.Item != building.Item.Item); var filteredSplitters = splitters.Where((s) => s.Item.Item != building.Item.Item && s.Rotation == building.Rotation); var filteredGround = ground.Where((g) => !g.IsUpward && g.Rotation == building.Rotation.Invert() && g.Item.Item != building.Item.Item); return(filteredBelts.Cast <FlowBuilding>() .Concat(filteredSplitters) .Concat(filteredGround)); }
public static IEnumerable <FlowBuilding> SolidLeaks(this FlowBuilding building, Searchspace space) { if (building is Splitter) { var offset = new BuildingRotation[] { BuildingRotation.East, BuildingRotation.South, BuildingRotation.East, BuildingRotation.South, }; return(SolidPointLeaks(building, Vector2.Zero, space) .Concat(SolidPointLeaks(building, offset[(int)building.Rotation].ToVector(), space))); } else { return(SolidPointLeaks(building, Vector2.Zero, space)); } }