public IEnumerable <FluidRouteState> NextStates(Func <Searchspace, IPhysicalBuilding, double> costFunction, Building pipeToGround, Building pipe) { if (_depth == Depth.Fluid) { Vector2 nextPos = _position + _direction.ToVector(); if (_undergroundLength < 9) { // Continue var flow = new UndergroundFlow(FlowBuilding.Item, nextPos, Depth.Fluid, _direction); flow.Previous.Add(_building); yield return(new FluidRouteState(flow, _cost + costFunction(_space, flow), flow.Position, _space.AddRoute(flow), flow.FlowDepth, flow.Rotation, false, _undergroundLength + 1)); } // Surface var surface = new Pipe(FlowBuilding.Item, pipeToGround, nextPos, _direction.Invert()); surface.Previous.Add(_building); yield return(new FluidRouteState(surface, _cost + costFunction(_space, surface), surface.Position, _space.AddRoute(surface), Depth.None, _direction, true)); } else { if (HasJustSurfaced) { Vector2 nextPos = _position + _direction.ToVector(); // Continue var cont = new FlowBuilding(FlowBuilding.Item, pipe, nextPos, BuildingRotation.North); cont.Previous.Add(_building); yield return(new FluidRouteState(cont, _cost + costFunction(_space, cont), cont.Position, _space.AddRoute(cont))); // Dive var dive = new FlowBuilding(FlowBuilding.Item, pipeToGround, nextPos, _direction); dive.Previous.Add(_building); yield return(new FluidRouteState(dive, _cost + costFunction(_space, dive), dive.Position, _space.AddRoute(dive), Depth.Fluid, _direction)); } else { BuildingRotation[] rotations = new BuildingRotation[] { BuildingRotation.North, BuildingRotation.East, BuildingRotation.South, BuildingRotation.West }; foreach (var rotation in rotations) { Vector2 nextPos = _position + rotation.ToVector(); // Straight var cont = new FlowBuilding(FlowBuilding.Item, pipe, nextPos, BuildingRotation.North); cont.Previous.Add(_building); yield return(new FluidRouteState(cont, _cost + costFunction(_space, cont), cont.Position, _space.AddRoute(cont))); // Dive var dive = new FlowBuilding(FlowBuilding.Item, pipeToGround, nextPos, rotation); dive.Previous.Add(_building); yield return(new FluidRouteState(dive, _cost + costFunction(_space, dive), dive.Position, _space.AddRoute(dive), Depth.Fluid, rotation)); } } } }
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 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 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)); } }
public Searchspace AddRoute(FlowBuilding building) { var result = new Searchspace(Size, _components, _routes.Add(new CollisionBox <FlowBuilding>(building)), _grid); for (int x = 0; x < building.Size.X; x++) { for (int y = 0; y < building.Size.Y; y++) { var xpos = x + (int)building.Position.X; var ypos = y + (int)building.Position.Y; if (xpos >= 0 && ypos >= 0 && xpos < Size.X && ypos < Size.Y) { result._grid[xpos, ypos] = _grid[xpos, ypos].Add(building); } } } return(result); }