Skip to content

Commit 3ef2070

Browse files
committed
maze.py 1.0.1: fix linter/typing errors, reformat script, remove history, add SPDX copyright and license tags
1 parent 3417530 commit 3ef2070

2 files changed

Lines changed: 80 additions & 97 deletions

File tree

REUSE.toml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,12 +1331,6 @@ precedence = "override"
13311331
SPDX-FileCopyrightText = "2015-2016 Jos Ahrens <zarthus@lovebytes.me>"
13321332
SPDX-License-Identifier = "MIT"
13331333

1334-
[[annotations]]
1335-
path = "python/maze.py"
1336-
precedence = "override"
1337-
SPDX-FileCopyrightText = "2012-2022 Sébastien Helleu <flashcode@flashtux.org>"
1338-
SPDX-License-Identifier = "GPL-3.0-or-later"
1339-
13401334
[[annotations]]
13411335
path = "python/memon.py"
13421336
precedence = "override"

python/maze.py

Lines changed: 80 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#
2-
# Copyright (C) 2012-2022 Sébastien Helleu <flashcode@flashtux.org>
2+
# SPDX-FileCopyrightText: 2012-2026 Sébastien Helleu <flashcode@flashtux.org>
3+
#
4+
# SPDX-License-Identifier: GPL-3.0-or-later
35
#
46
# This program is free software; you can redistribute it and/or modify
57
# it under the terms of the GNU General Public License as published by
@@ -15,26 +17,14 @@
1517
# along with this program. If not, see <http://www.gnu.org/licenses/>.
1618
#
1719

18-
#
19-
# Interactive maze generator and solver for WeeChat.
20-
#
21-
# History:
22-
#
23-
# 2022-02-20, Sébastien Helleu <flashcode@flashtux.org>:
24-
# version 1.0.0: first public version
25-
# 2012-10-10, Sébastien Helleu <flashcode@flashtux.org>:
26-
# version 0.0.1: initial release
27-
#
28-
29-
"""Maze generator and solver for WeeChat."""
30-
31-
from dataclasses import dataclass, field
32-
from typing import ClassVar, Dict, List, Optional, Tuple
20+
"""Interactive maze generator and solver for WeeChat."""
3321

3422
import random
23+
from dataclasses import dataclass, field
3524

3625
try:
37-
import weechat
26+
import weechat # type: ignore[import]
27+
3828
IMPORT_OK = True
3929
except ImportError:
4030
print("This script must be run under WeeChat.")
@@ -43,13 +33,13 @@
4333

4434
SCRIPT_NAME = "maze"
4535
SCRIPT_AUTHOR = "Sébastien Helleu <flashcode@flashtux.org>"
46-
SCRIPT_VERSION = "1.0.0"
36+
SCRIPT_VERSION = "1.0.1"
4737
SCRIPT_LICENSE = "GPL3"
4838
SCRIPT_DESC = "Interactive maze generator and solver"
4939

5040
SCRIPT_COMMAND = "maze"
5141

