Beispiel #1
0
    //-------------//
    // Constructor //
    //-------------//

    /// <summary>
    /// Instantiates a new level path in the given world.
    /// </summary>
    /// <param name="parentWorld">The path's parent world.</param>
    public LevelPath(LevelWorld parentWorld)
    {
        ParentWorld = parentWorld;
        ChildNodes = new List<LevelNode>();

        ParentWorld.AddPath(this);
    }
Beispiel #2
0
    //-------------//
    // Constructor //
    //-------------//

    /// <summary>
    /// Instantiates a new level path in the given world.
    /// </summary>
    /// <param name="parentWorld">The path's parent world.</param>
    public LevelPath(LevelWorld parentWorld)
    {
        ParentWorld = parentWorld;
        ChildNodes  = new List <LevelNode>();

        ParentWorld.AddPath(this);
    }
Beispiel #3
0
 public void LevelCompleted(LevelWorld world, int levelNumber)
 {
     if (!levelComplete.ContainsKey(world.getKey()))
     {
         levelComplete.Add(world.getKey(), new bool[world.levelCount]);
     }
     levelComplete[world.getKey()][levelNumber] = true;
 }
Beispiel #4
0
 public bool IsLevelCompleted(LevelWorld world, int levelNumber)
 {
     if (levelComplete.ContainsKey(world.getKey()))
     {
         return(levelComplete[world.getKey()][levelNumber]);
     }
     return(false);
 }
Beispiel #5
0
    //---------------//
    // Build Helpers //
    //---------------//

    /// <summary>
    /// Continues building the world given the current active paths in it.
    /// </summary>
    /// <param name="world">The world to continue building.</param>
    /// <param name="currentActivePaths">The current active paths in the world.</param>
    /// <returns>The world after all active paths have completed.</returns>
    private LevelWorld BuildWorldFromExistingPaths(LevelWorld world, List <LevelPath> currentActivePaths)
    {
        while (currentActivePaths.Count > 0)
        {
            List <LevelPath> nextIterationActivePaths = new List <LevelPath>();
            foreach (var path in currentActivePaths)
            {
                // Verify that the path has at least one node already
                LevelNode tailNode = path.TailNode;
                Debug.Assert(tailNode != null);

                // Get the possible directions to move
                List <Direction> possibleDirections = GetPossibleDirectionsForPathContinuation(path);

                // Check to see if we're out of possible directions
                if (possibleDirections.Count == 0)
                {
                    // Note that we don't add this current path to the next iteration's paths; this path is done
                    continue;
                }

                // Continue the path in a random direction
                Direction dirToContinueIn        = GetRandomDirection(possibleDirections);
                bool      addPathToNextIteration = ProcessPathContinuation(path, tailNode, dirToContinueIn);
                if (addPathToNextIteration)
                {
                    nextIterationActivePaths.Add(path);
                }

                // Check for a split
                float splitCheck = UnityEngine.Random.Range(0.0f, 1.0f);
                if (splitCheck < splitChance)
                {
                    possibleDirections.Remove(dirToContinueIn);

                    // Check if there are any directions to continue in
                    if (possibleDirections.Count != 0)
                    {
                        // Get the direction for the new node
                        Direction dirToSplitIn = GetRandomDirection(possibleDirections);

                        // Create the new path and add a node to it
                        LevelPath splitPath = new LevelPath(world);
                        addPathToNextIteration = ProcessPathContinuation(splitPath, tailNode, dirToSplitIn);
                        if (addPathToNextIteration)
                        {
                            nextIterationActivePaths.Add(splitPath);
                        }
                    }
                }
            }

            // Update the current paths for the next iteration
            currentActivePaths = nextIterationActivePaths;
        }

        return(world);
    }
