public void GeneratePath(Point PointToMoveTo)
        {
            PathFinderFast p = new PathFinderFast(Area.PathGrid);
            p.Diagonals = true;
            p.Formula = Algorithms.HeuristicFormula.Manhattan;
            p.HeavyDiagonals = false;
            p.HeuristicEstimate = 2;
            p.PunishChangeDirection = false;
            p.TieBreaker = false;
            p.SearchLimit = 50000;
            Starttime = GameProject.GameLoop.GameTime;

             try
            {
                path = p.FindPath(Stats.Location.ToPoint(), PointToMoveTo);
            }
            catch (Exception ex)
            {
                throw new Exception("Error generating path for citizen " + ParentActor.ID.ToString() + ".  Moving from point " + Stats.Location.X + "," + Stats.Location.Y + " to " + PointToMoveTo.X + "," + PointToMoveTo.Y + " in area " + Area.Width + "," + Area.Height, ex);
            }

             if (path != null)
             {
                 double Rate = Stats.MovementSpeed;
                 TimeToTarget = (path.Count - 1) / Rate;
                 Starttime = GameProject.GameLoop.GameTime;
             }
             else
             {
                 Console.WriteLine("Could not find a path for citizen " + ParentActor.ID.ToString());
             }
        }
Exemple #2
0
        int tileSize; /**< Size of single tile */

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="WS">Reference to World Screen</param>
        /// <param name="tileSize">Size of single tile</param>
        /// <param name="size">Size of map</param>
        public Map(WorldScreen WS, int tileSize, int size)
        {
            this.tileSize = tileSize;
            this.size = size;

            this.Entities = new List<Entity>();

            PhysicalWorld = new World(new Vector2(0, 0));

            Player = new Player(new Rectangle(6 * 64, 6 * 64, 64, 64), this);
            AddEntity(Player);

            chunk = new Chunk(new Rectangle(0, 0, size * tileSize, size * tileSize), this, tileSize);
            Parent = WS;

            pfinder = new PathFinderFast(GetChunk().GetCostArray());

            for (int i = 0; i < 25; i++)
            {
                Rectangle r = new Rectangle((int)Helper.GetRandomTo(size * tileSize), (int)Helper.GetRandomTo(size * tileSize), 64, 64);
                Rectangle t = new Rectangle(r.X / tileSize, r.Y / tileSize, tileSize, tileSize);

                while (chunk.tiles[t.X,t.Y].isSolid)
                {
                    r = new Rectangle((int)Helper.GetRandomTo(size * tileSize), (int)Helper.GetRandomTo(size * tileSize), 64, 64);
                    t = new Rectangle(r.X / tileSize, r.Y / tileSize, tileSize, tileSize);
                }
                new ZombieBig(r, this);
            }

            new Barrel(new Rectangle(Player.Position.X + 64, Player.Position.Y + 64, 32, 32), this);
            new FloorFan(new Rectangle(Player.Position.X + 64, Player.Position.Y + 64, 128, 128), this);
            //chunk.Save("Content/Chunks/00.xml");
        }
Exemple #3
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="WS">Reference to World Screen</param>
        /// <param name="tileSize">Size of single tile</param>
        /// <param name="size">Size of map</param>
        public Map(WorldScreen WS, int tileSize, int size)
        {
            this.tileSize = tileSize;
            this.size     = size;

            this.Entities = new List <Entity>();

            PhysicalWorld = new World(new Vector2(0, 0));

            Player = new Player(new Rectangle(6 * 64, 6 * 64, 64, 64), this);
            AddEntity(Player);

            chunk  = new Chunk(new Rectangle(0, 0, size * tileSize, size * tileSize), this, tileSize);
            Parent = WS;

            pfinder = new PathFinderFast(GetChunk().GetCostArray());

            for (int i = 0; i < 25; i++)
            {
                Rectangle r = new Rectangle((int)Helper.GetRandomTo(size * tileSize), (int)Helper.GetRandomTo(size * tileSize), 64, 64);
                Rectangle t = new Rectangle(r.X / tileSize, r.Y / tileSize, tileSize, tileSize);

                while (chunk.tiles[t.X, t.Y].isSolid)
                {
                    r = new Rectangle((int)Helper.GetRandomTo(size * tileSize), (int)Helper.GetRandomTo(size * tileSize), 64, 64);
                    t = new Rectangle(r.X / tileSize, r.Y / tileSize, tileSize, tileSize);
                }
                new ZombieBig(r, this);
            }

            new Barrel(new Rectangle(Player.Position.X + 64, Player.Position.Y + 64, 32, 32), this);
            new FloorFan(new Rectangle(Player.Position.X + 64, Player.Position.Y + 64, 128, 128), this);
            //chunk.Save("Content/Chunks/00.xml");
        }
Exemple #4
0
 public bool checkWalk(int startX, int startY, int targetX, int targetY)
 {
     if (startX == door_x && startY == door_y)
     {
         return(true);
     }
     else
     {
         if ((!(targetX == door_x && targetY == door_y)) && targetX >= 0 && targetY >= 0 && targetX < breed && targetY < lang)
         {
             PathFinderFast        Pathfinder = new PathFinderFast(GenerateGrid(targetX, targetY));
             List <PathFinderNode> Path       = Pathfinder.FindPath(new Point(startX, startY), new Point(targetX, targetY));
             if (Path == null || Path.Count == 0)
             {
                 return(false);
             }
             else
             {
                 return(true);
             }
         }
         else
         {
             return(false);
         }
     }
 }
Exemple #5
0
        private void DoPath(Map map, Unit unit, Vec2Double target)
        {
            var pathF = new PathFinderFast(map.MGrid, map);

            _path = pathF.FindPath(new Vector2I((int)unit.Position.X, (int)unit.Position.Y), new Vector2I((int)target.X, (int)target.Y), 1, 2, 5, 10);
            _path?.Reverse();
            _i          = 0;
            _pathLength = 0;
        }
