-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfunctions.py
233 lines (187 loc) · 8.33 KB
/
functions.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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
import dearpygui.dearpygui as dpg
import threading
import random
import string
import time
class WordleGame:
print_secret_word = False
COLS = 5
ROWS = 6
def __init__(self):
self.row_index = 0
self.button_index = 0
self.valid_words = []
self.user_answer = []
self.buttons_dict = {}
self.random_word = ""
self.game_state = "playing"
def show_error_popup(self, message, pos):
dpg.set_item_label("error_popup", message)
dpg.set_item_pos("error_popup", pos)
dpg.configure_item("error_popup", show=True)
threading.Thread(target=self.hide_error_popup, args=(2.0,)).start()
def hide_error_popup(self, delay):
time.sleep(delay)
dpg.configure_item("error_popup", show=False)
def pick_word(self):
with open("valid_words.txt", "r") as file:
words_list = file.readlines()
self.valid_words = [words.rstrip(
"\n").upper() for words in words_list]
self.random_word = random.choice(self.valid_words)
if self.print_secret_word == True:
print(f"Word selected: {self.random_word}")
else:
print(f"Word selected: *****")
# Fix from https://github.com/pixegami/python-wordle
def verify_answer(self):
user_answer = ''.join(self.user_answer)
secret_word_letters = list(self.random_word)
correct_positions = set()
result = ["ABSENT"] * len(secret_word_letters)
# Check for correct letters in correct positions and mark their positions.
for i, letter in enumerate(user_answer):
if letter == secret_word_letters[i]:
correct_positions.add(i)
result[i] = "CORRECT"
# Void out the correctly guessed letter.
secret_word_letters[i] = "*"
# Check for correct letters in incorrect positions and mark them.
for i, letter in enumerate(user_answer):
if result[i] == "CORRECT": # Skip letters already marked green.
continue
elif letter in secret_word_letters:
result[i] = "INWORD"
# Void out the guessed letter.
secret_word_letters[secret_word_letters.index(letter)] = "*"
# Mark remaining correct letters.
for i, letter in enumerate(user_answer):
if result[i] == "ABSENT" and letter in secret_word_letters:
result[i] = "CORRECT"
# Void out the correctly guessed letter.
secret_word_letters[secret_word_letters.index(letter)] = "*"
# Mark the buttons according to the result array.
for i, color in enumerate(result):
button_to_update = self.buttons_dict.get(i)
if color == "CORRECT":
self.mark_correct_guess(
button_to_update, user_answer[i])
elif color == "INWORD":
self.mark_in_word_guess(
button_to_update, user_answer[i])
else:
self.mark_incorrect_position(
button_to_update, user_answer[i])
if len(correct_positions) == len(self.random_word):
self.handle_game_won(correct_positions)
def mark_correct_guess(self, button, letter):
dpg.bind_item_theme(button, "correct_theme")
dpg.bind_item_theme(f"{letter}", "key_correct_theme")
def mark_in_word_guess(self, button, letter):
dpg.bind_item_theme(button, "in_word_theme")
dpg.bind_item_theme(f"{letter}", "key_in_word_theme")
def mark_incorrect_position(self, button, letter):
dpg.bind_item_theme(button, "absent_theme")
dpg.bind_item_theme(f"{letter}", "key_absent_theme")
def handle_game_won(self, correct_positions):
dpg.set_item_label("logo", "Click to restart")
self.show_error_popup("Splendid", [236, 50])
self.game_state = "won"
def keyboard_btn_pressed(self, sender):
if self.game_state != "playing":
return
if len(self.user_answer) < self.COLS:
key_pressed = dpg.get_item_label(sender)
self.user_answer.append(key_pressed)
self.update_game_ui(key_pressed)
print(f"Pressed: {key_pressed}, added to list: {self.user_answer}")
else:
self.user_answer = self.user_answer[:self.COLS]
print(f"Reached the limit of available space. {self.user_answer}")
def key_press_handler(self, sender, app_data):
if self.game_state != "playing":
return
elif app_data == 13: # Enter key
wordle_game.enter_key_button(sender)
elif app_data == 8: # Backspace key
wordle_game.del_key_button(sender)
if len(self.user_answer) < self.COLS:
# Check if the pressed key is a letter
if 65 <= app_data <= 90:
key_pressed = chr(app_data)
self.user_answer.append(key_pressed)
wordle_game.update_game_ui(key_pressed)
else:
self.user_answer = self.user_answer[:self.COLS]
def enter_key_button(self, sender):
answer = ''.join(self.user_answer)
if self.game_state != "playing":
return
elif self.button_index == self.COLS:
print(f"Row {self.row_index} completed!")
if self.row_index == self.ROWS:
print("All rows completed!")
if answer in self.valid_words:
self.verify_answer()
self.row_index += 1
self.button_index = 0
self.user_answer.clear()
else:
self.show_error_popup("Not in word list", [220, 50])
print(f"Invalid word, user answer: {self.user_answer}")
else:
self.show_error_popup("Not enough letters", [209, 50])
print(f"Enter five letters in the current row. {self.user_answer}")
if self.row_index >= self.ROWS:
if self.game_state == "won":
pass
else:
self.show_error_popup(
f"The words was: {self.random_word}", [200, 50])
dpg.set_item_label("logo", "Click to restart")
self.game_state = "lost"
else:
print(f"Reached the limit of available space. {self.user_answer}")
def del_key_button(self, sender):
if self.game_state != "playing":
return
elif self.button_index > 0:
self.button_index -= 1
self.user_answer.pop()
button_to_update = self.buttons_dict.get(self.button_index)
print(f"Deleted last letter, new user answer: {self.user_answer}")
if button_to_update:
dpg.set_item_label(button_to_update, "")
dpg.bind_item_theme(button_to_update, "tile_theme")
else:
self.user_answer = []
print("No letters to delete.")
def update_game_ui(self, key_pressed):
if len(self.user_answer) <= self.COLS:
if self.button_index < self.COLS:
button_to_update = dpg.get_item_alias(
f"#{self.button_index + self.row_index * self.COLS}_key")
if not dpg.get_item_label(button_to_update):
dpg.set_item_label(button_to_update, key_pressed)
self.button_index += 1
self.buttons_dict[self.button_index - 1] = button_to_update
print(f"""Letter: {key_pressed}, added to button #{
self.button_index} in row {self.row_index}""")
if self.button_index == self.COLS:
print("Row completed!")
else:
print(f"Reached the limit of available space. {self.user_answer}")
def restart(self):
self.__init__()
self.pick_word()
dpg.set_item_label("logo", "Wordle.py")
print("Game restarted!")
# Restart letters state
for i in range(self.COLS * self.ROWS):
button_to_reset = dpg.get_item_alias(f"#{i}_key")
dpg.set_item_label(button_to_reset, "")
dpg.bind_item_theme(button_to_reset, "tile_theme")
# Restart keyboard state
for i in string.ascii_uppercase:
dpg.bind_item_theme(f"{i}", "keyboard_theme")
wordle_game = WordleGame()