/**
     * Invert the required state of the switch.
     *
     * @return  a SwitchState with the opposite required switch state or
     *          this SwitchState if no particular state is required
     */
    public static MZCondition.SwitchState Invert(this MZCondition.SwitchState state)
    {
        switch (state)
        {
        case MZCondition.SwitchState.Off: return(MZCondition.SwitchState.On);

        case MZCondition.SwitchState.On: return(MZCondition.SwitchState.Off);

        default:
            return(state);
        }
    }
    /**
     * Convert this SwitchState to a {@link MZSymbol}.
     *
     * @return  a symbol representing the required state of the switch or
     *          null if the switch may be in any state
     */
    public static MZSymbol ToSymbol(this MZCondition.SwitchState state)
    {
        switch (state)
        {
        case MZCondition.SwitchState.Off:
            return(new MZSymbol((int)MZSymbol.MZSymbolValue.SwitchOff));

        case MZCondition.SwitchState.On:
            return(new MZSymbol((int)MZSymbol.MZSymbolValue.SwitchOn));

        default:
            return(null);
        }
    }
    /**
     * Randomly locks descendant rooms of the given {@link MZRoom} with
     * {@link MZEdge}s that require the switch to be in the given state.
     * <p>
     * If the given state is Either, the required states will be random.
     *
     * @param room          the room whose child to lock
     * @param givenState    the state to require the switch to be in for the
     *                      child rooms to be accessible
     * @return              true if any locks were Added, false if none were
     *                      Added (which can happen due to the way the random
     *                      decisions are made)
     * @see MZCondition.SwitchState
     */
    protected bool SwitchLockChildRooms(MZRoom room,
                                        MZCondition.SwitchState givenState)
    {
        bool anyLocks = false;

        MZCondition.SwitchState state = givenState != MZCondition.SwitchState.Either
                ? givenState
                : (UnityEngine.Random.Range(0, 2) == 0
                    ? MZCondition.SwitchState.On
                    : MZCondition.SwitchState.Off);

        foreach (MZEdge edge in room.GetEdges())
        {
            int    neighborId = edge.GetTargetRoomId();
            MZRoom nextRoom   = dungeon.Get(neighborId);
            if (room.GetChildren().Contains(nextRoom))
            {
                if (room.GetEdge(neighborId).GetSymbol() == null &&
                    UnityEngine.Random.Range(0, 4) != 0)
                {
                    dungeon.Link(room, nextRoom, state.ToSymbol());
                    AddPrecond(nextRoom, new MZCondition(state.ToSymbol()));
                    anyLocks = true;
                }
                else
                {
                    anyLocks |= SwitchLockChildRooms(nextRoom, state);
                }

                if (givenState == MZCondition.SwitchState.Either)
                {
                    state = state.Invert();
                }
            }
        }
        return(anyLocks);
    }