-
Notifications
You must be signed in to change notification settings - Fork 0
/
menu.py
94 lines (71 loc) · 2.61 KB
/
menu.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
from action import Action
from typing import TypeVar
MenuOption = TypeVar("MenuOption", "Menu", Action)
class Menu:
"""Class for constructing the text menus. Uses builder pattern to allow
for method chaining style of construction."""
def __init__(self, title: str = "", prompt: str = "What will you do? "):
self.title = title
self.prompt = prompt
self.actions: list[Action] = []
self.submenus: list["Menu"] = []
self.is_child = False
def add_submenu(self, submenu: "Menu"):
submenu.is_child = True
self.submenus.append(submenu)
return self
def add_action(self, action: Action):
self.actions.append(action)
return self
@property
def options(self) -> dict[str, MenuOption]:
opts = self.actions + self.submenus
return {f"{i+1}": opt for i, opt in enumerate(opts)}
def valid_selection(self, selection: str) -> bool:
return selection in self.options.keys()
def get_selection(self, selection: str) -> MenuOption:
return self.options[selection]
def is_menu(self, selection: MenuOption) -> bool:
return isinstance(selection, self.__class__)
def print_separator(self):
print("-" * 25)
def show(self):
"""Does the work of printing out the menu text"""
if self.is_child:
print()
self.print_separator()
print(f"{self.title}")
if self.title != "":
print()
for key, opt in self.options.items():
if self.is_menu(opt):
text = opt.title.title()
else:
text = str(opt)
print(f"{key}) {text}")
if self.is_child:
print("0) Cancel")
print()
def get_action(self) -> str:
"""Shows the menu text and prompts the user for input.
Will return the name of an Action to be performed in the battle loop"""
self.show()
while True:
select_in = input(self.prompt)
if self.is_child and select_in == "0":
return
elif not self.valid_selection(select_in):
continue
elif self.is_menu(
# Using 3.8's fancy new walrus operator
selection := self.get_selection(select_in)
):
# For when the selection is a submenu
action_name = selection.get_action()
if action_name:
return action_name
else:
self.show()
continue
else:
return selection.name