Ejemplo n.º 1
0
 public UndergroundFlow(ItemAmount item, Vector2 position, Depth depth, BuildingRotation rotation) : base(item, new Building("underground-flow"), position, rotation)
 {
     Position  = position;
     FlowDepth = depth;
     Rotation  = rotation;
     Size      = Vector2.One;
 }
Ejemplo n.º 2
0
        private IEnumerable <SolidRouteState> GenerateSplitterStates(Func <Searchspace, IPhysicalBuilding, double> costFunction, Building splitter)
        {
            var offsets = new BuildingRotation[] {
                BuildingRotation.West,
                BuildingRotation.North,
                BuildingRotation.West,
                BuildingRotation.North,
            };
            var     offsetDir = offsets[(int)Direction];
            Vector2 nextpos   = _position + (_transportState == RoutingCoordinate.CoordinateType.Belt ? _direction.ToVector() : Vector2.Zero);

            var endPoint1 = nextpos + offsetDir.ToVector();
            var endPoint2 = nextpos - offsetDir.ToVector();

            var target = FlowBuilding.Item.Item;
            var dir    = Direction;

            var matches1 = Space.CalculateCollisions(endPoint1).OfType <Belt>().Where((b) => b.Item.Item == target && b.Rotation == dir);
            var matches2 = Space.CalculateCollisions(endPoint2).OfType <Belt>().Where((b) => b.Item.Item == target && b.Rotation == dir);

            if (matches1.Any())
            {
                var building = new Splitter(FlowBuilding.Item, splitter, endPoint1, Direction);
                building.Previous.Add(Building);
                yield return(new SolidRouteState(building, _cost + costFunction(_space, building), endPoint1, _space.AddRoute(building), RoutingCoordinate.CoordinateType.Splitter));
            }

            if (matches2.Any())
            {
                var building = new Splitter(FlowBuilding.Item, splitter, nextpos, Direction);
                building.Previous.Add(Building);
                yield return(new SolidRouteState(building, _cost + costFunction(_space, building), endPoint2, _space.AddRoute(building), RoutingCoordinate.CoordinateType.Splitter));
            }
        }
Ejemplo n.º 3
0
        private bool ValidateEndState(FluidRouteState state, HashSet <RoutingCoordinate> destinations)
        {
            if (state.Depth != Depth.None)
            {
                return(false);
            }

            if (state.Building.Building.Name != "pipe")
            {
                return(false);
            }

            bool found = false;

            BuildingRotation[] rotations = new BuildingRotation[] { BuildingRotation.North, BuildingRotation.East, BuildingRotation.South, BuildingRotation.West };
            foreach (var rotation in rotations)
            {
                if (destinations.Where((d) => d.Position == state.Position + rotation.ToVector()).Any())
                {
                    found = true;
                }
            }

            if (!found)
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 4
0
        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));
                    }
                }
            }
        }
Ejemplo n.º 5
0
 public FluidRouteState(IPhysicalBuilding building, double cost, Vector2 position, Searchspace space, Depth depth = Depth.None, BuildingRotation direction = BuildingRotation.North, bool hasJustSurfaced = false, int undergroundLength = 0)
 {
     _building          = building;
     _cost              = cost;
     _position          = position;
     _space             = space;
     _depth             = depth;
     _direction         = direction;
     _hasJustSurfaced   = hasJustSurfaced;
     _undergroundLength = undergroundLength;
 }
Ejemplo n.º 6
0
 public SolidRouteState(IPhysicalBuilding building, double cost, Vector2 position, Searchspace space, RoutingCoordinate.CoordinateType transportState, Depth depth = Depth.None, BuildingRotation direction = BuildingRotation.North, int undergroundLength = 0)
 {
     _building          = building;
     _cost              = cost;
     _position          = position;
     _space             = space;
     _depth             = depth;
     _direction         = direction;
     _undergroundLength = undergroundLength;
     _transportState    = transportState;
 }
Ejemplo n.º 7
0
        private IEnumerable <SolidRouteState> GenerateBeltStates(Func <Searchspace, IPhysicalBuilding, double> costFunction, Building belt)
        {
            BuildingRotation[] rotations = new BuildingRotation[] { BuildingRotation.North, BuildingRotation.East, BuildingRotation.South, BuildingRotation.West };
            Vector2            nextpos   = _position + (_transportState == RoutingCoordinate.CoordinateType.Belt ? _direction.ToVector() : Vector2.Zero);

            foreach (var rotation in rotations)
            {
                var building = new Belt(((FlowBuilding)_building).Item, belt, nextpos, rotation);
                building.Previous.Add(Building);
                yield return(new SolidRouteState(building, _cost + costFunction(_space, building), nextpos, _space.AddRoute(building), RoutingCoordinate.CoordinateType.Belt, Depth.None, rotation));
            }
        }
        public ProductionBuilding(Recipe recipe, double amount, Building building, Vector2 position, BuildingRotation rotation)
            : base(recipe, amount, building)
        {
            if (recipe == null)
            {
                throw new ArgumentNullException("recipe");
            }
            if (building == null)
            {
                throw new ArgumentNullException("building");
            }

            Position = position;
            Size     = building.Size.RotateAbsolute(rotation);
            Rotation = rotation;
        }
