def handleDeath(initialState, nightInNDeaths):
    """
    Output:
        Returns list of GameStates
    Input:
        initialState: initialGameState. Mainly for the playersToDie
        nightInNDeaths: to keep a shooter from activating Thermal
    """
    results = []
    if initialState is None:
        raise TypeError("None was passed in place of a GameState")
    elif not isinstance(initialState, GameState):
        raise TypeError("State was of incorrect type. Was of type %s", initialState.__name__)
    if type(nightInNDeaths) is not int:
        raise TypeError(
            "Night counter is of incorrect type. Was %s, but expected %s", type(nightInNDeaths).__name__, int.__name__
        )
    elif nightInNDeaths < 0:
        raise ValueError("Night counter must be positive. Was %s.", nightInNDeaths)
    if initialState.playersToDie is not None and len(initialState.playersToDie) == 0:
        return [initialState]
    currentPlayerToDie = initialState.playersToDie[0]
    if currentPlayerToDie not in initialState.players:
        initialState.playersToDie.pop(0)
        return handleDeath(initialState, nightInNDeaths - 1)
    if (
        initialState.protectedPlayer == currentPlayerToDie
        or currentPlayerToDie == "ackbar"
        or currentPlayerToDie == "guard"
    ):
        initialState.playersToDie.pop(0)
        results = handleDeath(initialState, len(initialState.playersToDie))
    else:
        newGameState = GameState(
            newPlayerList=removeFirst(initialState.players, currentPlayerToDie), otherState=initialState
        )
        newGameState.playersToDie.pop(0)
        remainingPlayersToDie = len(newGameState.playersToDie)
        if currentPlayerToDie not in swSets.shooters or currentPlayerToDie == newGameState.disabledPlayer:
            if nightInNDeaths > 0 and currentPlayerToDie == "thermal":
                highestSith = "emperor" if "emperor" in initialState.players else "darth"
                newGameState.playersToDie.insert(0, highestSith)
                remainingPlayersToDie += 1
            if currentPlayerToDie == "storm":
                newGameState.resurectStorm = True
            results = handleDeath(newGameState, remainingPlayersToDie)
        else:
            shooterResults = []
            for player in newGameState.players:
                shooterResponseGameState = GameState(otherState=newGameState)
                shooterResponseGameState.playersToDie.append(player)
                shooterResults += handleDeath(shooterResponseGameState, remainingPlayersToDie)
            results = shooterResults

        for state in results:
            state.evaluateEndConditions()
    return results
    def nightCycle(state):
        """
            Evaluates possible dayTimeResults
            Returns a list of one of two results:
            1 - List) The game continues with a list of remaining players
            2 - Num) The game has ended

            Possible ways of dying during the night:
              'sith kills', 'shot after shooter dies', 'incineration', 'thermal detinator'
        """
        if state.evaluateEndConditions() is not None:
            return unzipGameStates(state)

        possibleOutcomes = []
        protected = None

        # Sith kill
        postSithOutcomes = []
        highestSith = "emperor" if "emperor" in state.players else "darth"
        playersWithoutHighestSith = [x for x in state.players if x != highestSith]
        for player in playersWithoutHighestSith:
            newGameState = GameState(otherState=state)
            newGameState.playersToDie.append(player)
            postSithOutcomes.append(newGameState)
        possibleOutcomes += postSithOutcomes

        if "yoda" in state.players:
            currentPossibleOutcomes = [x for x in possibleOutcomes]
            possibleOutcomes = []
            outcomesWithProtection = []
            for outcome in currentPossibleOutcomes:
                for player in [x for x in outcome.players if x != "yoda"]:
                    newGameState = GameState(otherState=outcome)
                    newGameState.protectedPlayer = player
                    outcomesWithProtection.append(newGameState)
            possibleOutcomes += outcomesWithProtection

        if "luke" in state.players:
            currentPossibleOutcomes = [x for x in possibleOutcomes]
            outcomesWithChallenge = []
            for outcome in currentPossibleOutcomes:
                for player in [x for x in state.players if x != "luke"]:
                    newGameState = GameState(otherState=outcome)
                    newGameState.playersToDie.append(player)
                    if player in swSets.good and player != newGameState.protectedPlayer:
                        newGameState.playersToDie.append("luke")
                    outcomesWithChallenge.append(newGameState)
            possibleOutcomes += outcomesWithChallenge

        if "bathan" in state.players:
            currentPossibleOutcomes = [x for x in possibleOutcomes]
            outComesWithIncineration = []
            for outcome in currentPossibleOutcomes:
                for player in [x for x in state.players if x != "bathan"]:
                    newGameState = GameState(otherState=outcome)
                    newGameState.playersToDie.append(player)
                    outComesWithIncineration.append(newGameState)
            possibleOutcomes += outComesWithIncineration

        if "ev" in state.players:
            currentPossibleOutcomes = [x for x in possibleOutcomes]
            outcomesWithDisable = []
            for outcome in currentPossibleOutcomes:
                for player in [x for x in state.players if x != "ev"]:
                    newGameState = GameState(otherState=outcome)
                    newGameState.disabledPlayer = player
                    outcomesWithDisable.append(newGameState)
            possibleOutcomes += outcomesWithDisable

        evaluatedOutcomes = []
        for outcome in possibleOutcomes:
            evaluatedOutcomes += handleDeath(outcome, len(outcome.playersToDie))
        for outcome in evaluatedOutcomes:
            outcome.protectedPlayer = None
            outcome.evaluateEndConditions()
        return unzipGameStates(reduceStates(evaluatedOutcomes))
    def dayCycle(state):
        """
            Evaluats possible dayTimeResults
            Returns a list of one of two results:
            1 - List) The game continues with a list of remaining players
            2 - Num) The game has ended

            Possible ways of dying during the day:
              'trial', 'being eaten', 'shot after shooter dies'
        """
        if state is None:
            raise ValueError("state was null")
        if state.evaluateEndConditions() is not None:
            return unzipGameStates(state)

        possibleOutcomes = [state]

        livingActiveEaters = [x for x in swSets.eaters.intersection(state.players) if state.killerStates[x] == 1]
        powerSetPermutationsOfEaters = StarWarsPathEvaluator.powerSetPermutations(livingActiveEaters)
        for eaterSet in powerSetPermutationsOfEaters:
            for eaterPermutation in eaterSet:
                newGameStates = [GameState(otherState=state)]
                for eater in eaterPermutation:
                    currentGameStates = [x for x in newGameStates]
                    for gameState in currentGameStates:
                        if eater not in gameState.players and eater != gameState.disabledPlayer:
                            newGameStates = [x for x in newGameStates if x != gameState]
                            continue
                        playersWithoutEater = [
                            x
                            for x in gameState.players
                            if x != eater
                            or x in eaterSet
                            and gameState.killerStates[x] != 1
                            and x not in gameState.playersToDie
                        ]
                        for player in playersWithoutEater:
                            newGameState = GameState(otherState=gameState)
                            newGameState.killerStates[eater] = 0
                            newGameState.playersToDie.append(player)
                            newGameStates += handleDeath(newGameState, 0)
                possibleOutcomes += [x for x in newGameStates if x not in possibleOutcomes]

        currentPossibleOutcomes = [x for x in possibleOutcomes]
        possibleOutcomes = []
        for gameState in currentPossibleOutcomes:
            possibleOutcomes += handleDeath(gameState, 0)

        currentPossibleOutcomes = [x for x in possibleOutcomes if not x.isOver]
        for gameState in currentPossibleOutcomes:
            if len(gameState.players) > 2:
                for player in gameState.players:
                    newGameState = GameState(otherState=gameState)
                    newGameState.playersToDie.append(player)
                    possibleOutcomes.append(newGameState)

        currentPossibleOutcomes = [x for x in possibleOutcomes]
        possibleOutcomes = []
        for gameState in currentPossibleOutcomes:
            possibleOutcomes += handleDeath(gameState, 0)

        for gameState in possibleOutcomes:
            gameState.disabledPlayer = None
            if gameState.resurectStorm:
                gameState.players.append("storm")
                gameState.resurectStorm = False
            gameState.evaluateEndConditions()

        return unzipGameStates(reduceStates(possibleOutcomes))