예제 #1
0
        public void TestJumpRecursive()
        {
            // . f .
            // . X j
            // . . .
            // p . g

            // p   : (0, 3)
            // g   : (2, 3)
            // dir : NORTHEAST
            // j   : (2, 1)

            JPS jps = new JPS(new bool[5, 4] {
                { false, false, false, false },
                { false, true, false, false },
                { false, false, false, false },
                { false, false, false, false },
                { false, false, false, false },
            });

            Int2      p   = new Int2(0, 3);
            Int2      g   = new Int2(2, 3);
            EDirFlags dir = EDirFlags.NORTHEAST;

            Int2 result = new Int2(0, 0);

            Assert.True(jps.TryJump(p, dir, g, ref result));
            Assert.Equal(new Int2(2, 1), result);
        }
예제 #2
0
        public void TESTSuccesorsDir()
        {
            JPS jps = new JPS(new bool[5, 5] {
                { false, false, false, false, false },
                { false, false, false, false, false },
                { false, false, false, true, false },
                { false, false, false, false, false },
                { false, false, false, false, false },
            });

            Int2 o = new Int2(2, 2);

            // . . F
            // . o X
            // . . P
            EDirFlags forcedNeighbourDir = jps.ForcedNeighbourDir(o, EDirFlags.NORTHWEST);

            Assert.Equal(EDirFlags.NORTHEAST, forcedNeighbourDir);

            // N N .
            // N o X
            // . . P
            EDirFlags naturalNeighbours = JPS.NaturalNeighbours(EDirFlags.NORTHEAST);

            Assert.Equal(EDirFlags.NORTHEAST | EDirFlags.NORTH | EDirFlags.EAST, naturalNeighbours);

            // S S S
            // S o X
            // . . P
            EDirFlags succesorsDir = jps.SuccesorsDir(o, EDirFlags.NORTHWEST);

            Assert.Equal(EDirFlags.NORTHWEST | EDirFlags.NORTH | EDirFlags.NORTHEAST | EDirFlags.WEST, succesorsDir);
        }
예제 #3
0
        public static EDirFlags DiagonalToNorthSouth(EDirFlags dir)
        {
            if ((dir & (EDirFlags.NORTHEAST | EDirFlags.NORTHWEST)) != EDirFlags.NONE)
            {
                return(EDirFlags.NORTH);
            }

            if ((dir & (EDirFlags.SOUTHEAST | EDirFlags.SOUTHWEST)) != EDirFlags.NONE)
            {
                return(EDirFlags.SOUTH);
            }

            return(EDirFlags.NONE);
        }
예제 #4
0
        public static EDirFlags DiagonalToEastWest(EDirFlags dir)
        {
            if ((dir & (EDirFlags.NORTHEAST | EDirFlags.SOUTHEAST)) != EDirFlags.NONE)
            {
                return(EDirFlags.EAST);
            }

            if ((dir & (EDirFlags.NORTHWEST | EDirFlags.SOUTHWEST)) != EDirFlags.NONE)
            {
                return(EDirFlags.WEST);
            }

            return(EDirFlags.NONE);
        }
 internal void Reset()
 {
     isStartOrGoal = false;
     mIsDiagonalOn = false;
     mIsStraightOn = false;
     mIsWallOn     = false;
     mBase.color   = Color.white;
     for (int i = 0b10000000; i > 0; i >>= 1)
     {
         EDirFlags dir   = (EDirFlags)i;
         int       index = DirFlags.ToArrayIndex(dir);
         dirImages[index].color = InvisibleColor;
         dirTexts[index].text   = string.Empty;
     }
 }
예제 #6
0
        public static int ToArrayIndex(EDirFlags dir)
        {
            switch (dir)
            {
            case EDirFlags.NORTHWEST: return(0);

            case EDirFlags.NORTH: return(1);

            case EDirFlags.NORTHEAST: return(2);

            case EDirFlags.WEST: return(3);

            case EDirFlags.EAST: return(4);

            case EDirFlags.SOUTHWEST: return(5);

            case EDirFlags.SOUTH: return(6);

            case EDirFlags.SOUTHEAST: return(7);

            default: return(-1);
            }
        }
예제 #7
0
 public static Int2 ToPos(EDirFlags dir)
 {
     return(DirToPos[dir]);
 }
예제 #8
0
 public static bool IsDiagonal(EDirFlags dir)
 {
     return((dir & (EDirFlags.NORTHEAST | EDirFlags.NORTHWEST | EDirFlags.SOUTHEAST | EDirFlags.SOUTHWEST)) != EDirFlags.NONE);
 }
예제 #9
0
 public static bool IsStraight(EDirFlags dir)
 {
     return((dir & (EDirFlags.NORTH | EDirFlags.SOUTH | EDirFlags.EAST | EDirFlags.WEST)) != EDirFlags.NONE);
 }