Beispiel #6
0
 private void BuildWorld(LevelWorld levelWolrld)
 {
     initGridLayout();
     setTitleText(levelWolrld.worldName, 0);
     for (int i = 0; i < levelWolrld.levelCount; i++)
     {
         PlaceLevelButton(levelWolrld, i);
     }
     //Set the UI of the level selection
 }
Beispiel #7
0
    public void UpdateInfoLevelSecret(LevelWorld level)
    {
        LaunchLevelButton.gameObject.SetActive(false);
        LevelName.text   = "Coin To unlock : " + ProgressionManagement.Instance.TotalCoinsWorldGot[ProgressionManagement.Instance.ActiveWorld] + "/" + ProgressionManagement.Instance.TotalCoinsWorld[ProgressionManagement.Instance.ActiveWorld];
        levelNameForLoad = level.levelWorld + "-" + level.levelNum;

        Death.text = "";
        Coin.text  = "";
        Timer.text = "";

        Score.gameObject.SetActive(false);
    }
Beispiel #8
0
    /// <summary>
    /// Returns whether or not the given coordinates lie inside the given world.
    /// </summary>
    /// <param name="world">The world to check.</param>
    /// <param name="row">The row portion of the coordinates to check.</param>
    /// <param name="col">The column portion of the coodinates to check.</param>
    /// <returns>True if the coodinates are inside the world; false otherwise.</returns>
    private bool AreCoordinatesInsideWorld(LevelWorld world, int row, int col)
    {
        // Check top and left
        if (row < 0 || col < 0)
        {
            return(false);
        }

        // Check bottom and right
        if (row >= world.RowsInWorld || col >= world.ColumnsInWorld)
        {
            return(false);
        }

        return(true);
    }
Beispiel #9
0
    // Use this for initialization
    void Start()
    {
        LevelBuilder builder   = GetComponent <LevelBuilder>();
        LevelNode    startNode = builder.BuildNewWorld();

        world = startNode.ParentWorld;

        Dictionary <Direction, Quaternion> directions = new Dictionary <Direction, Quaternion>()
        {
            { Direction.UP, Quaternion.Euler(0, 0, 0) },
            { Direction.RIGHT, Quaternion.Euler(0, 0, 270) },
            { Direction.DOWN, Quaternion.Euler(0, 0, 180) },
            { Direction.LEFT, Quaternion.Euler(0, 0, 90) }
        };

        float rowOffset = world.RowsInWorld / 2.0f;
        float colOffset = world.ColumnsInWorld / 2.0f;

        for (int rr = 0; rr < world.RowsInWorld; rr++)
        {
            for (int cc = 0; cc < world.ColumnsInWorld; cc++)
            {
                LevelNode currNode = world.ChildNodes[rr, cc];

                if (currNode == null)
                {
                    Instantiate(tile, new Vector3(cc - colOffset, -1 * (rr - rowOffset)), Quaternion.identity);
                }

                else
                {
                    foreach (var dir in directions.Keys)
                    {
                        if (!currNode.OpenSides.Contains(dir))
                        {
                            Instantiate(wall, new Vector3(cc - colOffset, -1 * (rr - rowOffset)), directions[dir]);
                        }
                    }
                }
            }
        }
    }
Beispiel #10
0
    /// <summary>
    /// Finds and returns the coordinates of the first empty node in the given world.
    /// </summary>
    /// <param name="world">The world whose node to return.</param>
    /// <param name="mustBeAdjacentToNonEmptyNode">Whether or not the empty node must be adjacent to a non-empty node.</param>
    /// <returns>The coordinates of the empty node, or null if no node.</returns>
    private Tuple <int, int> GetCoordinatesOfEmptyNodeInWorld(LevelWorld world, bool mustBeAdjacentToNonEmptyNode = false)
    {
        for (int rr = 0; rr < world.ChildNodes.GetLength(0); rr++)
        {
            for (int cc = 0; cc < world.ChildNodes.GetLength(1); cc++)
            {
                LevelNode currNode = world.ChildNodes[rr, cc];
                if (currNode == null)
                {
                    LevelNode adjacentNonEmptyNode = GetAdjacentNonEmptyNode(world, rr, cc);
                    if (!mustBeAdjacentToNonEmptyNode || adjacentNonEmptyNode != null)
                    {
                        return(new Tuple <int, int>(rr, cc));
                    }
                }
            }
        }

        return(null);
    }