52-
MAZE_KEYS: Dict[str, Tuple[str, str]] = {
42+
MAZE_KEYS: dict[str, tuple[str, str]] = {
5343
"n": ("", "new maze"),
5444
"d": ("default", "default size"),
5545
"+": ("+", "bigger"),
@@ -63,23 +53,23 @@
6353
@dataclass
6454
class Maze:
6555
"""Maze."""
56+
6657
width: int = 0
6758
height: int = 0
6859

69-
cells: List[int] = field(default_factory=list, init=False)
70-
solution: List[tuple[int, int, bool]] = field(default_factory=list,
71-
init=False)
60+
cells: list[int] = field(default_factory=list, init=False)
61+
solution: list[tuple[int, int, bool]] = field(default_factory=list, init=False)
7262
buffer: str = field(init=False)
7363
timer: str = field(default="", init=False)
7464

7565
# cell status
76-
VISITED: ClassVar[int] = 1 # visited cell
77-
TOP: ClassVar[int] = 2 # door opened on top
78-
BOTTOM: ClassVar[int] = 4 # door opened on bottom
79-
LEFT: ClassVar[int] = 8 # door opened on the left
80-
RIGHT: ClassVar[int] = 16 # door opened on the right
81-
SOLUTION: ClassVar[int] = 32 # cell part of the solution
82-
SOLUTION_INT: ClassVar[int] = 64 # cell displayed for solution
66+
VISITED: int = 1 # visited cell
67+
TOP: int = 2 # door opened on top
68+
BOTTOM: int = 4 # door opened on bottom
69+
LEFT: int = 8 # door opened on the left
70+
RIGHT: int = 16 # door opened on the right
71+
SOLUTION: int = 32 # cell part of the solution
72+
SOLUTION_INT: int = 64 # cell displayed for solution
8373

8474
def __post_init__(self) -> None:
8575
"""Initialize maze with the given size."""
@@ -89,10 +79,9 @@ def __post_init__(self) -> None:
8979
self.solution = []
9080
self.buffer = Maze.open_buffer()
9181
if self.buffer:
92-
keys = ", ".join([
93-
f"alt+\"{key}\": {value[1]}"
94-
for key, value in MAZE_KEYS.items()
95-
])
82+
keys = ", ".join(
83+
[f'alt+"{key}": {value[1]}' for key, value in MAZE_KEYS.items()]
84+
)
9685
weechat.buffer_set(
9786
self.buffer,
9887
"title",
@@ -123,8 +112,8 @@ def open_buffer() -> str:
123112
return buf
124113

125114
def get_adjacent_cells(
126-
self, col: int, line: int
127-
) -> List[Tuple[int, int, int, int]]:
115+
self, col: int, line: int
116+
) -> list[tuple[int, int, int, int]]:
128117
"""Get adjacent cells."""
129118
list_cells = []
130119
if col < self.width - 1: # right
@@ -144,11 +133,11 @@ def generate(self) -> None:
144133
col: int = 0
145134
line: int = 0
146135
self.cells[0] |= self.VISITED
147-
stack: List[Tuple[int, int]] = []
136+
stack: list[tuple[int, int]] = []
148137
while True:
149138
pos: int = (line * self.width) + col
150-
list_cells: List[Tuple[int, int, int, int]] = (
151-
self.get_adjacent_cells(col, line)
139+
list_cells: list[tuple[int, int, int, int]] = self.get_adjacent_cells(
140+
col, line
152141
)
153142
random.shuffle(list_cells)
154143
for col2, line2, to_neighbor, from_neighbor in list_cells:
@@ -171,25 +160,28 @@ def solve(self, interactive: bool = False) -> None:
171160
"""Solve a maze: find path from entry (0,0) to exit (n,n)."""
172161
self.remove_timer()
173162
for index, cell in enumerate(self.cells):
174-
self.cells[index] = cell & ~(self.VISITED | self.SOLUTION
175-
| self.SOLUTION_INT)
163+
self.cells[index] = cell & ~(
164+
self.VISITED | self.SOLUTION | self.SOLUTION_INT
165+
)
176166
col: int = 0
177167
line: int = 0
178168
self.cells[0] |= self.SOLUTION
179169
self.solution = [(col, line, True)]
180-
stack: List[Tuple[int, int]] = []
170+
stack: list[tuple[int, int]] = []
181171
visited_solution = self.VISITED | self.SOLUTION
182172
while not self.cells[-1] & self.SOLUTION:
183173
pos: int = (line * self.width) + col
184174
self.cells[pos] |= self.VISITED
185-
list_cells: List[Tuple[int, int, int, int]] = (
186-
self.get_adjacent_cells(col, line)
175+
list_cells: list[tuple[int, int, int, int]] = self.get_adjacent_cells(
176+
col, line
187177
)
188178
for col2, line2, to_neighbor, _ in list_cells:
189179
pos2: int = (line2 * self.width) + col2
190180
# door opened and neighbor not visited/solution?
191-
if self.cells[pos] & to_neighbor \
192-
and not self.cells[pos2] & visited_solution:
181+
if (
182+
self.cells[pos] & to_neighbor
183+
and not self.cells[pos2] & visited_solution
184+
):
193185
self.cells[pos2] |= visited_solution
194186
self.solution.append((col2, line2, True))
195187
stack.append((col, line))
@@ -217,27 +209,27 @@ def display_line(self, line: int) -> None:
217209
"""Display a line of maze."""
218210
str_line: str
219211
if line >= self.height:
220-
str_line = (
221-
weechat.color("white")
222-
+ ("▀" * ((self.width * 2) + 1))
223-
)
212+
str_line = weechat.color("white") + ("▀" * ((self.width * 2) + 1))
224213
else:
225214
both_sol: int = self.SOLUTION | self.SOLUTION_INT
226215
cell: int = self.cells[line * self.width]
227216
color: str = (
228-
"lightred" if cell & self.SOLUTION_INT
229-
else "blue" if cell & self.SOLUTION
217+
"lightred"
218+
if cell & self.SOLUTION_INT
219+
else "blue"
220+
if cell & self.SOLUTION
230221
else "black"
231222
)
232-
str_line = (
233-
weechat.color(f"{color},white")
234-
+ ("▄" if cell & self.LEFT else " ")
223+
str_line = weechat.color(f"{color},white") + (
224+
"▄" if cell & self.LEFT else " "
235225
)
236226
for col in range(self.width):
237227
cell = self.cells[(line * self.width) + col]
238228
color = (
239-
"lightred" if cell & self.SOLUTION_INT
240-
else "blue" if cell & self.SOLUTION
229+
"lightred"
230+
if cell & self.SOLUTION_INT
231+
else "blue"
232+
if cell & self.SOLUTION
241233
else "black"
242234
)
243235
# door opened on top?
@@ -250,9 +242,8 @@ def display_line(self, line: int) -> None:
250242
else:
251243
str_line += weechat.color(f"{color},white") + "▄"
252244
# door opened on the right?
253-
str_line += (
254-
weechat.color(f"{color},white")
255-
+ ("▄" if cell & self.RIGHT else " ")
245+
str_line += weechat.color(f"{color},white") + (
246+
"▄" if cell & self.RIGHT else " "
256247
)
257248
str_line += weechat.color("reset")
258249
weechat.prnt_y(self.buffer, line, str_line)
@@ -278,9 +269,6 @@ def show_interactive_solution(self) -> None:
278269

279270
def show_next_solution(self) -> None:
280271
"""Show next solution step."""
281-
col: int
282-
line: int
283-
show: bool
284272
col, line, show = self.solution.pop(0)
285273
pos: int = (line * self.width) + col
286274
if show:
@@ -296,10 +284,10 @@ def __del__(self) -> None:
296284
self.remove_timer()
297285

298286

299-
maze: Optional[Maze] = None
287+
maze: Maze | None = None
300288

301289

302-
def maze_input_buffer(data: str, buffer: str, str_input: str) -> int:
290+
def maze_input_buffer(_data: str, buffer: str, str_input: str) -> int:
303291
"""Input data in maze buffer."""
304292
# pylint: disable=unused-argument
305293
if str_input.lower() == "q":
@@ -309,23 +297,23 @@ def maze_input_buffer(data: str, buffer: str, str_input: str) -> int:
309297
return weechat.WEECHAT_RC_OK
310298

311299

312-
def maze_close_buffer(data: str, buffer: str) -> int:
300+
def maze_close_buffer(_data: str, _buffer: str) -> int:
313301
"""Called when maze buffer is closed."""
314302
# pylint: disable=unused-argument
315303
global maze
316304
maze = None
317305
return weechat.WEECHAT_RC_OK
318306

319307

320-
def maze_timer_cb(data: str, remaining_calls: int) -> int:
308+
def maze_timer_cb(_data: str, _remaining_calls: int) -> int:
321309
"""Timer used to show solution, one cell by one cell."""
322310
global maze
323311
if maze:
324312
maze.show_next_solution()
325313
return weechat.WEECHAT_RC_OK
326314

327315

328-
def maze_get_size(args: str = "") -> Tuple[int, int]:
316+
def maze_get_size(args: str = "") -> tuple[int, int]:
329317
"""Get maze size with args, defaulting to current maze or window size."""
330318
global maze
331319
width: int = 0
@@ -348,20 +336,20 @@ def maze_get_size(args: str = "") -> Tuple[int, int]:
348336
width, height = 0, 0
349337
if not width or not height:
350338
# automatic size with size of window
351-
win_width: int = weechat.window_get_integer(weechat.current_window(),
352-
"win_chat_width") - 1
353-
win_height: int = weechat.window_get_integer(weechat.current_window(),
354-
"win_chat_height") - 1
339+
win_width: int = (
340+
weechat.window_get_integer(weechat.current_window(), "win_chat_width") - 1
341+
)
342+
win_height: int = (
343+
weechat.window_get_integer(weechat.current_window(), "win_chat_height") - 1
344+
)
355345
size: int = min(win_width, win_height)
356346
width, height = size, size
357347
return width, height
358348

359349

360-
def maze_get_other_size(pct_diff: int) -> Tuple[int, int]:
350+
def maze_get_other_size(pct_diff: int) -> tuple[int, int]:
361351
"""Get another size using a percent of size to add or subtract."""
362352
factor: int = pct_diff // abs(pct_diff)
363-
width: int
364-
height: int
365353
width, height = maze_get_size()
366354
add_width: int = max(2, (width * abs(pct_diff)) // 100)
367355
add_height: int = max(2, (height * abs(pct_diff)) // 100)
@@ -378,11 +366,9 @@ def maze_new(width: int, height: int) -> None:
378366
maze.display()
379367

380368

381-
def maze_cmd_cb(data: str, buffer: str, args: str) -> int:
369+
def maze_cmd_cb(_data: str, _buffer: str, args: str) -> int:
382370
"""The /maze command."""
383371
global maze
384-
width: int
385-
height: int
386372
if args in ("s", "solve"):
387373
if maze:
388374
maze.solve()
@@ -403,21 +389,24 @@ def maze_cmd_cb(data: str, buffer: str, args: str) -> int:
403389
width, height = maze_get_size()
404390
else:
405391
error = weechat.prefix("error")
406-
weechat.prnt("", f"{error}maze error: unknown option \"{args}\"")
392+
weechat.prnt("", f'{error}maze error: unknown option "{args}"')
407393
return weechat.WEECHAT_RC_OK
408394
maze_new(width, height)
409395
return weechat.WEECHAT_RC_OK
410396

411397

412-
if __name__ == "__main__" and IMPORT_OK:
413-
if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION,
414-
SCRIPT_LICENSE, SCRIPT_DESC, "", ""):
415-
weechat.hook_command(
416-
SCRIPT_COMMAND,
417-
"Generate and solve a maze.",
418-
"size || n|new || d|default || s|solve || i|isolve || r|reset "
419-
"|| +|-",
420-
"""\
398+
if (
399+
__name__ == "__main__"
400+
and IMPORT_OK
401+
and weechat.register(
402+
SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, "", ""
403+
)
404+
):
405+
weechat.hook_command(
406+
SCRIPT_COMMAND,
407+
"Generate and solve a maze.",
408+
"size || n|new || d|default || s|solve || i|isolve || r|reset || +|-",
409+
"""\
421410
size: one size (square) or width and height separated by spaces
422411
new: regenerate another maze
423412
default: regenerate another maze with default size
@@ -429,7 +418,7 @@ def maze_cmd_cb(data: str, buffer: str, args: str) -> int:
429418
430419
All options shown above can be given in input of maze buffer.
431420
""",
432-
"",
433-
"maze_cmd_cb",
434-
"",
435-
)
421+
"",
422+
"maze_cmd_cb",
423+
"",
424+
)

0 commit comments

Comments
 (0)