예제 #10
0
        void MarkPrimary()
        {
            for (int y = 0; y < Height; ++y)
            {
                for (int x = 0; x < Width; ++x)
                {
                    Int2 p = new Int2(x, y);

                    if (IsWalkable(p))
                    {
                        continue;
                    }

                    for (int d = 0b10000000; d > 0b00001111; d >>= 1)
                    {
                        EDirFlags dir      = (EDirFlags)d;
                        var       primaryP = p.Foward(dir);
                        var       primaryB = GetBlockOrNull(primaryP);
                        if (primaryB == null)
                        {
                            continue;
                        }

                        switch (dir)
                        {
                        case EDirFlags.NORTHEAST:
                        {
                            var p1 = p.Foward(EDirFlags.NORTH);
                            var p2 = p.Foward(EDirFlags.EAST);
                            if (IsWalkable(p1) && IsWalkable(p2))
                            {
                                primaryB.JumpDirFlags |= EDirFlags.SOUTH | EDirFlags.WEST;
                            }
                            break;
                        }

                        case EDirFlags.SOUTHEAST:
                        {
                            var p1 = p.Foward(EDirFlags.SOUTH);
                            var p2 = p.Foward(EDirFlags.EAST);
                            if (IsWalkable(p1) && IsWalkable(p2))
                            {
                                primaryB.JumpDirFlags |= EDirFlags.NORTH | EDirFlags.WEST;
                            }
                            break;
                        }

                        case EDirFlags.NORTHWEST:
                        {
                            var p1 = p.Foward(EDirFlags.NORTH);
                            var p2 = p.Foward(EDirFlags.WEST);
                            if (IsWalkable(p1) && IsWalkable(p2))
                            {
                                primaryB.JumpDirFlags |= EDirFlags.SOUTH | EDirFlags.EAST;
                            }
                            break;
                        }

                        case EDirFlags.SOUTHWEST:
                        {
                            var p1 = p.Foward(EDirFlags.SOUTH);
                            var p2 = p.Foward(EDirFlags.WEST);
                            if (IsWalkable(p1) && IsWalkable(p2))
                            {
                                primaryB.JumpDirFlags |= EDirFlags.NORTH | EDirFlags.EAST;
                            }
                            break;
                        }

                        default:
                            throw new ArgumentException();
                        }
                    }
                }
            }
        }
    private void Indicate(bool mIsStraightOn, bool mIsDiagonalOn, bool mIsWallOn)
    {
        for (int i = 0b10000000; i > 0; i >>= 1)
        {
            EDirFlags dir   = (EDirFlags)i;
            int       dist  = mBakedBlock.GetDistance(dir);
            int       index = DirFlags.ToArrayIndex(dir);
            if (dist > 0)
            {
                if ((dir & StraightDirs) == dir)
                {
                    if (mIsStraightOn)
                    {
                        dirImages[index].color = InvisibleColor;
                        dirTexts[index].text   = dist.ToString();
                    }
                    else
                    {
                        dirImages[index].color = InvisibleColor;
                        dirTexts[index].text   = string.Empty;
                    }
                }

                if ((dir & DiagonalDirs) == dir)
                {
                    if (mIsDiagonalOn)
                    {
                        dirImages[index].color = InvisibleColor;
                        dirTexts[index].text   = dist.ToString();
                    }
                    else
                    {
                        dirImages[index].color = InvisibleColor;
                        dirTexts[index].text   = string.Empty;
                    }
                }
            }
            else if (dist == 0)
            {
                if (mIsWallOn)
                {
                    dirImages[index].color = Color.red;
                    dirTexts[index].text   = dist.ToString();
                }
                else
                {
                    dirImages[index].color = InvisibleColor;
                    dirTexts[index].text   = string.Empty;
                }
            }
            else
            {
                if ((dir & StraightDirs) == dir)
                {
                    if (mIsWallOn && mIsStraightOn)
                    {
                        dirImages[index].color = Color.yellow;
                        dirTexts[index].text   = dist.ToString();
                    }
                    else
                    {
                        dirImages[index].color = InvisibleColor;
                        dirTexts[index].text   = string.Empty;
                    }
                }

                if ((dir & DiagonalDirs) == dir)
                {
                    if (mIsWallOn && mIsDiagonalOn)
                    {
                        dirImages[index].color = Color.yellow;
                        dirTexts[index].text   = dist.ToString();
                    }
                    else
                    {
                        dirImages[index].color = InvisibleColor;
                        dirTexts[index].text   = string.Empty;
                    }
                }
            }
        }
    }
예제 #12
0
        public bool Step(int stepCount)
        {
            for (int step = stepCount; step > 0; --step)
            {
                if (mOpenList.Count == 0)
                {
                    return(false);
                }

                AStarNode curr = mOpenList.Dequeue();
                if (curr == mGoal)
                {
                    return(true);
                }

                mCloseList.Add(curr);

                for (int i = 0b10000000; i > 0; i >>= 1)
                {
                    EDirFlags dir      = (EDirFlags)i;
                    Int2      dp       = DirFlags.ToPos(dir);
                    AStarNode adjacent = GetNodeOrNull(curr.Position + dp);
                    if (adjacent == null)
                    {
                        continue;
                    }
                    if (IsWall(adjacent.Position))
                    {
                        continue;
                    }

                    if (DirFlags.IsDiagonal(dir))
                    { // for prevent corner cutting
                        if (IsWall(curr.Position + new Int2(dp.X, 0)) || IsWall(curr.Position + new Int2(0, dp.Y)))
                        {
                            continue;
                        }
                    }

                    if (mCloseList.Contains(adjacent))
                    {
                        continue;
                    }

                    int nextG = G(curr, adjacent);
                    if (!mOpenList.Contains(adjacent))
                    {
                        adjacent.Parent = curr;
                        adjacent.G      = nextG;
                        adjacent.H      = H(adjacent, mGoal);
                        mOpenList.Enqueue(adjacent, adjacent.F);
                    }
                    else if (nextG < adjacent.G)
                    {
                        adjacent.Parent = curr;
                        adjacent.G      = nextG;
                        adjacent.H      = H(adjacent, mGoal);
                        mOpenList.UpdatePriority(adjacent, adjacent.F);
                    }
                }
            }
            return(false);
        }