Exemple #1
0
    /**
     * Resets the grid and creates a new path. The higher the
     * difficulty, the shorter the generated path will be.
     */
    public void GeneratePath(GameState.Difficulty diff)
    {
        UpdateDimension(Width, Length);

        Position pos      = (Position)startPos.Clone();
        Position waypoint = (Position)startPos.Clone();

        Direction dir           = Direction.right;
        int       tilesToExpand = 0;

        while (true)
        {
            // reached the end, done
            if (pos == endPos)
            {
                return;
            }

            // figure out how many tiles we CAN expand in the current direction
            int availableTiles = pos.AvailableUnitsUntilBorder(this, dir);
            Debug.Assert(availableTiles > 0);
            Debug.Assert(dir != Direction.up); // should not go up!

            // figure out how many tiles we WILL expand based on difficulty
            switch (diff)
            {
            case (GameState.Difficulty.easy):
                if (dir == Direction.right || dir == Direction.left)
                {
                    tilesToExpand = UnityEngine.Random.Range(
                        Math.Min(1, (int)(availableTiles * 0.9f)),
                        availableTiles + 1);         // +1 because Random.Range is exclusive for end
                }
                else
                {
                    tilesToExpand = 2;     // go down two at a time to ensure maximum length
                }
                break;

            case (GameState.Difficulty.medium):
                if (dir == Direction.right || dir == Direction.left)
                {
                    tilesToExpand = UnityEngine.Random.Range(
                        Math.Min(1, (int)(availableTiles * 0.4f)),
                        Math.Min(1, (int)(availableTiles * 0.8f)) + 1);
                }
                else
                {
                    tilesToExpand = UnityEngine.Random.Range(2, 4);
                }
                break;

            case (GameState.Difficulty.hard):
                if (dir == Direction.right || dir == Direction.left)
                {
                    tilesToExpand = UnityEngine.Random.Range(
                        Math.Min(1, (int)(availableTiles * 0.4f)),
                        Math.Min(1, (int)(availableTiles * 0.2f)) + 1);
                }
                else
                {
                    tilesToExpand = 3;
                }
                break;

            default:
                Debug.LogError("Invalid difficulty received: " + diff.ToString());
                return;
            }
            tilesToExpand = Math.Min(tilesToExpand, availableTiles);

            // move the waypoint to the destination
            waypoint.Move(tilesToExpand, dir);
            // double check that all assumptions are valid
            // Debug.Log("# tiles to expand: " + tilesToExpand + ", destination: " + waypoint.ToString() + ", direction: " + dir.ToString());
            Debug.Assert(!waypoint.IsOnBorder(this));
            Debug.Assert(!waypoint.OutOfBound(this));
            Debug.Assert(
                state[waypoint.X, waypoint.Y] == TileType.terrain || state[waypoint.X, waypoint.Y] == TileType.end);
            Debug.Assert(waypoint.X <= endPos.X);
            Debug.Assert(waypoint.Y <= endPos.Y);

            // if at the bottom-most row and moving right, then bring the path to the finish line
            if (waypoint.Y == endPos.Y && waypoint.X != endPos.X && dir == Direction.right)
            {
                waypoint.UpdatePosition(endPos.X, endPos.Y);
            }

            // if one or two units above end point, bring the path to finish line
            if (endPos.Y - waypoint.Y <= 2 && waypoint.X == endPos.X && dir == Direction.down)
            {
                waypoint.UpdatePosition(endPos.X, endPos.Y);
            }

            // save the waypoint
            waypoints.Add((Position)waypoint.Clone());

            // update the state to build the path
            while (true)
            {
                pos.Move(1, dir);

                if (pos == endPos)
                {
                    break;
                }

                state[pos.X, pos.Y] = TileType.path;

                if (pos == waypoint)
                {
                    break;
                }
            }

            // ============================================
            // figure out direction for the next iteration
            // ============================================

            // if at the bottom row, just go right next time so it will hit the end
            if (pos.Y == length - 2)
            {
                dir = Direction.right;
                continue;
            }

            if (dir == Direction.right || dir == Direction.left)
            {
                dir = Direction.down;
                continue;
            }

            if (dir == Direction.down)
            {
                // if current row is one above the end point, go down one more
                if (pos.Y + 1 == endPos.Y)
                {
                    dir = Direction.down;
                    continue;
                }

                int leftRoom  = pos.AvailableUnitsUntilBorder(this, Direction.left);
                int rightRoom = pos.AvailableUnitsUntilBorder(this, Direction.right);
                dir = leftRoom > rightRoom ? Direction.left : Direction.right;
                continue;
            }
        }
    }
Exemple #2
0
 public void GenerateMaze(GameState.Difficulty difficulty)
 {
     currentGrid.GeneratePath(difficulty);
     DrawTiles();
 }