Пример #1
0
        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);
Пример #2
0
        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);
                }
            }
        }
Пример #3
0
        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;
            }
        }