Beispiel #11
0
 public void UpdateInfoLevel(LevelWorld level)
 {
     LaunchLevelButton.gameObject.SetActive(true);
     LevelName.text   = "Level " + (level.levelWorld + 1) + "-" + (level.levelNum + 1);
     levelNameForLoad = level.levelWorld + "-" + level.levelNum;
     if (level.levelcomplete)
     {
         Death.text   = level.Death + "";
         Coin.text    = level.CoinPlayer + "/" + level.CoinTotal;
         Timer.text   = (Mathf.FloorToInt(level.Timer / 6000)).ToString("00") + ":" + (Mathf.FloorToInt((level.Timer % 6000) / 100)).ToString("00") + ":" + (Mathf.FloorToInt((level.Timer % 6000) % 100)).ToString("00");
         Score.sprite = ScoreSprite[level.Score - 3];
         Score.gameObject.SetActive(true);
     }
     else
     {
         Score.gameObject.SetActive(false);
         Coin.text  = "0/" + level.CoinTotal;
         Death.text = "";
         Timer.text = "";
     }
 }
Beispiel #12
0
    private void PlaceLevelButton(LevelWorld levelWorld, int levelnumber)
    {
        GameObject button = GameObjectUtil.Instantiate(levelButton, Vector2.zero, levelsCanvas.transform);
        Button     b      = button.GetComponent <Button>();

        button.GetComponentInChildren <Text>().text = levelnumber.ToString();

        if (UIManager.Instance.isLevelCompleted(levelWorld, levelnumber))
        {
            button.transform.GetChild(2).gameObject.SetActive(true);
            b.onClick.AddListener(() => clickLevel(levelWorld, levelnumber));
            ///TODO: need to add mark that level is complete
        }
        else if (!UIManager.Instance.isLevelOpen(levelWorld, levelnumber))
        {
            button.transform.GetChild(1).gameObject.SetActive(true);
        }
        else
        {
            b.onClick.AddListener(() => clickLevel(levelWorld, levelnumber));
        }

        button.transform.SetParent(panel.transform);
    }
Beispiel #13
0
    /// <summary>
    /// Returns a randomly selected non-empty node adjacent to the node with the given coordinates.
    /// </summary>
    /// <param name="world">The world whose node to return.</param>
    /// <param name="rowOfNode">The row of the node whose adjacent node to return.</param>
    /// <param name="colOfNode">The column of the node whose adjacent node to return.</param>
    /// <returns>The adjacent, non-empty node, or null if no node.</returns>
    private LevelNode GetAdjacentNonEmptyNode(LevelWorld world, int rowOfNode, int colOfNode)
    {
        List <Direction> directions = new List <Direction>()
        {
            Direction.UP,
            Direction.RIGHT,
            Direction.DOWN,
            Direction.LEFT
        };

        List <LevelNode> adjacentNonEmptyNodes = new List <LevelNode>();

        // Find all non-empty adjacent nodes
        foreach (var dir in directions)
        {
            Tuple <int, int> coordinates = GetNewCoordinatesInDirection(rowOfNode, colOfNode, dir);
            int newRow = coordinates.First;
            int newCol = coordinates.Second;

            if (AreCoordinatesInsideWorld(world, newRow, newCol) && world.ChildNodes[newRow, newCol] != null)
            {
                adjacentNonEmptyNodes.Add(world.ChildNodes[newRow, newCol]);
            }
        }

        // Check if we have no adjacent nodes
        if (adjacentNonEmptyNodes.Count == 0)
        {
            return(null);
        }

        // If we do, then return one at random
        int index = UnityEngine.Random.Range(0, adjacentNonEmptyNodes.Count);

        return(adjacentNonEmptyNodes[index]);
    }
