private void Add(MZSymbol sym)
 {
     if (sym.GetValue() == (int)MZSymbol.MZSymbolValue.SwitchOff)
     {
         switchState = SwitchState.Off;
     }
     else if (sym.GetValue() == (int)MZSymbol.MZSymbolValue.SwitchOn)
     {
         switchState = SwitchState.On;
     }
     else
     {
         keyLevel = Math.Max(keyLevel, sym.GetValue() + 1);
     }
 }
 /**
  * Creates a MZCondition that requires the player to have a particular
  * {@link MZSymbol}.
  *
  * @param e the symbol that the player must have for the MZCondition to be
  *          satisfied
  */
 public MZCondition(MZSymbol e)
 {
     if (e.GetValue() == (int)MZSymbol.MZSymbolValue.SwitchOff)
     {
         keyLevel    = 0;
         switchState = SwitchState.Off;
     }
     else if (e.GetValue() == (int)MZSymbol.MZSymbolValue.SwitchOn)
     {
         keyLevel    = 0;
         switchState = SwitchState.On;
     }
     else
     {
         keyLevel    = e.GetValue() + 1;
         switchState = SwitchState.Either;
     }
 }
    /*
     * private int keyLevel;
     *
     * public AStarClient(int keyLevel)
     * {
     *  this.keyLevel = keyLevel;
     * }
     *
     * public override List<int> GetNeighbors(int roomId)
     * {
     *  List<int> ids = new List<int>();
     *  foreach (MZEdge edge in dungeon.Get(roomId).GetEdges())
     *  {
     *      if (!edge.HasSymbol() || edge.GetSymbol().GetValue() < keyLevel)
     *      {
     *          ids.Add(edge.GetTargetRoomId());
     *      }
     *  }
     *  return ids;
     * }
     * public override Vector2Int GetVector2Int(int roomId)
     * {
     *  return dungeon.Get(roomId).GetCenter();
     * }
     * }
     */
    /*
     * private List<int> AStar(int start, int goal, int keyLevel)
     * {
     *  AStar<int> astar = new AStar<int>();
     *  return astar.Solve();
     * }
     */

    /**
     * Nonlinearity is measured as the number of rooms the player would have to
     * pass through multiple times to Get to the goal room (collecting keys and
     * unlocking doors along the way).
     *
     * Uses A* to find a path from the entry to the first key, from each key to
     * the next key and from the last key to the goal.
     *
     * @return  The number of rooms passed through multiple times
     **/
    public int MeasureNonlinearity()
    {
        List <MZRoom> keyRooms = new List <MZRoom>(constraints.GetMaxKeys());

        for (int i = 0; i < constraints.GetMaxKeys(); ++i)
        {
            keyRooms.Add(null);
        }
        foreach (MZRoom room in dungeon.GetRooms())
        {
            if (room.GetItem() == null)
            {
                continue;
            }
            MZSymbol item = room.GetItem();
            if (item.GetValue() >= 0 && item.GetValue() < keyRooms.Count)
            {
                keyRooms.Insert(item.GetValue(), room);
            }
        }
        //for N >= 0: keyRooms[N] = location of key N

        MZRoom current = dungeon.FindStart(), goal = dungeon.FindGoal();

        //clients may disable generation of the goal room if redundant, in which case the equivalent 'ending' room becomes the boss room
        if (goal == null)
        {
            goal = dungeon.FindBoss();
        }
        Debug.Assert(current != null && goal != null);
        int nextKey = 0, nonlinearity = 0;

        List <int> visitedRooms = new List <int>();

        while (current != goal)
        {
            MZRoom intermediateGoal;

            //Debug.Log("Current room ID: " + current.id);
            //Debug.Log("Max Keys:" + constraints.GetMaxKeys());
            //Debug.Log("Next Key: " + nextKey);

            if (nextKey == constraints.GetMaxKeys())
            {
                intermediateGoal = goal;
            }

            else
            {
                intermediateGoal = keyRooms[nextKey];
            }
            //Debug.Log("Current goal ID: " + intermediateGoal.id);
            ///*
            //Debug.Log("Dungeon: " + dungeon.GetType());
            //*/
            //Debug.Log("A* running...");
            List <int> steps = astar(current.id, intermediateGoal.id, nextKey, dungeon); //ちゃんとこれを作ってよ
            //Debug.Log("Reversing steps!");
            steps.Reverse();

            foreach (int id in steps)
            {
                Debug.Log("Visited Room: " + id);
                if (visitedRooms.Contains(id))
                {
                    ++nonlinearity;
                }
            }
            visitedRooms.AddRange(steps);

            nextKey++;
            current = dungeon.Get(steps[0]);
            MZRoom test = current;
        }
        return(nonlinearity);
    }
