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)); }
public void SetFluidConcentrations(IDropletSource dropleSource) { dropleSource.GetFluidConcentrations().ForEach(pair => FluidConcentrations[pair.Key] = pair.Value); }
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"); }
public Route(Point[] route, IDropletSource routedDroplet, int startTime) { this.route = route; this.routedDroplet = routedDroplet; this.startTime = startTime; }