-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcrossword.py
183 lines (154 loc) · 6.45 KB
/
crossword.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
import tkinter as tk
from tkinter import messagebox
import sys, os
def resource_path(relative_path):
""" Get the absolute path to the resource, works for dev and for PyInstaller """
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
class MainWindow():
"""Main class for constructing the tkinter widgets on a tkinter window
on top of the main window with the explanation of the game.
"""
def __init__(self, master):
"""Create the top level window.
Args:
master (tkinter.Tk): window of the general game
"""
self.top = tk.Toplevel(master)
self.top.attributes('-topmost', True)
self.top.attributes('-topmost', False)
def create_descriptions(self, descriptions, des_font):
"""Create labels with the descriptions of the crossword keys.
Args:
descriptions (list): list of strings with the words' definitions
des_font (int): font size for the description text
"""
i = 0
for des in descriptions:
tk.Label(self.top, text=des, font=('Helvetica', \
des_font)).grid(row=i, column=0)
i += 1
def create_entries(self, let_pos, wid, let_font):
"""Create the entries where the player can write the words and
implement that after the player has pressed a key, the cursor moves to
the next entry.
Args:
let_pos (list): list of positions for the entries
wid (int): width of the entries
let_font (int): font size for the text written on the entries
"""
self.let_dic = {}
for pos in let_pos:
if pos[1] == 7:
bg_color = '#ccccff'
else:
bg_color = '#ffffff'
self.let_dic[str(pos)] = tk.Entry(self.top, font=('Helvetica', \
let_font), background = bg_color, width = wid)
self.let_dic[str(pos)].grid(row=pos[0], column=pos[1])
entries = [child for child in self.top.winfo_children() if \
isinstance(child, tk.Entry)]
for idx, entry in enumerate(entries):
entry.bind('<Key>', lambda e, idx=idx: self.go_to_entry(e, \
entries, idx))
def go_to_entry(self, event, entry_list, this_index):
"""Go to the next or previous entry depending on the key pressed by the
player. The event.keycode = 8 corresponds to the backspace key
Args:
event (tkinter.Event): event: the player has pressed a key
entry_list (list): list of entries
this_index (int): index of the position of the entry where the
player is at
"""
if event.keycode == 8:
self.go_to_previous_entry(entry_list, this_index)
elif event.char == event.keysym:
self.go_to_next_entry(entry_list, this_index)
else:
pass
def go_to_next_entry(self, entry_list, this_index):
"""Go to the next entry when the player presses a letter key
Args:
entry_list (list): list of entries
this_index (int): index of the position of the entry where the
player is at
"""
next_index = (this_index + 1) % len(entry_list)
entry_list[next_index].focus_set()
def go_to_previous_entry(self, entry_list, this_index):
"""Go to the previous entry when the player presses a non-letter key,
such as the backspace
Args:
entry_list (list): list of entries
this_index (int): index of the position of the entry where the
player is at
"""
previous_index = (this_index - 1) % len(entry_list)
entry_list[previous_index].focus_set()
entry_list[previous_index].delete(0, tk.END)
def create_next_button(self, img_next):
"""Create a button to check whether the player has correctly filled the
crossword.
Args:
img_next (tkinter.PhotoImage): image displayed in the button
"""
tk.Button(self.top, height=50, width=50, image=img_next,
command=lambda: self.retrieve_input()).grid(row=6, column=10)
def message_box(self):
"""Generate a warning message in case the message is not correct"""
root = tk.Toplevel(self.top)
root.attributes('-topmost', True)
root.geometry("+650+100")
root.withdraw()
messagebox.showinfo('Oh oh', 'Wrong message. Try again!')
try:
root.destroy()
except:
pass
def retrieve_input(self):
"""Read the letters written in the entries on position 5, and compare
to the correct message. If the written message is correct, the game
window is destroyed. Otherwise, a warning message stating that the
message is incorrect is shown.
"""
message = 'NOCHES'
written_message = ''
for i in range(0,6):
let_id = '['+str(i)+', 7]'
written_message += self.let_dic[let_id].get().upper()
if message == written_message:
self.top.destroy()
self.top.quit()
else:
self.message_box()
self.top.attributes('-topmost', True)
self.top.attributes('-topmost', False)
def main_crossword(master):
"""Function for the crossword, based on key concepts from balloons. By
correctly filling the words, the message for the main game is extracted.
Args:
master (tkinter.Tk): window of the general game.
"""
w = MainWindow(master)
descriptions = [
'Not a plane, nor a helicopter, neither a zeppelin',
'What ties the balloon to the basket?',
'Vehicle that rescues you once you land',
'How is the air inside the balloon?',
'It heats the air so the balloon can fly',
'They look like cotton balls'
]
let_pos = [
[0, 1],[0, 2],[0, 3],[0, 4],[0, 5],[0, 6],[0, 7],[1, 6],[1, 7],[1, 8],
[1, 9],[2, 7],[2, 8],[2, 9],[3, 7],[3, 8],[3, 9],[4, 4],[4, 5],[4, 6],
[4, 7],[5, 2],[5, 3],[5, 4],[5, 5],[5, 6],[5, 7]
]
img_next = tk.PhotoImage(file=resource_path('figures/0_0_next.png'))
w.create_descriptions(descriptions,16)
w.create_entries(let_pos, 2, 18)
w.create_next_button(img_next)
w.top.mainloop()