0

I'm making a game in python with a UI in the terminal where the user has to navigate by pressing keys.

I have my Game() class being the following.

class Game(): 
    def __init__(self, 
                 config='default',
                 **kwargs): 

        print('\n'*20)
        # self.game_settings = self.set_game_settings(config, kwargs)
        self.main_menu()


    def main_menu(self): 
        '''Menu the player sees when playing the game'''
        print('Welcome to pyFastType!\n')
        print('Please dont use your mouse but only keyboard keys when prompt too to keep the window active or it wont detect your key presses afterwards.\nHave fun!\n\n')
        choice = self.propose_menu(question = 'Press the letter on the left to navigate through the menu:',
                                   choices = ['Play game', 'Leaderboard', 'Settings'])


        {0: self.confirm_game_settings_before_game(),
         1: self.leaderboard(),
         2: self.settings()}[choice]



    def propose_menu(self, question: list, choices: list) -> int:
        '''Print a new menu with question/answers with key pressed
        
        parameters 
        ----------
        question str: question to ask to the player
        choices list: list of choices fo the user to answer 
        
        returns
        ----------
        Index of the list corresponding to the choice of the user
        '''

        print(question.capitalize())
        choices_first_letter = []
        for choice in choices: 
            print(f'\t{choice[0].upper()} - {choice}')
            choices_first_letter.append(choice[0].lower())

        key = dk.next_key_pressed()[0].lower()
        return choices_first_letter.index(key)

In the main_menu method, I'm calling other method from a dictionary instead of if statement. Should I wrote all if/elifs instead? I'm new and see both working but I don't know which is best practice or better for readability.

Marc
  • 522
  • 1
  • 5
  • 15

2 Answers2

2

The core idea of using dicts to dispatch the behaviour is quite good in my opinion, and is actually used a lot. That said, you're calling each method in main_menu while creating the dict. Instead, try this:

options = {
    0: self.confirm_game_settings_before_game,
    1: self.leaderboard,
    2: self.settings,
}
options[choice]()
bereal
  • 32,519
  • 6
  • 58
  • 104
2

You are currently calling all three methods, then selecting one of the three return values. Instead, select the bound method, then call it once.

{0: self.confirm_game_settings_before_game,
 1: self.leaderboard,
 2: self.settings}[choice]()

If you plan on calling main_menu frequently, save the dict as another instance attribute rather than reconstructing the dict on ever function call.

chepner
  • 497,756
  • 71
  • 530
  • 681