cli-othello 1.0.2__tar.gz → 1.0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cli_othello-1.0.2 → cli_othello-1.0.3}/PKG-INFO +1 -1
- {cli_othello-1.0.2 → cli_othello-1.0.3}/pyproject.toml +1 -1
- {cli_othello-1.0.2 → cli_othello-1.0.3}/src/cli_othello/__init__.py +1 -1
- {cli_othello-1.0.2 → cli_othello-1.0.3}/src/cli_othello/ui.py +68 -27
- {cli_othello-1.0.2 → cli_othello-1.0.3}/src/cli_othello.egg-info/PKG-INFO +1 -1
- {cli_othello-1.0.2 → cli_othello-1.0.3}/README.md +0 -0
- {cli_othello-1.0.2 → cli_othello-1.0.3}/setup.cfg +0 -0
- {cli_othello-1.0.2 → cli_othello-1.0.3}/src/cli_othello/ai.py +0 -0
- {cli_othello-1.0.2 → cli_othello-1.0.3}/src/cli_othello/board.py +0 -0
- {cli_othello-1.0.2 → cli_othello-1.0.3}/src/cli_othello/cli.py +0 -0
- {cli_othello-1.0.2 → cli_othello-1.0.3}/src/cli_othello.egg-info/SOURCES.txt +0 -0
- {cli_othello-1.0.2 → cli_othello-1.0.3}/src/cli_othello.egg-info/dependency_links.txt +0 -0
- {cli_othello-1.0.2 → cli_othello-1.0.3}/src/cli_othello.egg-info/entry_points.txt +0 -0
- {cli_othello-1.0.2 → cli_othello-1.0.3}/src/cli_othello.egg-info/requires.txt +0 -0
- {cli_othello-1.0.2 → cli_othello-1.0.3}/src/cli_othello.egg-info/top_level.txt +0 -0
|
@@ -9,15 +9,24 @@ from .board import BLACK, EMPTY, SIZE, WHITE, Board, opponent
|
|
|
9
9
|
|
|
10
10
|
PLAYER_NAMES = {BLACK: "黒", WHITE: "白"}
|
|
11
11
|
|
|
12
|
-
# Each cell is
|
|
13
|
-
#
|
|
12
|
+
# Each cell's interior is CELL_W columns x CELL_H rows, not counting the
|
|
13
|
+
# grid lines drawn around it, so it reads as roughly square in a terminal
|
|
14
|
+
# (chars are about twice as tall as wide). All glyphs used inside the grid
|
|
15
|
+
# are plain ASCII: full-width characters (e.g. "●", "○") have ambiguous
|
|
16
|
+
# display width and end up misaligned in many terminals/fonts, so discs
|
|
17
|
+
# are shown as a colored background plus a half-width letter instead.
|
|
14
18
|
CELL_W = 5
|
|
15
19
|
CELL_H = 2
|
|
16
20
|
|
|
17
|
-
DISC_BLACK = "
|
|
18
|
-
DISC_WHITE = "
|
|
21
|
+
DISC_BLACK = "@"
|
|
22
|
+
DISC_WHITE = "O"
|
|
19
23
|
HINT_MARK = "+"
|
|
20
24
|
|
|
25
|
+
# Box-drawing characters for the grid lines between cells.
|
|
26
|
+
_TL, _TR, _BL, _BR = "┌", "┐", "└", "┘"
|
|
27
|
+
_H, _V = "─", "│"
|
|
28
|
+
_T_DOWN, _T_UP, _T_RIGHT, _T_LEFT, _CROSS = "┬", "┴", "├", "┤", "┼"
|
|
29
|
+
|
|
21
30
|
COLOR_BOARD = 1
|
|
22
31
|
COLOR_BLACK = 2
|
|
23
32
|
COLOR_WHITE = 3
|
|
@@ -60,7 +69,7 @@ def select_level(stdscr: "curses._CursesWindow") -> int:
|
|
|
60
69
|
if max_y < required_rows or max_x < required_cols:
|
|
61
70
|
_draw_too_small(stdscr)
|
|
62
71
|
continue
|
|
63
|
-
stdscr.addstr(1, 2, "
|
|
72
|
+
stdscr.addstr(1, 2, "CLI OTHELLO", curses.color_pair(COLOR_HEADER) | curses.A_BOLD)
|
|
64
73
|
stdscr.addstr(3, 2, "対戦するAIの強さを選んでください", curses.A_BOLD)
|
|
65
74
|
for i in range(MIN_LEVEL, MAX_LEVEL + 1):
|
|
66
75
|
label = LEVEL_LABELS[i]
|
|
@@ -116,8 +125,11 @@ def _required_size() -> tuple[int, int]:
|
|
|
116
125
|
"""Return (rows, cols) needed to draw the board and panel, plus a
|
|
117
126
|
1-line/1-column margin (curses can refuse writes to the very last
|
|
118
127
|
row/column of the screen)."""
|
|
119
|
-
|
|
120
|
-
|
|
128
|
+
grid_rows = 1 + SIZE * (CELL_H + 1)
|
|
129
|
+
grid_cols = 1 + SIZE * (CELL_W + 1)
|
|
130
|
+
row_label_w = 3
|
|
131
|
+
rows = 3 + 1 + grid_rows + 6 + 1
|
|
132
|
+
cols = 4 + row_label_w + grid_cols + 1
|
|
121
133
|
return rows, cols
|
|
122
134
|
|
|
123
135
|
|
|
@@ -153,7 +165,7 @@ def _draw_board(
|
|
|
153
165
|
return False
|
|
154
166
|
|
|
155
167
|
stdscr.erase()
|
|
156
|
-
stdscr.addstr(top, 2, "
|
|
168
|
+
stdscr.addstr(top, 2, "CLI OTHELLO", curses.color_pair(COLOR_HEADER) | curses.A_BOLD)
|
|
157
169
|
stdscr.addstr(
|
|
158
170
|
top + 1,
|
|
159
171
|
2,
|
|
@@ -164,29 +176,58 @@ def _draw_board(
|
|
|
164
176
|
board_top = top + 3
|
|
165
177
|
board_left = 4
|
|
166
178
|
grid_attr = curses.color_pair(COLOR_GRID)
|
|
179
|
+
row_label_w = 3
|
|
167
180
|
|
|
168
|
-
# Column labels (A-H), centered above each cell
|
|
169
|
-
|
|
181
|
+
# Column labels (A-H), centered above each cell (account for the
|
|
182
|
+
# leading grid line and the row-label gutter).
|
|
183
|
+
header = " " * row_label_w + " "
|
|
170
184
|
for col in range(SIZE):
|
|
171
|
-
header += "ABCDEFGH"[col].center(CELL_W)
|
|
185
|
+
header += "ABCDEFGH"[col].center(CELL_W) + " "
|
|
172
186
|
stdscr.addstr(board_top, board_left, header, curses.A_BOLD)
|
|
173
187
|
|
|
174
|
-
|
|
188
|
+
grid_top = board_top + 1
|
|
189
|
+
grid_left = board_left + row_label_w
|
|
190
|
+
grid_cols = 1 + SIZE * (CELL_W + 1)
|
|
191
|
+
grid_rows = 1 + SIZE * (CELL_H + 1)
|
|
192
|
+
board_width = row_label_w + grid_cols
|
|
193
|
+
|
|
194
|
+
# Draw the grid lines (the lattice of cell borders) first.
|
|
195
|
+
for r in range(SIZE + 1):
|
|
196
|
+
y = grid_top + r * (CELL_H + 1)
|
|
197
|
+
if r == 0:
|
|
198
|
+
left, mid, right = _TL, _T_DOWN, _TR
|
|
199
|
+
elif r == SIZE:
|
|
200
|
+
left, mid, right = _BL, _T_UP, _BR
|
|
201
|
+
else:
|
|
202
|
+
left, mid, right = _T_RIGHT, _CROSS, _T_LEFT
|
|
203
|
+
line = left + (_H * CELL_W + mid) * SIZE
|
|
204
|
+
line = line[:-1] + right
|
|
205
|
+
stdscr.addstr(y, grid_left, line, grid_attr)
|
|
206
|
+
if r < SIZE:
|
|
207
|
+
for line_offset in range(1, CELL_H + 1):
|
|
208
|
+
y2 = y + line_offset
|
|
209
|
+
stdscr.addstr(y2, grid_left, _V, grid_attr)
|
|
210
|
+
stdscr.addstr(y2, grid_left + grid_cols - 1, _V, grid_attr)
|
|
211
|
+
for c in range(1, SIZE):
|
|
212
|
+
x = grid_left + c * (CELL_W + 1)
|
|
213
|
+
stdscr.addstr(y2, x, _V, grid_attr)
|
|
214
|
+
|
|
215
|
+
# Row labels (1-8), centered next to each cell.
|
|
175
216
|
for row in range(SIZE):
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if line == CELL_H // 2:
|
|
217
|
+
y = grid_top + 1 + row * (CELL_H + 1) + (CELL_H - 1) // 2
|
|
218
|
+
stdscr.addstr(y, board_left, f"{row + 1:>2} ", curses.A_BOLD)
|
|
219
|
+
|
|
220
|
+
# Fill each cell's interior (background + disc/hint glyph).
|
|
221
|
+
for row in range(SIZE):
|
|
222
|
+
cell_top = grid_top + 1 + row * (CELL_H + 1)
|
|
223
|
+
for col in range(SIZE):
|
|
224
|
+
cell = board.get(row, col)
|
|
225
|
+
is_cursor = (row, col) == cursor
|
|
226
|
+
is_hint = cell == EMPTY and (row, col) in legal
|
|
227
|
+
x = grid_left + 1 + col * (CELL_W + 1)
|
|
228
|
+
for line in range(CELL_H):
|
|
229
|
+
y = cell_top + line
|
|
230
|
+
if line == (CELL_H - 1) // 2:
|
|
190
231
|
attr, ch = _cell_center_attr(cell, is_cursor, is_hint)
|
|
191
232
|
text = ch.center(CELL_W)
|
|
192
233
|
else:
|
|
@@ -194,7 +235,7 @@ def _draw_board(
|
|
|
194
235
|
text = " " * CELL_W
|
|
195
236
|
stdscr.addstr(y, x, text, attr)
|
|
196
237
|
|
|
197
|
-
board_bottom =
|
|
238
|
+
board_bottom = grid_top + grid_rows - 1
|
|
198
239
|
panel_left = board_left
|
|
199
240
|
panel_width = board_width
|
|
200
241
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|