Beispiel #14
0
 public bool isLevelOpen(LevelWorld world, int level)
 {
     return(levelCretion.isLevelOpen(world, level));
 }
Beispiel #15
0
    /// <summary>
    /// Returns whether or not the given coordinates lie inside the given world.
    /// </summary>
    /// <param name="world">The world to check.</param>
    /// <param name="row">The row portion of the coordinates to check.</param>
    /// <param name="col">The column portion of the coodinates to check.</param>
    /// <returns>True if the coodinates are inside the world; false otherwise.</returns>
    private bool AreCoordinatesInsideWorld(LevelWorld world, int row, int col)
    {
        // Check top and left
        if (row < 0 || col < 0)
        {
            return false;
        }

        // Check bottom and right
        if (row >= world.RowsInWorld || col >= world.ColumnsInWorld)
        {
            return false;
        }

        return true;
    }
Beispiel #16
0
    /// <summary>
    /// Builds a new world with the class's parameters and returns the start node of the world.
    /// </summary>
    /// <exception cref="InvalidOperationException">Thrown if world dimensions, start coordinates, or split chance is invalid.</exception>
    /// <returns>The start node in the new world.</returns>
    public LevelNode BuildNewWorld()
    {
        // Verify world dimensions
        if (rowsInWorld < 1 || colsInWorld < 1)
        {
            throw new InvalidOperationException(
                      string.Format("Invalid world dimensions ({0}, {1}). Dimensions must be >= 1.", rowsInWorld, colsInWorld));
        }

        // Verify split chance
        if (splitChance < 0 || splitChance > 1)
        {
            throw new InvalidOperationException(
                      string.Format("Invalid split chance {0}. Split chance must be >= 0 and <= 1.", splitChance));
        }

        // Create the world
        LevelWorld world = new LevelWorld(rowsInWorld, colsInWorld);

        // Verify start coordinates
        if (!AreCoordinatesInsideWorld(world, startRow, startCol))
        {
            throw new InvalidOperationException(
                      string.Format("Invalid start coordinates ({0}, {1}) for world with dimensions ({0}, {1}). Coordinates must be located inside world.", startRow, startCol, rowsInWorld, colsInWorld));
        }

        // Add the first path and start node
        LevelPath firstPath = new LevelPath(world);
        LevelNode startNode = new LevelNode(firstPath, startRow, startCol);

        // Get the directions for the next two nodes
        List <Direction> possibleDirections = GetPossibleDirectionsForPathContinuation(firstPath);

        Debug.Assert(possibleDirections.Count >= 2); // Since the world is square and there are no other nodes, there should always be at least 2 possible directions

        Direction dirOfFirstPath = GetRandomDirection(possibleDirections);

        possibleDirections.Remove(dirOfFirstPath);
        Direction dirOfSecondPath = GetRandomDirection(possibleDirections);

        // Add the nodes to the world
        ProcessPathContinuation(firstPath, startNode, dirOfFirstPath);
        LevelPath secondPath = new LevelPath(world);

        ProcessPathContinuation(secondPath, startNode, dirOfSecondPath);

        // Begin adding paths
        List <LevelPath> currentActivePaths = new List <LevelPath>()
        {
            firstPath,
            secondPath
        };

        // Add preliminary paths
        BuildWorldFromExistingPaths(world, currentActivePaths);

        // Fill in empty nodes
        Tuple <int, int> emptyNodeCoordinates = GetCoordinatesOfEmptyNodeInWorld(world, true);

        while (emptyNodeCoordinates != null)
        {
            // Create the new path and node
            LevelPath newPath = new LevelPath(world);
            LevelNode newNode = new LevelNode(newPath, emptyNodeCoordinates.First, emptyNodeCoordinates.Second);

            // Connect it to an adjacent non-empty node
            LevelNode adjacentNode = GetAdjacentNonEmptyNode(world, newNode);
            if (adjacentNode == null)
            {
                throw new InvalidOperationException(string.Format(
                                                        "Cannot continue this path; node at ({0}, {1}) has no adjacent non-empty nodes.", newNode.WorldRow, newNode.WorldColumn));
            }

            // Get the direction to the adjacent node and connect the two
            Direction dirToAdjacentNode = GetDirectionToCoordinates(newNode.WorldRow, newNode.WorldColumn, adjacentNode.WorldRow, adjacentNode.WorldColumn);
            newNode.UpdateOpenSideStatus(dirToAdjacentNode, true);
            adjacentNode.UpdateOpenSideStatus(GetOppositeDirection(dirToAdjacentNode), true);

            BuildWorldFromExistingPaths(world, new List <LevelPath>()
            {
                newPath
            });
            emptyNodeCoordinates = GetCoordinatesOfEmptyNodeInWorld(world, true);
        }

        return(startNode);
    }