Beispiel #4
0
    public void CreateDungeon()
    {
        float roomRatio = 0.6875f; // 256x176


        // Use CountConstraints to make a truly random map.

        /*
         * CountConstraints constraints = new CountConstraints((int)maxSpaces, (int)maxKeys, (int)maxSwitches);
         * Debug.Log("Constraints: " + maxSpaces + "," + maxKeys + "," + maxSwitches);
         */

        // Use SpaceConstraints to make a map fitting to a shape.
        ///*
        MZSpaceMap spaceMap = new MZSpaceMap();

        //random tile map
        //tileMap = tileMapObjects[Random.Range(0, tileMapObjects.Length)].GetComponentInChildren<Tilemap>();
        tileMap = tileMapObjects[0].GetComponentInChildren <Tilemap>();
        foreach (Vector3Int posWithZ in tileMap.cellBounds.allPositionsWithin.GetEnumerator())
        {
            if (tileMap.HasTile(posWithZ))
            {
                Vector2Int pos = new Vector2Int(posWithZ.x, posWithZ.y);
                spaceMap.Set(pos, true);
            }
        }

        SpaceConstraints constraints = new SpaceConstraints(spaceMap, (int)maxKeys, (int)maxSwitches);

        //*/
        generator = new LinearDungeonGenerator(Random.Range(0, int.MaxValue), constraints, numberOfRooms, (int)maxGenerations);
        //generator = new DungeonGenerator(Random.Range(0, int.MaxValue), constraints, numberOfRooms);

        Debug.Log("Generate()");
        generator.Generate();
        dungeon = generator.GetMZDungeon();
        foreach (MZRoom room in dungeon.GetRooms())
        {
            MZSymbol   item          = room.GetItem();
            GameObject toInstantiate = normalRoom;
            Color      roomColor     = new Color((float)room.GetIntensity(), 1.0f - (float)room.GetIntensity(), 0.5f - (float)room.GetIntensity() / 2);
            if (item != null)
            {
                switch (item.GetValue())
                {
                case (int)MZSymbol.MZSymbolValue.Start:
                    toInstantiate = entranceRoom;
                    roomColor     = Color.white;
                    break;

                case (int)MZSymbol.MZSymbolValue.Boss:
                    toInstantiate = bossRoom;
                    break;

                case (int)MZSymbol.MZSymbolValue.Goal:
                    toInstantiate = goalRoom;
                    roomColor     = Color.white;
                    break;

                default:
                    break;
                }

                if (item.GetValue() >= 0)
                {
                    GameObject keyObjectInstance = Instantiate(key, new Vector3(room.GetCoords()[0].x, room.GetCoords()[0].y * roomRatio, 0), Quaternion.identity, transform);
                    keyObjectInstance.GetComponent <SpriteRenderer>().color = keyColors[item.GetValue()];
                    keyObjectInstance.transform.localScale += new Vector3(2, 2, 2);
                    instances.Add(keyObjectInstance);
                }
                else if (item.GetValue() == (int)MZSymbol.MZSymbolValue.Switch)
                {
                    GameObject keyObjectInstance = Instantiate(roomSwitch, new Vector3(room.GetCoords()[0].x, room.GetCoords()[0].y * roomRatio, 0), Quaternion.identity, transform);
                    keyObjectInstance.transform.localScale += new Vector3(2, 2, 2);
                    instances.Add(keyObjectInstance);
                }
            }

            GameObject roomObject = Instantiate(toInstantiate, new Vector3(room.GetCoords()[0].x, room.GetCoords()[0].y * roomRatio, 0), Quaternion.identity, transform);
            roomObject.GetComponent <SpriteRenderer>().color = roomColor;
            instances.Add(roomObject);

            foreach (MZEdge edge in room.GetEdges())
            {
                MZRoom     targetRoom = dungeon.Get(edge.GetTargetRoomId());
                Vector2Int edgeDir    = targetRoom.GetCoords()[0] - room.GetCoords()[0];

                toInstantiate = openDoor;
                GameObject keyObject = null;
                Color      keyColor  = Color.white;
                if (edge.GetSymbol() != null)
                {
                    switch (edge.GetSymbol().GetValue())
                    {
                    case (int)MZSymbol.MZSymbolValue.SwitchOn:
                        toInstantiate = blockedDoor;
                        keyObject     = roomSwitchOn;
                        break;

                    case (int)MZSymbol.MZSymbolValue.SwitchOff:
                        toInstantiate = blockedDoor;
                        keyObject     = roomSwitchOff;
                        break;

                    default:
                        break;
                    }

                    if (edge.GetSymbol().GetValue() >= 0)
                    {
                        toInstantiate = lockedDoor;
                        keyObject     = key;
                        keyColor      = keyColors[edge.GetSymbol().GetValue()];
                    }
                }

                //this only works for identically sized rooms
                Vector3 pos = Vector3.zero;
                if (edgeDir == Vector2Int.right)
                {
                    pos = new Vector3(room.GetCoords()[0].x + 0.5f, room.GetCoords()[0].y * roomRatio, 0);
                    GameObject doorObject = Instantiate(toInstantiate, pos, Quaternion.identity, transform);
                    instances.Add(doorObject);
                    if (keyObject != null)
                    {
                        GameObject keyObjectInstance = Instantiate(keyObject, pos, Quaternion.identity, transform);
                        instances.Add(keyObjectInstance);
                        keyObjectInstance.GetComponent <SpriteRenderer>().color = keyColor;
                        keyObjectInstance.transform.localScale += new Vector3(1, 1, 1);
                    }
                }
                else if (edgeDir == Vector2Int.down)
                {
                    pos = new Vector3(room.GetCoords()[0].x, room.GetCoords()[0].y * roomRatio - (roomRatio / 2), 0);
                    Vector2Int relativePos = Vector2Int.zero + Vector2Int.up;
                    float      angle       = Mathf.Atan2(relativePos.y, relativePos.x) * Mathf.Rad2Deg;
                    Quaternion rotation    = Quaternion.AngleAxis(angle, Vector3.forward); //90 degrees
                    GameObject doorObject  = Instantiate(toInstantiate, pos, rotation, transform);
                    instances.Add(doorObject);
                    if (keyObject != null)
                    {
                        GameObject keyObjectInstance = Instantiate(keyObject, pos, Quaternion.identity, transform);
                        instances.Add(keyObjectInstance);
                        keyObjectInstance.GetComponent <SpriteRenderer>().color = keyColor;
                        keyObjectInstance.transform.localScale += new Vector3(1, 1, 1);
                    }
                }
            }
        }
        foreach (var room in dungeon.GetRooms())
        {
            foreach (var edge in room.GetEdges())
            {
                //wrap this up laterino
            }
        }
    }