Exemple #6
0
        public static List <int[]> FindPath(Point startPoint, Point endPoint, int mapCode)
        {
            GameMap      gameMap = GameManager.MapMgr.DictMaps[mapCode];
            List <int[]> result;

            if (null == gameMap)
            {
                result = null;
            }
            else
            {
                PathFinderFast pathFinderFast;
                if (GlobalNew._pathStack.Count <= 0)
                {
                    pathFinderFast = new PathFinderFast(gameMap.MyNodeGrid.GetFixedObstruction())
                    {
                        Formula           = HeuristicFormula.Manhattan,
                        Diagonals         = true,
                        HeuristicEstimate = 2,
                        ReopenCloseNodes  = true,
                        SearchLimit       = int.MaxValue,
                        Punish            = null,
                        MaxNum            = Global.GMax(gameMap.MapGridWidth, gameMap.MapGridHeight)
                    };
                }
                else
                {
                    pathFinderFast = GlobalNew._pathStack.Pop();
                }
                startPoint.X = (double)(gameMap.CorrectWidthPointToGridPoint((int)startPoint.X) / gameMap.MapGridWidth);
                startPoint.Y = (double)(gameMap.CorrectHeightPointToGridPoint((int)startPoint.Y) / gameMap.MapGridHeight);
                endPoint.X   = (double)(gameMap.CorrectWidthPointToGridPoint((int)endPoint.X) / gameMap.MapGridWidth);
                endPoint.Y   = (double)(gameMap.CorrectHeightPointToGridPoint((int)endPoint.Y) / gameMap.MapGridHeight);
                pathFinderFast.EnablePunish = false;
                List <PathFinderNode> nodeList = pathFinderFast.FindPath(startPoint, endPoint);
                if (nodeList == null || nodeList.Count <= 0)
                {
                    result = null;
                }
                else
                {
                    List <int[]> path = new List <int[]>();
                    for (int i = 0; i < nodeList.Count; i++)
                    {
                        path.Add(new int[]
                        {
                            nodeList[i].X,
                            nodeList[i].Y
                        });
                    }
                    result = path;
                }
            }
            return(result);
        }
Exemple #7
0
 public BattleData(Squad[] enemyArmy, Squad[] allyArmy, byte[] map, int mapWidth)
 {
     this.EnemyArmy = enemyArmy;
     this.AllyArmy = allyArmy;
     this.Map = map;
     this.MapWidth = mapWidth;
     this.MapHeight = map.Length / mapWidth;
     this.MapHeightLog2 = (int)(Math.Log(MapWidth, 2));
     this.PathFinder = new PathFinderFast(Map, MapWidth);
     PathFinder.PathFinderDebug += PathFinder_PathFinderDebug;
 }
Exemple #8
0
        public List <Node> GetPath(float X, float Z, int id)
        {
            List <Node>           ReturnPath   = new List <Node>();
            var                   Temp         = GetWaypointClosestTo(Character.Api.Player.X, Character.Api.Player.Z);
            int                   StartingX    = Convert.ToInt32(Temp.X) + offset;
            int                   StartingZ    = Convert.ToInt32(Temp.Z) + offset;
            int                   DestinationX = Convert.ToInt32(X) + offset;
            int                   DestinationZ = Convert.ToInt32(Z) + offset;
            var                   mob          = Character.Api.Entity.GetEntity(id);
            List <PathFinderNode> Path         = new PathFinderFast(Grid).FindPath(new DeenGames.Utils.Point(StartingX, StartingZ), new DeenGames.Utils.Point(DestinationX, DestinationZ));

            if (Path != null && Path.Count > 5)
            {
                foreach (PathFinderNode point in Path)
                {
                    ReturnPath.Add(new Node {
                        X = point.X - offset, Z = point.Y - offset
                    });
                }
                // Waypoints are added backwards, so let's reverse.
                ReturnPath.Reverse();
                // Character.Logger.AddDebugText(Character.Tc.rtbDebug, string.Format(@"Path Found
                // Moving to {0} distance {1}y",
                // Character.Api.Entity.GetEntity(Character.hunter.MobID).Name, Character.Api.Entity.GetEntity(Character.hunter.MobID).Distance));

                ReturnPath = SmoothNodes(ReturnPath);
                Character.Api.ThirdParty.KeyDown(EliteMMO.API.Keys.NUMPAD8);
                Thread.Sleep(1);
                Character.Api.ThirdParty.KeyUp(EliteMMO.API.Keys.NUMPAD8);
                Thread.Sleep(1);
                FailedToPath = 0;
            }
            if (Path == null || Path.Count < 5)
            {
                FailedToPath++;

                Character.Logger.AddDebugText(Character.Tc.rtbDebug, string.Format(@"Failed To Find Path to {0} distance // {1}y", mob.Name.ToString(), mob.Distance.ToString()));
            }
            if (FailedToPath > 2)
            {
                Character.Target.BlockedTargets.Add(id);
                Character.Logger.AddDebugText(Character.Tc.rtbDebug, string.Format(@"failed to path to many times. added {0} id {1} to blocked target list", mob.Name, id.ToString()));
            }

            return(ReturnPath);
        }
Exemple #9
0
    public void InitPathFinder()
    {
        mPathFinder = new PathFinderFast(this);

        //EuclideanNoSQR seemed to work the best, although it sometimes provides a little hop off ledges that is unneeded
        mPathFinder.Formula = HeuristicFormula.EuclideanNoSQR;
        //if false then diagonal movement will be prohibited
        mPathFinder.Diagonals = false;
        //if true then diagonal movement will have higher cost
        mPathFinder.HeavyDiagonals = false;
        //estimate of path length
        mPathFinder.HeuristicEstimate     = 6;
        mPathFinder.PunishChangeDirection = false;
        mPathFinder.TieBreaker            = false;
        mPathFinder.SearchLimit           = 10000;
        mPathFinder.DebugProgress         = false;
        mPathFinder.DebugFoundPath        = false;
    }
