Search code examples
pythonloopsbreak

How can I close a loop without exiting the 'game'


I'm looking for a little help to clean up my code for a class assignment. The code itsself works as intended, but I'm looking for a way to show the ending message without closing out of the program or continuing the loop. Any other advice in other areas would be greatly appreciated! Thank you

def main_menu():
    # Print instructions and intro
    print("Tea Party Take Over Game")
    print("Collect 6 items to win the game, or be eaten by the giant serpent.")
    print("Move commands: go South, go North, go East, go West")
    print("Add to Inventory: get 'item name'")


def move_between_rooms(current_room, move, rooms):
    # move to corresponding room
    current_room = rooms[current_room][move]
    return current_room


def get_item(current_room, move, rooms, inventory):
    # add item to inventory and remove it from the room
    inventory.append(rooms[current_room]['item'])
    del rooms[current_room]['item']


def main():
    # dictionary of connecting rooms with items
    rooms = {
        'Main Hall': {'North': 'Library', 'East': 'Dining room', 'South': 'Greenhouse', 'West': 'Storage'},
        'Library': {'South': 'Main Hall', 'East': 'Artifact Collection', 'item': 'Potion Book'},
        'Artifact Collection': {'West': 'Library', 'item': 'Serpent Sword'},
        'Dining room': {'West': 'Main Hall', 'North': 'Kitchen', 'item': 'Strong Sheild'},
        'Kitchen': {'South': 'Dining room', 'item': 'Potion Ingredients'},
        'Greenhouse': {'North': 'Main Hall', 'East': 'Garden', 'item': 'Healing Herb'},
        'Garden' : {'West': 'Greenhouse'},
        'Storage': {'East': 'Main Hall', 'item': 'Small Cauldron'}
    }
    s = ' '
    # list for storing player inventory
    inventory = []
    # starting room
    current_room = "Main Hall"
    # show the player the main menu
    main_menu()

    while True:
        # handle the case when player encounters the 'villain'
        if current_room == 'Garden':
            # winning case
            if len(inventory) == 6:
                print('Congratulations you have defeated The Giant Serpent and saved the tea party!')
                print('Thank you for playing!')

            # losing case
            else:
                print('\nOh dear! You did not collect all of the items!')
                print('You were eaten by The Giant Serpent and the party was ruined!')
                print('Thank you for playing!')

        # Tell the user their current room, inventory and prompt for a move, ignores case
        print('You are in the ' + current_room)
        print('Inventory:', inventory)
        # tell the user if there is an item in the room
        if current_room != 'Garden' and 'item' in rooms[current_room].keys():
            print('You see the {}'.format(rooms[current_room]['item']))
        print('------------------------------')
        move = input('Enter your move: ').title().split()

        # handle if the user enters a command to move to a new room
        if len(move) >= 2 and move[1] in rooms[current_room].keys():
            current_room = move_between_rooms(current_room, move[1], rooms)
            continue
        # handle if the user enter a command to get an item
        elif len(move[0]) == 3 and move[0] == 'Get' and ' '.join(move[1:]) in rooms[current_room]['item']:
            print('You pick up the {}'.format(rooms[current_room]['item']))
            print('------------------------------')
            get_item(current_room, move, rooms, inventory)
            continue
        # handle if the user enters an invalid command
        else:
            print('Invalid move, please try again')
            continue


main()

When i put a break statement it closes the game without showing the message.


Solution

  • The correct thing to do there is to wrap your main() function in yet another function, which can contain another menu for asking things like "play again?" (and then, just call main() again). You will then start your game calling this other function, which will in turn call main().

    Returning from main() will then, instead of finishing the program, just return to this other function, which can have its own while True: loop, which will confirm exit/play again. In time, if you choose to expand the game, you could even have main calling other functions which represent other locations (like the interior of a castle or spaceship, or whatever), and then there you can use the mechanism of Exceptions instead of simply returning from a function, to bring you back to this game menu from a nested location. But that will come to you in time.

    Alternativally, as your problem seems to be you are playing in a platform which will close the terminal when the program ends, you can simply include an extra input call after printing your end-game messages. You don´t need to care about value entered in this final input , but it will require that players press <enter> to move past it.

    So, after printing your end-game messages, add your break statement, and after the while True: block (i.e. indented the same as the while keyword), add input("\nGame Over. Press <enter> to terminate program")