Ejemplo n.º 9
0
 public FlowBuilding(ItemAmount item, Building building, Vector2 position, BuildingRotation rotation)
     : base(item)
 {
     if (item == null)
     {
         throw new ArgumentNullException("item");
     }
     if (building == null)
     {
         throw new ArgumentNullException("building");
     }
     Item     = item;
     Building = building;
     Position = position;
     Size     = building.Size.RotateAbsolute(rotation);
     Rotation = rotation;
 }
Ejemplo n.º 10
0
        public static Vector2 Rotate(this Vector2 vector, BuildingRotation rotation)
        {
            switch (rotation)
            {
            case BuildingRotation.North:
                return(vector);

            case BuildingRotation.East:
                return(new Vector2(-vector.Y, vector.X));

            case BuildingRotation.South:
                return(new Vector2(-vector.X, -vector.Y));

            case BuildingRotation.West:
                return(new Vector2(vector.Y, -vector.X));
            }
            return(vector);
        }
Ejemplo n.º 11
0
        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 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));
            }
        }
Ejemplo n.º 13
0
        public static Vector2 ToVector(this BuildingRotation direction)
        {
            switch (direction)
            {
            case BuildingRotation.North:
                return(new Vector2(0, -1));

            case BuildingRotation.East:
                return(new Vector2(1, 0));

            case BuildingRotation.South:
                return(new Vector2(0, 1));

            case BuildingRotation.West:
                return(new Vector2(-1, 0));

            default:
                return(Vector2.Zero);
            }
        }
Ejemplo n.º 14
0
        public static BuildingRotation Invert(this BuildingRotation rotation)
        {
            switch (rotation)
            {
            case BuildingRotation.North:
                return(BuildingRotation.South);

            case BuildingRotation.East:
                return(BuildingRotation.West);

            case BuildingRotation.South:
                return(BuildingRotation.North);

            case BuildingRotation.West:
                return(BuildingRotation.East);

            default:
                return(BuildingRotation.North);
            }
        }
Ejemplo n.º 15
0
        private IEnumerable <SolidRouteState> GenerateInserters(Func <Searchspace, IPhysicalBuilding, double> costFunction, Building inserter, Building longInserter, Building fastInserter)
        {
            BuildingRotation[] rotations = new BuildingRotation[] { BuildingRotation.North, BuildingRotation.East, BuildingRotation.South, BuildingRotation.West };

            foreach (var rotation in rotations)
            {
                Vector2 nextpos              = _position;
                var     buildingInserter     = new PhysicalFlowBuilding(((FlowBuilding)_building).Item, inserter, nextpos + rotation.ToVector(), rotation);
                var     buildingLongInserter = new PhysicalFlowBuilding(((FlowBuilding)_building).Item, longInserter, nextpos + 2 * rotation.ToVector(), rotation);
                var     buildingFastInserter = new PhysicalFlowBuilding(((FlowBuilding)_building).Item, fastInserter, nextpos + rotation.ToVector(), rotation);

                buildingInserter.Previous.Add(Building);
                buildingLongInserter.Previous.Add(Building);
                buildingFastInserter.Previous.Add(Building);

                yield return(new SolidRouteState(buildingInserter, _cost + costFunction(_space, buildingInserter), nextpos + 2 * rotation.ToVector(), _space.AddRoute(buildingInserter), RoutingCoordinate.CoordinateType.Inserter, Depth.None, BuildingRotation.North));

                yield return(new SolidRouteState(buildingLongInserter, _cost + costFunction(_space, buildingLongInserter), nextpos + 4 * rotation.ToVector(), _space.AddRoute(buildingLongInserter), RoutingCoordinate.CoordinateType.Inserter, Depth.None, BuildingRotation.North));

                yield return(new SolidRouteState(buildingFastInserter, _cost + costFunction(_space, buildingFastInserter), nextpos + 2 * rotation.ToVector(), _space.AddRoute(buildingFastInserter), RoutingCoordinate.CoordinateType.Inserter, Depth.None, BuildingRotation.North));
            }
        }
 public GroundToUnderground(ItemAmount item, Building building, Vector2 position, BuildingRotation rotation, Depth depth, bool isUpward)
     : base(item, building, position, rotation)
 {
     FlowDepth = depth;
     IsUpward  = isUpward;
 }
Ejemplo n.º 17
0
 public Pipe(ItemAmount item, Building building, Vector2 position, BuildingRotation rotation)
     : base(item, building, position, rotation)
 {
 }
Ejemplo n.º 18
0
 public RoutingCoordinate(Vector2 position, CoordinateType type, BuildingRotation rotation)
 {
     _position = position;
     _type     = type;
     _rotation = rotation;
 }
Ejemplo n.º 19
0
 public VirtualFlowStep(ItemAmount item, Building building, Vector2 position, BuildingRotation rotation)
     : base(item, building, position, rotation)
 {
     Size = Vector2.Zero;
 }