Exemple #10
0
        public void CalcMinionNewPath(MinionBase minion, Cell cell)
        {
            if (false)
            {
                minion.Path = PathFinding.CalcPath(minion.CurrentCell, cell, true, 10f);
                minion.PathLength = (minion.Path.Count - 1) * Map.R;
                minion.TraveledLength = 0f;
            }
            else
            {
                IPathFinder mPathFinder = new PathFinderFast(Map.Matrix);
                //IPathFinder mPathFinder = new PathFinder(Map.Matrix);

                mPathFinder.Formula = HeuristicFormula.Manhattan;
                mPathFinder.Diagonals = false;
                mPathFinder.HeavyDiagonals = false;
                mPathFinder.HeuristicEstimate = 1;
                mPathFinder.PunishChangeDirection = false;
                mPathFinder.TieBreaker = false;
                mPathFinder.SearchLimit = 5000;
                mPathFinder.DebugProgress = true;
                mPathFinder.DebugFoundPath = true;

                List<PathFinderNode> path = mPathFinder.FindPath(new System.Drawing.Point(minion.CurrentCell.Coord.X - 1, minion.CurrentCell.Coord.Y - 1), new System.Drawing.Point(cell.Coord.X - 1, cell.Coord.Y - 1));

                minion.Path = new List<int>();
                if (path != null)
                {
                    path.Reverse();

                    for (int i = 0; i < path.Count; i++)
                    {
                        minion.Path.Add(path[i].X + path[i].Y * Map.Width);
                    }
                }

                minion.PathLength = (minion.Path.Count - 1) * Map.R;
                minion.TraveledLength = 0f;
            }
        }
Exemple #11
0
    public List <CSCell> Search(Vector3 startPos, Vector3 endPos)
    {
        List <CSCell>  ret        = new List <CSCell>();
        PathFinderFast PathFinder = new PathFinderFast(m_map);

        PathFinder.Formula     = HeuristicFormula.Manhattan; //使用我个人觉得最快的曼哈顿A*算法
        PathFinder.SearchLimit = 2000;                       //即移动经过方块(20*20)不大于2000个(简单理解就是步数)

        Point2D Start = new Point2D((int)startPos.x, (int)startPos.y);
        Point2D End   = new Point2D((int)endPos.x, (int)endPos.y);
        List <PathFinderNode> path = PathFinder.FindPath(Start, End); //开始寻径

        if (path == null)
        {
            Debug.Log("路径不存在!");
        }
        else
        {
            string output = string.Empty;
            for (int i = path.Count - 1; i >= 0; i--)
            {
                output = string.Format(output
                                       + "{0}"
                                       + path[i].X.ToString()
                                       + "{1}"
                                       + path[i].Y.ToString()
                                       + "{2}",
                                       "(", ",", ") ");
                ret.Add(new CSCell()
                {
                    X = path[i].X, Y = path[i].Y, Value = (int)MapCellStatus.Normal
                });
            }
            Debug.Log("路径坐标分别为:" + output);
        }

        return(ret);
    }
Exemple #12
0
        /// <summary>
        /// Analyses the map. Can take up a few seconds.
        /// </summary>
        public void Analyse()
        {
            DateTime now = DateTime.Now;

            Width  = Game.MapWidth;
            Height = Game.MapHeight;

            int minSize = Math.Max(Width, Height);
            int power   = 1;

            while (power < minSize)
            {
                power *= 2;
            }

            PathFinderTileData = new byte[power, power];
            PathFinderTile     = new PathFinderFast(PathFinderTileData);

            BuildGrid = new BuildTileInfo[Width, Height];
            WalkGrid  = new WalkTileInfo[Width * 4, Height * 4];
            UpdateWalkability();
            CalculateInaccessibility();
            CalculateAltitude();
            InitLength = (DateTime.Now.Ticks - now.Ticks) / 10000.0f;

            FindBases();

#if DEBUG
            Game.SendText($"Map analyser: {InitLength}ms");
            SaveToFile(Game.MapFileName);
#endif

            SelfBase = Bases.OrderBy(x => x.DepotPosition.CalcDistance(Game.Self.StartLocation)).First();

            AnalysisFinished();
        }