Beispiel #17
0
 /// <summary>
 /// Returns a randomly selected non-empty node adjacent to the given node.
 /// </summary>
 /// <param name="world">The world whose node to return.</param>
 /// <param name="node">The node whose adjacent node to return.</param>
 /// <returns>The adjacent, non-empty node, or null if no node.</returns>
 private LevelNode GetAdjacentNonEmptyNode(LevelWorld world, LevelNode node)
 {
     return(GetAdjacentNonEmptyNode(world, node.WorldRow, node.WorldColumn));
 }
Beispiel #18
0
    /// <summary>
    /// Builds a new world with the class's parameters and returns the start node of the world.
    /// </summary>
    /// <exception cref="InvalidOperationException">Thrown if world dimensions, start coordinates, or split chance is invalid.</exception>
    /// <returns>The start node in the new world.</returns>
    public LevelNode BuildNewWorld()
    {
        // Verify world dimensions
        if (rowsInWorld < 1 || colsInWorld < 1)
        {
            throw new InvalidOperationException(
                string.Format("Invalid world dimensions ({0}, {1}). Dimensions must be >= 1.", rowsInWorld, colsInWorld));
        }

        // Verify split chance
        if (splitChance < 0 || splitChance > 1)
        {
            throw new InvalidOperationException(
                string.Format("Invalid split chance {0}. Split chance must be >= 0 and <= 1.", splitChance));
        }

        // Create the world
        LevelWorld world = new LevelWorld(rowsInWorld, colsInWorld);

        // Verify start coordinates
        if (!AreCoordinatesInsideWorld(world, startRow, startCol))
        {
            throw new InvalidOperationException(
                string.Format("Invalid start coordinates ({0}, {1}) for world with dimensions ({0}, {1}). Coordinates must be located inside world.", startRow, startCol, rowsInWorld, colsInWorld));
        }

        // Add the first path and start node
        LevelPath firstPath = new LevelPath(world);
        LevelNode startNode = new LevelNode(firstPath, startRow, startCol);

        // Get the directions for the next two nodes
        List<Direction> possibleDirections = GetPossibleDirectionsForPathContinuation(firstPath);
        Debug.Assert(possibleDirections.Count >= 2); // Since the world is square and there are no other nodes, there should always be at least 2 possible directions

        Direction dirOfFirstPath = GetRandomDirection(possibleDirections);
        possibleDirections.Remove(dirOfFirstPath);
        Direction dirOfSecondPath = GetRandomDirection(possibleDirections);

        // Add the nodes to the world
        AddNodeToWorld(startNode, firstPath, dirOfFirstPath);
        LevelPath secondPath = new LevelPath(world);
        AddNodeToWorld(startNode, secondPath, dirOfSecondPath);

        // Begin adding paths
        List<LevelPath> currentActivePaths = new List<LevelPath>()
        {
            firstPath,
            secondPath
        };

        while (currentActivePaths.Count > 0)
        {
            List<LevelPath> nextIterationActivePaths = new List<LevelPath>();
            foreach (var path in currentActivePaths)
            {
                // Verify that the path has at least one node already
                Debug.Assert(path.TailNode != null);
                
                // Get the possible directions to move
                possibleDirections = GetPossibleDirectionsForPathContinuation(path);

                // Check to see if we're out of possible directions
                if (possibleDirections.Count == 0)
                {
                    // Note that we don't add this current path to the next iteration's paths; this path is done
                    continue;
                }

                // Get the direction for the new node
                Direction dirToContinueIn = GetRandomDirection(possibleDirections);

                // Check if this is a join or if we're adding a new node
                Tuple<int, int> newCoordinates = GetNewCoordinatesInDirection(path.TailNode, dirToContinueIn);
                LevelNode nodeAtCoordinates = world.ChildNodes[newCoordinates.First, newCoordinates.Second];

                // If there's no node at these coordinates, add the node
                if (nodeAtCoordinates == null)
                {
                    AddNodeToWorld(path.TailNode, path, dirToContinueIn);

                    // This path continues next iteration
                    nextIterationActivePaths.Add(path);
                }

                // Otherwise, process a path join
                else
                {
                    JoinNodes(path.TailNode, nodeAtCoordinates);

                    // Note that we don't add this current path to the next iteration's paths; this path is done
                    continue;
                }

                // Check for a split
                float splitCheck = UnityEngine.Random.Range(0.0f, 1.0f);
                if (splitCheck < splitChance)
                {
                    possibleDirections.Remove(dirToContinueIn);
                    
                    // Check if there are any directions to continue in
                    if (possibleDirections.Count == 0)
                    {
                        // Get the direction for the new node
                        Direction dirToSplitIn = GetRandomDirection(possibleDirections);

                        // TODO: Implement. Perhaps refactor lines 103 to 125
                    }
                }
            }

            // Update the current paths for the next iteration
            currentActivePaths = nextIterationActivePaths;
        }
        

        return startNode;
    }
