private WirePath PathLine(RouterBoard board, IOInfo start, IOInfo end, Rectangle?startRect, Rectangle?endRect, List <WirePath> allPaths) { board.ReloadCheckpoint(); Point relativeStart = board.GetRelativeBoardPos(start.DirIO.Position); Point relativeEnd = board.GetRelativeBoardPos(end.DirIO.Position); //Start position may lie inside the component rectangle //and therefore the is no way to reach it. //This here makes a straight path out of the component //so it's possible to find a path. if (endRect.HasValue) { Rectangle endRectRelative = board.GetRelativeBoard(endRect.Value); Point endGo = relativeEnd; MoveDirs allowedDir = end.DirIO.InitialDir.Reverse(); do { board.SetCellAllowedMoves(endGo, allowedDir); endGo = allowedDir.MovePoint(endGo); } while (endRectRelative.Within(endGo)); } else { board.SetCellAllowedMoves(relativeEnd, end.DirIO.InitialDir.Reverse()); } if (startRect.HasValue) { Rectangle startRectRelative = board.GetRelativeBoard(startRect.Value); Point startGo = relativeStart; MoveDirs allowedDir = start.DirIO.InitialDir.Reverse(); do { board.SetCellAllowedMoves(startGo, allowedDir); startGo = allowedDir.Reverse().MovePoint(startGo); } while (startRectRelative.Within(startGo)); } foreach (var path in allPaths) { MoveDirs wireType; if (path.StartIO.DirIO.Position == start.DirIO.Position || path.EndIO.DirIO.Position == end.DirIO.Position) { wireType = MoveDirs.FriendWire; } else { wireType = MoveDirs.EnemyWire; } path.PlaceOnBoard(board, wireType); } ref ScorePath startScore = ref board.GetCellScorePath(relativeEnd);
internal void PlaceOnBoard(RouterBoard board, MoveDirs move) { foreach (var pos in BoardPositions) { board.AddCellAllowedMoves(pos, move); } if (move == MoveDirs.EnemyWire) { foreach (var pos in BoardPosTurns) { board.AddCellAllowedMoves(pos, MoveDirs.WireCorner); } } }
public List <WirePath> PathLines(PlacementInfo placements) { try { int rerouteCount = 0; Dictionary <Line, int> repathCounter = new Dictionary <Line, int>(); List <LineInfo> sortedLines = new List <LineInfo>(); foreach ((IOInfo start, IOInfo end) in Connections.GetAllConnectionLines(placements)) { LineInfo line = new LineInfo(start, end); sortedLines.Add(line); repathCounter.Add(line.GetLine(), 0); } Queue <LineInfo> linesPriority = new Queue <LineInfo>(sortedLines.OrderBy(x => x.GetScore())); RouterBoard board = new RouterBoard(placements.SpaceNeeded); board.PrepareBoard(placements.UsedSpace.Values.ToList()); board.CreateCheckpoint(); List <WirePath> paths = new List <WirePath>(); while (linesPriority.Count > 0) { //Debug.WriteLine(linesPriority.Count); (IOInfo start, IOInfo end) = linesPriority.Dequeue(); Rectangle?startRect = null; Rectangle?endRect = null; if (placements.UsedSpace.ContainsKey(start.Node)) { startRect = placements.UsedSpace[start.Node]; } if (placements.UsedSpace.ContainsKey(end.Node)) { endRect = placements.UsedSpace[end.Node]; } WirePath path = PathLine(board, start, end, startRect, endRect, paths); Debug.Assert(path.StartIO == start && path.EndIO == end); List <WirePath> needsRepathing = new List <WirePath>(); foreach (var oldPath in paths) { if (!path.CanCoexist(oldPath)) { needsRepathing.Add(oldPath); } } foreach (var repath in needsRepathing) { LineInfo line = new LineInfo(repath.StartIO, repath.EndIO); if (repathCounter[line.GetLine()]++ >= 20) { continue; } paths.Remove(repath); linesPriority.Enqueue(line); } paths.Add(path); } RefineWirePaths(board, paths); return(paths); } catch (Exception e) { Debug.WriteLine(e.Message + Environment.NewLine + e.StackTrace); throw; } }