Exemple #13
0
        void ComputeRouteMatrix(TERRAIN_CAPABILITY terrainCapability, float minAltitude, float maxAltitude)
        {
            bool computeMatrix = false;
            byte thisMatrix    = 1;

            // prepare matrix
            if (earthRouteMatrix == null)
            {
                earthRouteMatrix   = new byte[EARTH_ROUTE_SPACE_WIDTH * EARTH_ROUTE_SPACE_HEIGHT];
                computedMatrixBits = 0;
            }

            // prepare water mask data
            bool checkWater = terrainCapability != TERRAIN_CAPABILITY.Any;

            if (checkWater)
            {
                computeMatrix = CheckRouteWaterMask();
            }

            // check elevation data if needed
            bool checkElevation = minAltitude > 0f || maxAltitude < 1.0f;

            if (checkElevation)
            {
                if (viewportElevationPoints == null)
                {
                    Debug.LogError("Viewport needs to be initialized before calling using Path Finding functions.");
                    return;
                }
                if (minAltitude != earthRouteMatrixWithElevationMinAltitude || maxAltitude != earthRouteMatrixWithElevationMaxAltitude)
                {
                    computeMatrix = true;
                    earthRouteMatrixWithElevationMinAltitude = minAltitude;
                    earthRouteMatrixWithElevationMaxAltitude = maxAltitude;
                }
            }
            else
            {
                if (terrainCapability == TERRAIN_CAPABILITY.OnlyGround)
                {
                    thisMatrix = 2;
                }
                else
                {
                    thisMatrix = 4; // water
                }
                if ((computedMatrixBits & thisMatrix) == 0)
                {
                    computeMatrix       = true;
                    computedMatrixBits |= thisMatrix;   // mark computedMatrixBits
                }
            }

            // Compute route
            if (computeMatrix)
            {
                int   jj_waterMask = 0, kk_waterMask;
                int   jj_terrainElevation = 0, kk_terrainElevation;
                bool  dry = false;
                float elev = 0;
                for (int j = 0; j < EARTH_ROUTE_SPACE_HEIGHT; j++)
                {
                    int jj = j * EARTH_ROUTE_SPACE_WIDTH;
                    if (checkWater)
                    {
                        jj_waterMask = (int)((j * (float)earthWaterMaskHeight / EARTH_ROUTE_SPACE_HEIGHT)) * earthWaterMaskWidth;
                    }
                    if (checkElevation)
                    {
                        jj_terrainElevation = ((int)(j * (float)heightmapTextureHeight / EARTH_ROUTE_SPACE_HEIGHT)) * heightmapTextureWidth;
                    }
                    for (int k = 0; k < EARTH_ROUTE_SPACE_WIDTH; k++)
                    {
                        bool setBit = false;
                        // Check altitude
                        if (checkElevation)
                        {
                            kk_terrainElevation = (int)(k * (float)heightmapTextureWidth / EARTH_ROUTE_SPACE_WIDTH);
                            elev = viewportElevationPoints[jj_terrainElevation + kk_terrainElevation];
                        }
                        if (elev >= minAltitude && elev <= maxAltitude)
                        {
                            if (checkWater)
                            {
                                kk_waterMask = (int)(k * (float)earthWaterMaskWidth / EARTH_ROUTE_SPACE_WIDTH);
                                dry          = !earthWaterMask.GetBit(jj_waterMask + kk_waterMask);
                            }
                            if (terrainCapability == TERRAIN_CAPABILITY.Any ||
                                terrainCapability == TERRAIN_CAPABILITY.OnlyGround && dry ||
                                terrainCapability == TERRAIN_CAPABILITY.OnlyWater && !dry)
                            {
                                setBit = true;
                            }
                        }
                        if (setBit)     // set navigation bit
                        {
                            earthRouteMatrix[jj + k] |= thisMatrix;
                        }
                        else            // clear navigation bit
                        {
                            earthRouteMatrix[jj + k] &= (byte)(byte.MaxValue ^ thisMatrix);
                        }
                    }
                }
            }

            if (finder == null)
            {
                if (_customRouteMatrix == null || !_pathFindingEnableCustomRouteMatrix)
                {
                    PathFindingCustomRouteMatrixReset();
                }
                finder = new PathFinderFast(earthRouteMatrix, thisMatrix, EARTH_ROUTE_SPACE_WIDTH, EARTH_ROUTE_SPACE_HEIGHT, _customRouteMatrix);
            }
            else
            {
                if (computeMatrix || thisMatrix != lastMatrix)
                {
                    lastMatrix = thisMatrix;
                    finder.SetCalcMatrix(earthRouteMatrix, thisMatrix);
                }
            }
        }
 /// <summary>
 /// 从当前位置向目标位置移动
 /// </summary>
 /// <param name="destination">窗口Canvas中的目标位置</param>
 public void MoveTo(Point destination)
 {
     if (isActionLock || isFreeze || isPetrifaction || isSpecialMove) { return; }
     //特殊坐标判断处理
     Point end = terrain.GetCoordinateFromPosition(destination);
     int startX = (int)Coordinate.X, startY = (int)Coordinate.Y, endX = (int)end.X, endY = (int)end.Y;
     if ((startX == endX && startY == endY) || !terrain.InEffectiveRange(end)) { return; } //对目标点进行有效检测
     bool findObstacle = false;
     //如果在地面则采用路径预测法中的(两点线段检测(直线等分逐测算法)+A*寻路算法组合),空中目前忽略一切障碍物
     if (SpaceLayer == SpaceLayers.Ground) {
         //if (terrain.TerrainType == TerrainTypes.Static) {
         double angle = GlobalMethod.GetRadian(Position, destination);
         double cosA = Math.Cos(angle);
         double sinA = Math.Sin(angle);
         for (int i = 0; i <= (int)(GlobalMethod.GetDistance(Position, destination) / terrain.UnitMinLength); i++) {
             Point p = terrain.GetCoordinateFromPosition(new Point(cosA * i * terrain.UnitMinLength + destination.X, sinA * i * terrain.UnitMinLength + destination.Y));
             if (terrain.DynamicMatrix[(int)p.X, (int)p.Y] == 0) {
                 findObstacle = true;
                 break;
             }
         }
         //} else if (terrain.TerrainType == TerrainTypes.Dynamic) {
         //    //动态地形直接用寻路移动模式
         //    findObstacle = true;
         //}
     }
     //如果将要的行程中有障碍则寻路移动,否则直线移动
     if (findObstacle) {
         PathFinderFast pathFinderFast = new PathFinderFast(terrain.DynamicMatrix) {
             Formula = HeuristicFormula.Manhattan,
             Diagonals = true,
             HeuristicEstimate = 2,
             SearchLimit = (int)Application.Current.Host.Content.ActualWidth, //寻径限度(太小可能导致找不到路径)
         };
         List<PathFinderNode> pathTemp = pathFinderFast.FindPath(new Point2D(startX, startY), new Point2D(endX, endY));
         if (pathTemp != null && pathTemp.Count > 1) {
             path = pathTemp;
             path.Remove(path[path.Count - 1]);
             StraightMoveTo(new Point(path[path.Count - 1].X, path[path.Count - 1].Y));
         }
     } else {
         path.Clear();
         path.Add(new PathFinderNode() { X = endX, Y = endY });
         StraightMoveTo(end);
     }
 }
Exemple #15
0
        /// <summary>Find a path from a point on a map to another point</summary>
        /// <returns>Point[] of path</returns>
        public static Point[] GetPathFast(gMap Map, int X, int Y, int EndX, int EndY)
        {
            int NewWidth = (int)Math.Pow(2d, Math.Ceiling(Math.Log(Map.Width) / Math.Log(2d)));
            int NewHeight = (int)Math.Pow(2d, Math.Ceiling(Math.Log(Map.Height) / Math.Log(2d)));

            byte[,] Grid = new byte[NewWidth, NewHeight];
            Grid.Initialize();

            for (int x = 0; x < Map.Width; x++)
            {
                for (int y = 0; y < Map.Height; y++)
                {
                    Grid[x, y] = Convert.ToByte(Map[x, y]);
                }
            }

            PathFinderFast PathFinder = new PathFinderFast(Grid);
            PathFinder.Formula = HeuristicFormula.Manhattan;
            PathFinder.Diagonals = true;
            PathFinder.HeavyDiagonals = false;
            PathFinder.HeuristicEstimate = 2;
            PathFinder.PunishChangeDirection = false;
            PathFinder.TieBreaker = false;
            PathFinder.SearchLimit = 50000;
            PathFinder.DebugProgress = false;
            PathFinder.ReopenCloseNodes = true;
            PathFinder.DebugFoundPath = true;
            List<PathFinderNode> path = PathFinder.FindPath(new Point(X, Y), new Point(EndX, EndY));

            Point[] pointArray = new Point[path.Count];
            for (int i = 0; i < pointArray.Length; i++)
            {
                pointArray[(pointArray.Length - i) - 1] = new Point(path[i].X, path[i].Y);
            }

            return pointArray;
        }
