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));
        }
Esempio n. 3
0
        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));
            }
        }
Esempio n. 5
0
        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);
        }