Ejemplo n.º 20
0
        /// <summary>
        /// Attempts to route from the start states to the destination states. The given states are both lists, but only one state from each list will be selected for the final routing.
        /// </summary>
        /// <param name="item">How much to route.</param>
        /// <param name="space">The initialstate from which the routing starts.</param>
        /// <param name="startPositions">The list of starting states. Only one will be used.</param>
        /// <param name="destinations">The list of desired destination states. Only one will be reached.</param>
        /// <returns>The solution state found after routing</returns>
        public Searchspace Route(ItemAmount item, Searchspace space, IEnumerable <RoutingCoordinate> startPositions, IEnumerable <RoutingCoordinate> destinations)
        {
            if (startPositions == null)
            {
                throw new ArgumentNullException("startPositions");
            }
            if (destinations == null)
            {
                throw new ArgumentNullException("destinations");
            }

            AStar <SolidRouteState> star = new AStar <SolidRouteState>();

            star.StateGenerator    = (s) => s.NextStates(Grader.CostForBuilding, Belt, BeltGroundNormal, BeltGroundFast, BeltGroundExpress, Inserter, LongInserter, FastInserter, Splitter);
            star.EndStateValidator = ValidateEndState;

            foreach (var dest in destinations)
            {
                star.AddDestination(dest);
            }

            foreach (var position in startPositions)
            {
                switch (position.State)
                {
                case RoutingCoordinate.CoordinateType.Belt:
                    var startBuilding = new Belt(item, Belt, position.Position, position.Rotation);
                    var tmpSpace1     = space.AddRoute(startBuilding);
                    var startState    = new SolidRouteState(startBuilding, 0, position.Position, tmpSpace1, RoutingCoordinate.CoordinateType.Belt, Depth.None, position.Rotation);
                    star.AddState(startState);
                    break;

                case RoutingCoordinate.CoordinateType.PlacedItem:
                case RoutingCoordinate.CoordinateType.Inserter:
                    var startPlacedBuilding = new PlacedItem(item, position.Position);
                    var tmpSpace2           = space.AddRoute(startPlacedBuilding);
                    var startPlacedState    = new SolidRouteState(startPlacedBuilding, 0, position.Position, tmpSpace2, RoutingCoordinate.CoordinateType.PlacedItem);
                    star.AddState(startPlacedState);
                    break;

                case RoutingCoordinate.CoordinateType.Splitter:
                    var offsets = new BuildingRotation[] {
                        BuildingRotation.West,
                        BuildingRotation.North,
                        BuildingRotation.West,
                        BuildingRotation.North,
                    };

                    var offsetDir      = offsets[(int)position.Rotation];
                    var startSplitter1 = new Splitter(item, Splitter, position.Position, position.Rotation);
                    var startSplitter2 = new Splitter(item, Splitter, position.Position + offsetDir.ToVector(), position.Rotation);
                    var space1         = space.AddRoute(startSplitter1);
                    var space2         = space.AddRoute(startSplitter2);
                    var state1         = new SolidRouteState(startSplitter1, 0, position.Position - offsetDir.ToVector(), space1, RoutingCoordinate.CoordinateType.Belt, Depth.None, position.Rotation);
                    var state2         = new SolidRouteState(startSplitter2, 0, position.Position + offsetDir.ToVector(), space2, RoutingCoordinate.CoordinateType.Belt, Depth.None, position.Rotation);
                    var before         = space.CalculateCollisions(position.Position - position.Rotation.ToVector()).OfType <Belt>()
                                         .Where((b) => b.Item.Item == item.Item)
                                         .Where((b) => b.Rotation == position.Rotation);
                    var after = space.CalculateCollisions(position.Position + position.Rotation.ToVector()).OfType <Belt>()
                                .Where((b) => b.Item.Item == item.Item)
                                .Where((b) => b.Rotation == position.Rotation);

                    if (before.Any() && after.Any())
                    {
                        star.AddState(state1);
                        star.AddState(state2);
                    }

                    var startPlacedBuilding2 = new PlacedItem(item, position.Position);
                    var tmpSpace3            = space.AddRoute(startPlacedBuilding2);
                    var startPlacedState2    = new SolidRouteState(startPlacedBuilding2, 0, position.Position, tmpSpace3, RoutingCoordinate.CoordinateType.PlacedItem);
                    star.AddState(startPlacedState2);
                    break;
                }
            }

            while (!star.Step())
            {
            }

            return(star.EndState.Space);
        }
Ejemplo n.º 21
0
        public static Vector2 RotateAbsolute(this Vector2 vector, BuildingRotation rotation)
        {
            var result = Rotate(vector, rotation);

            return(new Vector2(Math.Abs(result.X), Math.Abs(result.Y)));
        }
Ejemplo n.º 22
0
 public PhysicalFlowBuilding(ItemAmount item, Building building, Vector2 position, BuildingRotation rotation)
     : base(item, building, position, rotation)
 {
 }