Exemple #16
0
        /// <summary>
        /// Given a list of potential molecules, weed out all the ones where
        /// the atoms are not all adjacent to each other. This can occur due
        /// to a bug-fix for I-shaped molecules not reacting, where we
        /// extended molecule detection to all non-empty adjacent tiles.
        /// As a result, you can have H-Be-Cl forming H-Cl, which is wrong.
        /// This function will fix that, by checking that H and Cl are adjacent.
        /// </summary>
        /// <param name="molecules"></param>
        /// <returns></returns>
        private IList<Molecule> weedOutNonConnectedMolecules(IList<Molecule> molecules)
        {
            IList<Molecule> toReturn = new List<Molecule>();
            // The solution to this is really stupid. Checking for adjacencies
            // won't work; that will allow H-H-Be-Cl-Cl to form H-H-Cl-Cl, because
            // the two Hs are adjacent, as are the two Cls. Lame, dude.
            // The solution? Use path-finding to make sure there's a solid path of
            // atoms connecting every atom to every other atom. Yech.

            // Multi-Threading is a bloody business. There are lots of casualties.
            // Remove said casualties -- molecules that have "NONE" atoms in them.
            molecules = molecules.Where(m => !m.AtomTiles.Any(t => t.Atom == Atom.NONE)).ToList();

            foreach (Molecule candidate in molecules)
            {
                this._pathFinder = new PathFinderFast(candidate.ByteGrid);
                _pathFinder.Diagonals = false;

                bool allPairsHaveAPath = true;
                List<PathFinderNode> path;
                Tile startTile;
                Tile endTile;
                Point start;
                Point end;

                for (int i = 0; i < candidate.AtomTiles.Count; i++)
                {
                    startTile = candidate.AtomTiles[i];
                    start = new Point(startTile.X, startTile.Y);

                    for (int j = i + 1; j < candidate.AtomTiles.Count; j++)
                    {
                        endTile = candidate.AtomTiles[j];
                        end = new Point(endTile.X, endTile.Y);

                        path = this._pathFinder.FindPath(start, end);
                        if (path == null)
                        {
                            allPairsHaveAPath = false;
                        }
                    }
                }

                if (allPairsHaveAPath == true)
                {
                    toReturn.Add(candidate);
                }
            }

            return toReturn;
        }