Beispiel #19
0
 public void clickLevel(LevelWorld world, int level)
 {
     UIManager.Instance.Startlevel(world, level);
 }
Beispiel #20
0
    /*
     * List<LevelWorld> worlds = new List<LevelWorld>();
     *  worlds.Add(new LevelWorld("W1", 3));
     *  worlds.Add(new LevelWorld("W2", 3));
     *  return worlds;
     */

    /// <summary>
    /// Decide what happen when user press on level
    /// </summary>
    /// <param name="world"></param>
    /// <param name="level"></param>
    public void Startlevel(LevelWorld world, int level)
    {
        RefManager.Instance.level     = level;
        RefManager.Instance.worldName = world.worldName;
        SceneManager.LoadScene("Game");
    }
Beispiel #21
0
 /// <summary>
 /// Choose if the level is open or not
 /// </summary>
 /// <param name="world"></param>
 /// <param name="level"></param>
 /// <returns></returns>
 public bool isLevelOpen(LevelWorld world, int level)
 {
     return(true);
 }
Beispiel #22
0
 public void OpenLevel(LevelWorld world, int newLevel)
 {
     boardScript.SetupScene(newLevel);
 }
Beispiel #23
0
 public void Startlevel(LevelWorld world, int level)
 {
     levelCretion.Startlevel(world, level);
     currentLevel = level;
     currentWorld = world;
 }
Beispiel #24
0
 public void levelComplete(LevelWorld world, int level)
 {
     savedProgression.LevelCompleted(world, level);
     SaveProgression();
 }
Beispiel #25
0
 public bool isLevelCompleted(LevelWorld world, int level)
 {
     return(savedProgression.IsLevelCompleted(world, level));
 }