コード例 #1
0
    /**
     * Makes some {@link MZEdge}s within the dungeon require the dungeon's switch
     * to be in a particular state, and places the switch in a room in the
     * dungeon.
     *
     * @ if it fails
     */
    protected void PlaceSwitches()
    {
        // Possible TODO: have multiple switches on separate circuits
        // At the moment, we only have one switch per dungeon.
        if (constraints.GetMaxSwitches() <= 0)
        {
            return;
        }

        List <MZRoom> solution = GetSolutionPath();

        for (int attempt = 0; attempt < 10; ++attempt)
        {
            List <MZRoom> rooms = new List <MZRoom>(dungeon.GetRooms());
            Shuffle(rooms);
            Shuffle(solution);

            // Pick a base room from the solution path so that the player
            // will have to encounter a switch-lock to solve the dungeon.
            MZRoom baseRoom = null;
            foreach (MZRoom room in solution)
            {
                if (room.GetChildren().Count > 1 && room.GetParent() != null)
                {
                    baseRoom = room;
                    break;
                }
            }
            if (baseRoom == null)
            {
                throw new RetryException();
            }
            MZCondition baseRoomCond = baseRoom.GetPrecond();

            RemoveDescendantsFromList(rooms, baseRoom);

            MZSymbol switchSym = new MZSymbol((int)MZSymbol.MZSymbolValue.Switch);

            MZRoom switchRoom = null;
            foreach (MZRoom room in rooms)
            {
                if (room.GetItem() == null &&
                    baseRoomCond.Implies(room.GetPrecond()) &&
                    constraints.RoomCanFitItem(room.id, switchSym))
                {
                    switchRoom = room;
                    break;
                }
            }
            if (switchRoom == null)
            {
                continue;
            }

            if (SwitchLockChildRooms(baseRoom, MZCondition.SwitchState.Either))
            {
                switchRoom.SetItem(switchSym);
                return;
            }
        }
        throw new RetryException();
    }
コード例 #2
0
    /**
     * Places the BOSS and GOAL rooms within the dungeon, in existing rooms.
     * These rooms are moved into the next keyLevel.
     *
     * @param levels    the keyLevel -> room-set mapping to update
     * @ if it fails
     * @see KeyLevelRoomMapping
     */
    protected void PlaceBossGoalRooms(KeyLevelRoomMapping levels)
    {
        List <MZRoom> possibleGoalRooms = new List <MZRoom>(dungeon.RoomCount());

        MZSymbol goalSym = new MZSymbol((int)MZSymbol.MZSymbolValue.Goal),
                 bossSym = new MZSymbol((int)MZSymbol.MZSymbolValue.Boss);

        foreach (MZRoom room in dungeon.GetRooms())
        {
            if (room.GetChildren().Count > 0 || room.GetItem() != null)
            {
                continue;
            }
            MZRoom parent = room.GetParent();
            if (parent == null)
            {
                continue;
            }
            if (IsGenerateGoal() && (parent.GetChildren().Count != 1 ||
                                     !parent.GetPrecond().Implies(room.GetPrecond())))
            {
                continue;
            }
            if (IsGenerateGoal())
            {
                if (!constraints.RoomCanFitItem(room.id, goalSym) ||
                    !constraints.RoomCanFitItem(parent.id, bossSym))
                {
                    continue;
                }
            }
            else
            {
                if (!constraints.RoomCanFitItem(room.id, bossSym))
                {
                    continue;
                }
            }
            possibleGoalRooms.Add(room);
        }

        if (possibleGoalRooms.Count == 0)
        {
            throw new RetryException();
        }

        MZRoom goalRoom = possibleGoalRooms[UnityEngine.Random.Range(0,
                                                                     possibleGoalRooms.Count)],
               bossRoom = goalRoom.GetParent();

        if (!IsGenerateGoal())
        {
            bossRoom = goalRoom;
            goalRoom = null;
        }

        if (goalRoom != null)
        {
            goalRoom.SetItem(goalSym);
        }
        bossRoom.SetItem(bossSym);

        int oldKeyLevel = bossRoom.GetPrecond().GetKeyLevel(),
            newKeyLevel = Math.Min(levels.KeyCount(), constraints.GetMaxKeys());

        if (oldKeyLevel != newKeyLevel)
        {
            List <MZRoom> oklRooms = levels.GetRooms(oldKeyLevel);
            if (goalRoom != null)
            {
                oklRooms.Remove(goalRoom);
            }
            oklRooms.Remove(bossRoom);

            if (goalRoom != null)
            {
                levels.AddRoom(newKeyLevel, goalRoom);
            }
            levels.AddRoom(newKeyLevel, bossRoom);

            MZSymbol    bossKey = new MZSymbol(newKeyLevel - 1);
            MZCondition precond = bossRoom.GetPrecond().And(bossKey);
            bossRoom.SetPrecond(precond);
            if (goalRoom != null)
            {
                goalRoom.SetPrecond(precond);
            }

            if (newKeyLevel == 0)
            {
                dungeon.Link(bossRoom.GetParent(), bossRoom);
            }
            else
            {
                dungeon.Link(bossRoom.GetParent(), bossRoom, bossKey);
            }
            if (goalRoom != null)
            {
                dungeon.Link(bossRoom, goalRoom);
            }
        }
    }