Exemple #17
0
        public void DoEvents()
        {
            while (true)
            {
                StringBuilder sendText = new StringBuilder();
                foreach (ConnectedUser user in _Users.Values)
                {
                    if (user._Room_X != user._Room_X_Target || user._Room_Y != user._Room_Y_Target)
                    {
                        int[] nextCoords;
                        bool walkDoor = false;

                        if (user._Room_X == door_x && user._Room_Y == door_y)
                        {
                            // first walk out of the door, then check if you can walk after that!
                            walkDoor = true;
                            if (user._Room_X_Target == doorstep_x && user._Room_Y_Target == doorstep_y)
                            {
                                // just come out of the door
                                squareState[,] stateMap = avatarStateMap(doorstep_x, doorstep_y);
                                if (stateMap[doorstep_x, doorstep_y] == squareState.Open && (!_sqUnit[doorstep_x, doorstep_y]))
                                {
                                    // doorstep is free
                                    nextCoords = new int[2];
                                    nextCoords[0] = doorstep_x;
                                    nextCoords[1] = doorstep_y;
                                }
                                else
                                {
                                    nextCoords = null;
                                }
                            }
                            else
                            {
                                PathFinderFast Pathfinder = new PathFinderFast(GenerateGrid(user._Room_X_Target, user._Room_Y_Target));
                                List<PathFinderNode> Path = Pathfinder.FindPath(new Point(doorstep_x, doorstep_y), new Point(user._Room_X_Target, user._Room_Y_Target));
                                if (Path == null || Path.Count == 0)
                                {
                                    nextCoords = null;
                                }
                                else
                                {
                                    // after coming out of your door you'll be able to walk
                                    squareState[,] stateMap = avatarStateMap(doorstep_x, doorstep_y);
                                    if (stateMap[doorstep_x, doorstep_y] == squareState.Open && (!_sqUnit[doorstep_x, doorstep_y]))
                                    {
                                        // doorstep is free
                                        nextCoords = new int[2];
                                        nextCoords[0] = doorstep_x;
                                        nextCoords[1] = doorstep_y;
                                    }
                                    else
                                    {
                                        nextCoords = null;
                                    }
                                }
                            }
                        }
                        else
                        {
                            PathFinderFast Pathfinder = new PathFinderFast(GenerateGrid(user._Room_X_Target, user._Room_Y_Target));
                            List<PathFinderNode> Path = Pathfinder.FindPath(new Point(user._Room_X, user._Room_Y), new Point(user._Room_X_Target, user._Room_Y_Target));
                            if (Path == null || Path.Count == 0)
                            {
                                nextCoords = null;
                            }
                            else
                            {
                                PathFinderNode NextPosition = Path[Path.Count - 2];
                                nextCoords = new int[2];
                                nextCoords[0] = NextPosition.X;
                                nextCoords[1] = NextPosition.Y;
                            }
                        }

                        if (nextCoords == null)
                        {
                            user._Room_Sit = "";
                            user._Room_X_Target = user._Room_X;
                            user._Room_Y_Target = user._Room_Y;
                            StopAvatarPacket stopMove = new StopAvatarPacket();
                            stopMove.I = user._UserID;
                            string stopMovePacket = JsonConvert.SerializeObject(stopMove);
                            sendText.Append("064");
                            sendText.Append(stopMovePacket);
                            sendText.Append("#");
                        }
                        else
                        {
                            int nextX = nextCoords[0];
                            int nextY = nextCoords[1];
                            squareState nextState = _sqState[nextX, nextY];

                            if (!walkDoor)
                            {
                                _sqUnit[user._Room_X, user._Room_Y] = false;
                            }
                            _sqUnit[nextX, nextY] = true;

                            double nextHeight = 0;
                            nextHeight = (double)_sqHeight[nextX, nextY];

                            // dir eerst!
                            user._Room_Dir = getNewDir(user._Room_X, user._Room_Y, nextX, nextY);
                            user._Room_X = nextX;
                            user._Room_Y = nextY;
                            user._Room_Z = (int)nextHeight;

                            if (nextState == squareState.Seat)
                            {
                                // Do Sit
                                MoveAvatarPacket mvpack = new MoveAvatarPacket();
                                mvpack.I = user._UserID;
                                mvpack.X = nextX;
                                mvpack.Y = nextY;
                                mvpack.H = user._Room_Dir;
                                string stringmvpack = JsonConvert.SerializeObject(mvpack);
                                sendText.Append("057");
                                sendText.Append(stringmvpack);
                                sendText.Append("#");

                                if (user._Room_X == user._Room_X_Target && user._Room_Y == user._Room_Y_Target)
                                {
                                    user._Room_Dir = _sqRot[user._Room_X, user._Room_Y] * 2;
                                    user._Room_Sit = user._Room_Dir.ToString() + "|" + _sqTile[user._Room_X, user._Room_Y];
                                    StopAvatarPacket stopMove = new StopAvatarPacket();
                                    stopMove.I = user._UserID;
                                    string stopMovePacket = JsonConvert.SerializeObject(stopMove);
                                    sendText.Append("064");
                                    sendText.Append(stopMovePacket);
                                    sendText.Append("#");

                                    SetSitPacket setSit = new SetSitPacket();
                                    setSit.I = user._UserID;
                                    setSit.S = user._Room_Sit;
                                    string SetSitPacket = JsonConvert.SerializeObject(setSit);
                                    sendText.Append("081");
                                    sendText.Append(SetSitPacket);
                                    sendText.Append("#");
                                }
                            }
                            else
                            {
                                user._Room_Sit = "";

                                MoveAvatarPacket mvpack = new MoveAvatarPacket();
                                mvpack.I = user._UserID;
                                mvpack.X = nextX;
                                mvpack.Y = nextY;
                                mvpack.H = user._Room_Dir;
                                string stringmvpack = JsonConvert.SerializeObject(mvpack);
                                sendText.Append("057");
                                sendText.Append(stringmvpack);
                                sendText.Append("#");

                                if (user._Room_X == user._Room_X_Target && user._Room_Y == user._Room_Y_Target)
                                {
                                    StopAvatarPacket stopMove = new StopAvatarPacket();
                                    stopMove.I = user._UserID;
                                    string stopMovePacket = JsonConvert.SerializeObject(stopMove);
                                    sendText.Append("064");
                                    sendText.Append(stopMovePacket);
                                    sendText.Append("#");
                                }
                            }
                        }
                    }
                }

                // BOTS
                try
                {
                    foreach (RoomBot bot in _Bots.Values)
                    {
                        if (bot._MyX != bot.targetX || bot._MyY != bot.targetY)
                        {
                            int[] nextCoords;
                            bool walkDoor = false;

                            if (bot._MyX == door_x && bot._MyY == door_y)
                            {
                                // first walk out of the door, then check if you can walk after that!
                                walkDoor = true;
                                if (bot.targetX == doorstep_x && bot.targetY == doorstep_y)
                                {
                                    // just come out of the door
                                    squareState[,] stateMap = avatarStateMap(doorstep_x, doorstep_y);
                                    if (stateMap[doorstep_x, doorstep_y] == squareState.Open && (!_sqUnit[doorstep_x, doorstep_y]))
                                    {
                                        // doorstep is free
                                        nextCoords = new int[2];
                                        nextCoords[0] = doorstep_x;
                                        nextCoords[1] = doorstep_y;
                                    }
                                    else
                                    {
                                        nextCoords = null;
                                    }
                                }
                                else
                                {
                                    PathFinderFast Pathfinder = new PathFinderFast(GenerateGrid(bot.targetX, bot.targetY));
                                    List<PathFinderNode> Path = Pathfinder.FindPath(new Point(doorstep_x, doorstep_y), new Point(bot.targetX, bot.targetY));
                                    if (Path == null || Path.Count == 0)
                                    {
                                        nextCoords = null;
                                    }
                                    else
                                    {
                                        // after coming out of your door you'll be able to walk
                                        squareState[,] stateMap = avatarStateMap(doorstep_x, doorstep_y);
                                        if (stateMap[doorstep_x, doorstep_y] == squareState.Open && (!_sqUnit[doorstep_x, doorstep_y]))
                                        {
                                            // doorstep is free
                                            nextCoords = new int[2];
                                            nextCoords[0] = doorstep_x;
                                            nextCoords[1] = doorstep_y;
                                        }
                                        else
                                        {
                                            nextCoords = null;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                PathFinderFast Pathfinder = new PathFinderFast(GenerateGrid(bot.targetX, bot.targetY));
                                List<PathFinderNode> Path = Pathfinder.FindPath(new Point(bot._MyX, bot._MyY), new Point(bot.targetX, bot.targetY));
                                if (Path == null || Path.Count == 0)
                                {
                                    nextCoords = null;
                                }
                                else
                                {
                                    PathFinderNode NextPosition = Path[Path.Count - 2];
                                    nextCoords = new int[2];
                                    nextCoords[0] = NextPosition.X;
                                    nextCoords[1] = NextPosition.Y;
                                }
                            }
                            if (nextCoords == null)
                            {
                                if (bot.walking)
                                {
                                    bot._Sit = "";
                                    bot.targetX = bot._MyX;
                                    bot.targetY = bot._MyY;
                                    StopAvatarPacket stopMove = new StopAvatarPacket();
                                    stopMove.I = bot._MyAvatarID;
                                    string stopMovePacket = JsonConvert.SerializeObject(stopMove);
                                    sendText.Append("064");
                                    sendText.Append(stopMovePacket);
                                    sendText.Append("#");
                                    bot.walking = false;
                                }
                            }
                            else
                            {
                                bot.walking = true;
                                int nextX = nextCoords[0];
                                int nextY = nextCoords[1];
                                squareState nextState = _sqState[nextX, nextY];

                                if (!walkDoor)
                                {
                                    _sqUnit[bot._MyX, bot._MyY] = false;
                                }
                                _sqUnit[nextX, nextY] = true;

                                double nextHeight = 0;
                                nextHeight = (double)_sqHeight[nextX, nextY];

                                bot._MyZ = getNewDir(bot._MyX, bot._MyY, nextX, nextY);
                                bot._MyX = nextX;
                                bot._MyY = nextY;
                                //bot._MyZ = (int)nextHeight;

                                if (nextState == squareState.Seat)
                                {
                                    // Do Sit
                                    MoveAvatarPacket mvpack = new MoveAvatarPacket();
                                    mvpack.I = bot._MyAvatarID;
                                    mvpack.X = nextX;
                                    mvpack.Y = nextY;
                                    mvpack.H = bot._MyZ;
                                    string stringmvpack = JsonConvert.SerializeObject(mvpack);
                                    sendText.Append("057");
                                    sendText.Append(stringmvpack);
                                    sendText.Append("#");

                                    if (bot._MyX == bot.targetX && bot._MyY == bot.targetY)
                                    {
                                        bot._MyZ = _sqRot[bot._MyX, bot._MyY] * 2;
                                        bot._Sit = bot._MyZ.ToString() + "|" + _sqTile[bot._MyX, bot._MyY];
                                        StopAvatarPacket stopMove = new StopAvatarPacket();
                                        stopMove.I = bot._MyAvatarID;
                                        string stopMovePacket = JsonConvert.SerializeObject(stopMove);
                                        sendText.Append("064");
                                        sendText.Append(stopMovePacket);
                                        sendText.Append("#");

                                        SetSitPacket setSit = new SetSitPacket();
                                        setSit.I = bot._MyAvatarID;
                                        setSit.S = bot._Sit;
                                        string SetSitPacket = JsonConvert.SerializeObject(setSit);
                                        sendText.Append("081");
                                        sendText.Append(SetSitPacket);
                                        sendText.Append("#");
                                    }
                                }
                                else
                                {
                                    bot._Sit = "";
                                    MoveAvatarPacket mvpack = new MoveAvatarPacket();
                                    mvpack.I = bot._MyAvatarID;
                                    mvpack.X = nextX;
                                    mvpack.Y = nextY;
                                    mvpack.H = bot._MyZ;
                                    string stringmvpack = JsonConvert.SerializeObject(mvpack);
                                    sendText.Append("057");
                                    sendText.Append(stringmvpack);
                                    sendText.Append("#");

                                    if (bot._MyX == bot.targetX && bot._MyY == bot.targetY)
                                    {
                                        StopAvatarPacket stopMove = new StopAvatarPacket();
                                        stopMove.I = bot._MyAvatarID;
                                        string stopMovePacket = JsonConvert.SerializeObject(stopMove);
                                        sendText.Append("064");
                                        sendText.Append(stopMovePacket);
                                        sendText.Append("#");
                                        bot.walking = false;
                                    }
                                }
                            }
                        }
                    }

                }
                catch (Exception e)
                {
                    Console.WriteLine("BOTWALK ERROR: {0}", e);
                }
                string sendTextString = sendText.ToString();
                if (sendTextString != "")
                {
                    foreach (ConnectedUser usr in _Users.Values)
                    {
                        usr.sendData(sendTextString);
                    }
                }
                Thread.Sleep(480); // 480 milliseconds
            }
        }
Exemple #18
0
 public PathFindingAdapter(Map map)
 {
     _map     = map;
     _grid    = new byte[_map.Width, _map.Height];
     _adaptee = new PathFinderFast(_grid);
 }
Exemple #19
0
        /// <summary>
        /// Creates the shortest route between two points, used in Move()
        /// </summary>
        private void Path(Vector3I targetPosition)
        {
            //create a grid with all blocks in the 2d plane
            byte[,] grid = new byte[World.Map.Width, World.Map.Length];
            PathFinder pathFinder;

            Vector3I botPos = Position.ToBlockCoords();

            //Loop through all XZ coordinates of the map
            for (int y = 0; y < World.Map.Length; y++)
            {
                for (int x = 0; x < World.Map.Width; x++)
                {
                    //Find all valid positions, set as either an available tile or blocked tile
                    if (ValidBlock(new Vector3I(x, y, botPos.Z)) && ValidBlock(new Vector3I(x, y, botPos.Z - 1)))
                    {
                        grid[x, y] = PathFinderHelper.EMPTY_TILE;
                    }
                    else
                    {
                        grid[x, y] = PathFinderHelper.BLOCKED_TILE;
                    }
                }
            }

            //set pathFinder to the grid just created, disallow diagonals
            pathFinder = new PathFinder(grid);
            pathFinder.Diagonals = false;
            pathFinder.PunishChangeDirection = false;

            Point botInitPoint = new Point(botPos.X, botPos.Y);
            Point botFinalPoint = new Point(NewPosition.ToBlockCoords().X, NewPosition.ToBlockCoords().Y);

            //Implement A* to determine optimal path between two spots
            List<PathFinderNode> path = new PathFinderFast(grid).FindPath(botInitPoint, botFinalPoint);

            if (path == null)
            {
                //There is no path, stop moving
                beganMoving = false;
                isMoving = false;
                return;
            }

            //Convert node to block positions
            foreach(PathFinderNode node in path)
            {
                PositionList.Add(new Vector3I(node.X, node.Y, botPos.Z));
            }

            //A* returns points in the opposite order needed, reverse in order to get proper order
            PositionList.Reverse();
        }
Exemple #20
0
        public List<PathFinderNode> buildPath(System.Drawing.Point Start)
        {
            List<PathFinderNode> path;
            var pather = new PathFinderFast(grid);
            pather.Diagonals = false;
            foreach (var dest in this.Dests)
            {
                path = pather.FindPath(Start, dest);
                if (path != null)
                    return path;
            }

            return null;
        }
	public void InitPathFinder()
	{
		mPathFinder = new PathFinderFast(mGrid, this);
		
		mPathFinder.Formula                 = HeuristicFormula.Manhattan;
		//if false then diagonal movement will be prohibited
        mPathFinder.Diagonals               = false;
		//if true then diagonal movement will have higher cost
        mPathFinder.HeavyDiagonals          = false;
		//estimate of path length
        mPathFinder.HeuristicEstimate       = 6;
        mPathFinder.PunishChangeDirection   = false;
        mPathFinder.TieBreaker              = false;
        mPathFinder.SearchLimit             = 1000000;
        mPathFinder.DebugProgress           = false;
        mPathFinder.DebugFoundPath          = false;
	}
Exemple #22
0
 public bool checkWalk(int startX, int startY, int targetX, int targetY)
 {
     if (startX == door_x && startY == door_y)
     {
         return true;
     }
     else
     {
         if ((!(targetX == door_x && targetY == door_y)) && targetX >= 0 && targetY >= 0 && targetX < breed && targetY < lang)
         {
             PathFinderFast Pathfinder = new PathFinderFast(GenerateGrid(targetX, targetY));
             List<PathFinderNode> Path = Pathfinder.FindPath(new Point(startX, startY), new Point(targetX, targetY));
             if (Path == null || Path.Count == 0)
             {
                 return false;
             }
             else
             {
                 return true;
             }
         }
         else
         {
             return false;
         }
     }
 }
Exemple #23
0
 /// <summary>
 /// 向目标点跑去
 /// </summary>
 /// <param name="destination">目标点(窗口坐标系)</param>
 public void RunTo(Point destination)
 {
     if (isActionLocked) { return; }
     //特殊坐标判断处理
     Point end = Scene.GetGameCoordinate(destination);
     if ((int)Coordinate.X == end.X && (int)Coordinate.Y == end.Y) { return; } //目的地是自己脚底则取消移动
     if (end.X < 0 || end.Y < 0 || end.X > Scene.TerrainMatrix.GetUpperBound(0) || end.Y > Scene.TerrainMatrix.GetUpperBound(0)) { return; } //目的地超出坐标系范围
     //采用路径预测法中的(两点线段检测(直线等分逐测算法)+A*寻路算法组合)
     bool findObstacle = false;
     Point start = Scene.GetWindowCoordinate(Coordinate);
     double angle = Global.GetRadian(start, destination);
     int detectNum = (int)(Global.GetDistance(start, destination));
     for (int i = 0; i <= detectNum; i++) {
         int x = (int)(Math.Cos(angle) * i + destination.X);
         int y = (int)(Math.Sin(angle) * i + destination.Y);
         Point p = Scene.GetGameCoordinate(new Point(x, y));
         if (Scene.DynamicMatrix[(int)p.X, (int)p.Y] == 0) {
             findObstacle = true;
             break;
         }
     }
     if (findObstacle) {
         PathFinderFast pathFinderFast = new PathFinderFast(Scene.DynamicMatrix) {
             Formula = HeuristicFormula.Manhattan,
             Diagonals = true,
             HeuristicEstimate = 2,
             SearchLimit = Scene.TerrainMatrix.GetUpperBound(0) * 2, //寻径限度(太小可能导致找不到路径)
         };
         List<PathFinderNode> pathTemp = pathFinderFast.FindPath(new Point2D((int)Coordinate.X, (int)Coordinate.Y), new Point2D((int)end.X, (int)end.Y));
         if (pathTemp != null && pathTemp.Count > 1) {
             path = pathTemp;
             path.Remove(path[path.Count - 1]);
             StraightRunTo(new Point(path[path.Count - 1].X, path[path.Count - 1].Y));
         }
     } else {
         if (path != null) { path.Clear(); }
         StraightRunTo(end);
     }
 }
Exemple #24
0
        public override void ComputePossibleMoves(List <Move> possibleMoves, List <Position> includedPositions, MoveFilter moveFilter)
        {
            if ((moveFilter & MoveFilter.Move) == 0)
            {
                return;
            }

            if (Unit.Power == 0)
            {
                return;
            }

            // Never called by controls
            List <Tile>     openList     = new List <Tile>();
            List <Tile>     reachedTiles = new List <Tile>();
            List <Position> reachedPos   = new List <Position>();

            Tile startTile = Unit.Game.Map.GetTile(Unit.Pos);

            openList.Add(startTile);
            reachedTiles.Add(startTile);

            while (openList.Count > 0)
            {
                Tile tile = openList[0];
                openList.RemoveAt(0);

                // Distance at all
                double d = tile.Pos.GetDistanceTo(this.Unit.Pos);
                if (d >= Range)
                {
                    continue;
                }

                foreach (Tile n in tile.Neighbors)
                {
                    if (n.Pos == Unit.Pos)
                    {
                        continue;
                    }
                    if (includedPositions != null)
                    {
                        if (!includedPositions.Contains(n.Pos))
                        {
                            continue;
                        }
                    }
                    if (!reachedTiles.Contains(n))
                    {
                        reachedTiles.Add(n);

                        double d1 = n.Pos.GetDistanceTo(this.Unit.Pos);
                        if (d1 < Range)
                        {
                            openList.Add(n);

                            Move move = new Move();
                            move.MoveType = MoveType.Move;

                            PathFinderFast pathFinder = new PathFinderFast(Unit.Owner.Game.Map);

                            move.Positions = pathFinder.FindPath(Unit, Unit.Pos, n.Pos);
                            if (move.Positions != null)
                            {
                                move.UnitId   = Unit.UnitId;
                                move.PlayerId = Unit.Owner.PlayerModel.Id;

                                while (move.Positions.Count > Range + 1)
                                {
                                    move.Positions.RemoveAt(move.Positions.Count - 1);
                                }

                                Position finalPos = move.Positions[move.Positions.Count - 1];
                                if (!reachedPos.Contains(finalPos))
                                {
                                    reachedPos.Add(finalPos);


                                    // Do not move on other units
                                    if (Unit.Game.Map.GetTile(finalPos).Unit == null)
                                    {
                                        possibleMoves.Add(move);
                                    }
                                    else
                                    {
                                        //int x = 0;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }