-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgame_tk.py
183 lines (150 loc) · 5.83 KB
/
game_tk.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# pylint: disable=invalid-name
"""
GameTk 2024-01-18 4:39 p.m.
Tom Legrady - [email protected]
(c) 2024 Tom Legrady - All Rights Reserved
"""
import sys
import tkinter as tk
from config import Config as cfg
# ic.disable()
class Tk(tk.Tk):
"""The top level window widget"""
def __init__(
self,
) -> None:
super().__init__()
self.title(cfg.GAME_TITLE())
self.geometry(cfg.GEOMETRY())
self.reset()
def set_bg(self, colour: str) -> None:
"""Set the window background colour"""
self.configure(background=colour)
def reset(self) -> None:
"""Set the background colour to the PLAY condition."""
self.set_bg(cfg.BG_PLAY())
class Alphabet(tk.Text): # pylint: disable=too-many-ancestors
"""Display the letters of the alphabet which the player has not yet tried."""
def __init__(self, window) -> None:
super().__init__(
window,
font=cfg.FONT_SIZE(),
height=cfg.ALPHA_HEIGHT(),
width=cfg.ALPHA_WIDTH(),
borderwidth=cfg.ALPHA_BORDER_WIDTH(),
relief=cfg.ALPHA_RELIEF(),
pady=cfg.PAD_Y(),
)
self.pack(side=cfg.ALPHA_PACK_SIDE(), pady=cfg.PAD_Y())
self.init_text()
def init_text(self) -> None:
"""Delete any existing characters in the display, and insert
the letters of the alphabet.
"""
self.delete(cfg.TAG_START_INDEX(), cfg.TAG_END_INDEX())
self.insert(
cfg.ALPHA_INSERT_AT(),
cfg.ALPHABET(),
cfg.TEXT_ALIGN(),
)
def hide_used_letter(self, c: str) -> None:
"""Replace the specified letter of the alphabet with a space character."""
i = ord(c) - ord(cfg.CHAR_UC_A())
pos = "1." + str(i)
self.delete(pos)
self.insert(pos, cfg.CHAR_SPACE())
def get(self):
return super().get(cfg.TAG_START_INDEX(), cfg.TAG_END_INDEX()).strip()
def reset(self) -> None:
"""Restore the full alphabet display."""
self.init_text()
class UserInput(tk.Entry): # pylint: disable=too-many-ancestors
"""Where the player types their guess"""
def __init__(self, textvar, process_guess, window) -> None:
super().__init__(
window,
width=cfg.USERINPUT_WIDTH(),
borderwidth=cfg.USERINPUT_BORDER_WIDTH(),
font=cfg.FONT_SIZE(),
textvariable=textvar,
justify=cfg.USERINPUT_JUSTIFY(),
)
self.pack(side=cfg.USERINPUT_PACK_SIDE(), pady=cfg.PAD_Y())
self.bind(cfg.USERINPUT_EVENT(), process_guess)
class Eval(tk.Text): # pylint: disable=too-many-ancestors
"""For each player guess, display which letters are in the
right position; are in the word but in another position; or are
not in the word at all.
"""
def __init__(self, window) -> None:
super().__init__(window)
self.config(
font=cfg.FONT_SIZE(),
width=cfg.EVAL_WIDTH(),
height=cfg.EVAL_HEIGHT(),
state=cfg.EVAL_STATE_DISABLED(),
background=cfg.EVAL_BG(),
)
self.tag_config(cfg.TAG_CENTER(), justify=cfg.TEXT_ALIGN())
self.tag_config(cfg.BG_NONE(), background=cfg.BG_NONE())
self.tag_config(cfg.BG_LETTER(), background=cfg.BG_LETTER())
self.tag_config(cfg.BG_POSITION(), background=cfg.BG_POSITION())
self.pack(side=cfg.EVAL_PACK_SIDE(), pady=cfg.PAD_Y() / 2)
def insert(self, index: str, chars: str, *_) -> None:
"""Insert some text into an empty eval box. Call insert() on
super() to avoid infinite loop.
"""
self.config(state=cfg.EVAL_STATE_ENABLED())
super().insert(index, chars)
self.tag_add(cfg.TAG_CENTER(), cfg.TAG_START_INDEX(), cfg.TAG_END_INDEX())
self.config(state=cfg.EVAL_STATE_DISABLED())
def add_text_tag(self, colour: str, start: int, stop: int) -> None:
"""Apply a colour tag to one of more letters."""
self.config(state=cfg.EVAL_STATE_ENABLED())
start = cfg.EVAL_INDEX_START() + str(start)
stop = cfg.EVAL_INDEX_START() + str(stop)
self.tag_add(colour, start, stop)
self.config(state=cfg.EVAL_STATE_DISABLED())
def get(self): # pylint: disable=arguments-differ
return super().get(1.0, "end").strip()
def reset(self) -> None:
"""delete the text contents of the eval box."""
self.config(state=cfg.EVAL_STATE_ENABLED())
self.delete(cfg.TAG_START_INDEX(), cfg.TAG_END_INDEX())
self.config(state=cfg.EVAL_STATE_DISABLED())
class ScoreDisplay(tk.Label):
"""Display the games won and lost."""
def __init__(self, window) -> None:
super().__init__(
window,
anchor=cfg.TEXT_ALIGN(),
bg=cfg.EVAL_BG(),
width=cfg.SCORE_DISPLAY_WIDTH(),
pady=cfg.PAD_Y(),
text=cfg.SCORE_DISPLAY_INITIAL_TEXT(),
font=cfg.FONT_SIZE(),
relief=cfg.SCORE_DISPLAY_RELIEF(),
)
self.pack(side=cfg.SCORE_DISPLAY_PACK_SIDE(), pady=cfg.PAD_Y())
def update(self, display_text) -> None: # pylint: disable=arguments-differ
"""Change the text displayed in the score."""
self.config(text=display_text)
class Quit(tk.Button):
"""The Quit Button"""
def __init__(self, window) -> None:
super().__init__(
window,
text=cfg.QUIT_TEXT(),
width=cfg.QUIT_WIDTH(),
font=cfg.FONT_SIZE(),
padx=cfg.PAD_X(),
pady=cfg.PAD_Y(),
command=self.close,
)
self.pack(side=cfg.QUIT_PACK_SIDE(), pady=cfg.PAD_Y())
def close(self):
"""Game over! ... close the window .. shut the door!"""
sys.exit(0)
# ======================================================================
# End of File
#