Exemple #1
0
        public static Route DetermineRouteToModule(Func <Module, bool> hasReachedTarget, Module sourceModule, IDropletSource targetInput, Board board, int startTime)
        {
            //Finds the route from the module to route to (source module), to the closest droplet of type targetFluidType,
            (int startingXPos, int startingYPos) = targetInput.GetMiddleOfSource();
            RouteDirection[,] routeMap           = new RouteDirection[board.Width, board.Heigth];
            routeMap[startingXPos, startingYPos] = RouteDirection.Start;

            Queue <Point> queue = new Queue <Point>();

            queue.Enqueue(new Point(startingXPos, startingYPos));

            //because this is a breath first search the queue will start
            //by containing the points with route length 1, then route length 2 and then 3
            //and so on, all on order. We can keep track of how many points
            //there is for each route length and thus keep track of how far away the
            //search is from the starting point when it has found the end point.
            //Route length starts at 1 and not 0 because the to place the starting point
            //a point is needed which is included in the route.
            int currentRangeCount = 1;
            int nextRangeCount    = 0;
            int routeLength       = 1;

            while (queue.Count > 0)
            {
                Point  currentNode         = queue.Dequeue();
                Module moduleAtCurrentNode = board.ModuleGrid[currentNode.X, currentNode.Y];

                if (currentRangeCount == 0)
                {
                    currentRangeCount = nextRangeCount;
                    nextRangeCount    = 0;
                    routeLength++;
                }
                currentRangeCount--;

                if (hasReachedTarget(moduleAtCurrentNode)) //Have reached the desired target
                {
                    return(GetRouteFromSourceToTarget(currentNode, routeMap, (IDropletSource)moduleAtCurrentNode, startTime, routeLength));
                }
                //No collisions with other modules are allowed (except the starting module):
                else if (hasCollisionWithOtherModules(sourceModule, moduleAtCurrentNode))
                {
                    continue;
                }

                //go through all neighbors
                UpdateAllNeighborPriorities(board, routeMap, queue, currentNode, ref nextRangeCount);
            }
            //If no route was found:
            throw new InternalRuntimeException("No route to the desired component could be found");
        }
Exemple #2
0
        private static Route GetRouteFromSourceToTarget(Point routeInfo, RouteDirection[,] routeMap, IDropletSource routedDroplet, int startTime, int routeLength)
        {
            (int dropletMiddleX, int dropletMiddleY) = routedDroplet.GetMiddleOfSource();

            int xDiff = dropletMiddleX - routeInfo.X;
            int yDiff = dropletMiddleY - routeInfo.Y;

            RouteDirection xDirection = (xDiff > 0) ? RouteDirection.Right : RouteDirection.Left;
            RouteDirection yDirection = (yDiff > 0) ? RouteDirection.Up : RouteDirection.Down;

            int xDiffAbs = Math.Abs(xDiff);
            int yDiffAbs = Math.Abs(yDiff);

            int movementsToCenter = xDiffAbs + yDiffAbs;

            Point[] wholeRoute = new Point[routeLength + movementsToCenter];

            int   routeIndex = movementsToCenter - 1;
            Point currentPos = routeInfo;

            for (int i = 0; i < xDiffAbs; i++)
            {
                currentPos = currentPos.Move(xDirection);
                wholeRoute[routeIndex--] = currentPos;
            }
            for (int i = 0; i < yDiffAbs; i++)
            {
                currentPos = currentPos.Move(yDirection);
                wholeRoute[routeIndex--] = currentPos;
            }

            routeIndex = movementsToCenter;
            currentPos = routeInfo;
            for (int i = 0; i < routeLength - 1; i++)
            {
                wholeRoute[routeIndex++] = currentPos;
                currentPos = currentPos.Move(routeMap[currentPos.X, currentPos.Y]);
            }
            //add starting point to the route
            wholeRoute[routeIndex] = currentPos;

            return(new Route(wholeRoute, routedDroplet, startTime));
        }