forked from Marken-Foo/tsumemi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathboard_canvas.py
More file actions
159 lines (146 loc) · 6.12 KB
/
board_canvas.py
File metadata and controls
159 lines (146 loc) · 6.12 KB
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
from collections import Counter
from tkinter import Canvas
from tkinter import font
from kif_parser import KanjiNumber
class BoardCanvas(Canvas):
'''Class encapsulating the canvas where the board is drawn.'''
# Default/current canvas size for board
canvas_width = 600
canvas_height = 500
# Constant proportions
SQ_ASPECT_RATIO = 11 / 12
KOMADAI_W_IN_SQ = 1.7
INNER_H_PAD = 30
def __init__(self, parent, controller, *args, **kwargs):
self.controller = controller
self.is_upside_down = False
super().__init__(parent, *args, **kwargs)
return
def draw(self):
# Specify source of board data
reader = self.controller.model.reader
# Clear board display - could also keep board and just redraw pieces
self.delete("all")
(sq_w, sq_h, komadai_w, w_pad, h_pad, sq_text_size,
komadai_text_size, coords_text_size) = self.calculate_sizes()
def x_sq(i):
return w_pad + komadai_w + sq_w * i
def y_sq(j):
return h_pad + sq_h * j
# Note: if is_upside_down, essentially performs a deep copy,
# but just "passes by reference" the reader's board if not.
if self.is_upside_down:
south_hand = reader.board.gote_hand
north_hand = reader.board.sente_hand
south_board = reader.board.gote[::-1]
north_board = reader.board.sente[::-1]
for i, row in enumerate(south_board):
south_board[i] = row[::-1]
for i, row in enumerate(north_board):
north_board[i] = row[::-1]
south_hand_strings = ["△\n持\n駒\n"]
north_hand_strings = ["▲\n持\n駒\n"]
row_coords = [" " + KanjiNumber(i).name for i in range(9, 0, -1)]
col_coords = [str(i) for i in range(1, 10, 1)]
else:
south_hand = reader.board.sente_hand
north_hand = reader.board.gote_hand
south_board = reader.board.sente
north_board = reader.board.gote
south_hand_strings = ["▲\n持\n駒\n"]
north_hand_strings = ["△\n持\n駒\n"]
row_coords = [" " + KanjiNumber(i).name for i in range(1, 10, 1)]
col_coords = [str(i) for i in range(9, 0, -1)]
# Draw board
for i in range(10):
self.create_line(x_sq(i), y_sq(0), x_sq(i), y_sq(9),
fill="black", width=1)
self.create_line(x_sq(0), y_sq(i), x_sq(9), y_sq(i),
fill="black", width=1)
# Draw board pieces
for row_num, row in enumerate(south_board):
for col_num, piece in enumerate(row):
self.create_text(
x_sq(col_num+0.5), y_sq(row_num+0.5),
text=str(piece),
font=(font.nametofont("TkDefaultFont"), sq_text_size)
)
for row_num, row in enumerate(north_board):
for col_num, piece in enumerate(row):
self.create_text(
x_sq(col_num+0.5), y_sq(row_num+0.5),
text=str(piece),
font=(font.nametofont("TkDefaultFont"), sq_text_size),
angle=180
)
# Draw board coordinates
for row_num in range(9):
self.create_text(
x_sq(9), y_sq(row_num+0.5),
text=" " + row_coords[row_num],
font=(font.nametofont("TkDefaultFont"), coords_text_size),
anchor="w"
)
for col_num in range(9):
self.create_text(
x_sq(col_num+0.5), y_sq(0),
text=col_coords[col_num],
font=(font.nametofont("TkDefaultFont"), coords_text_size),
anchor="s"
)
# Draw sente hand pieces
c = Counter(south_hand)
for piece in c:
south_hand_strings.append(str(piece) + str(c[piece]))
if len(south_hand_strings) == 1:
south_hand_strings.append("な\nし")
self.create_text(
x_sq(9) + komadai_w, y_sq(9),
text="\n".join(south_hand_strings),
font=(font.nametofont("TkDefaultFont"), komadai_text_size),
anchor="se"
)
# Draw gote hand pieces
c = Counter(north_hand)
for piece in c:
north_hand_strings.append(str(piece) + str(c[piece]))
if len(north_hand_strings) == 1:
north_hand_strings.append("な\nし")
self.create_text(
w_pad, h_pad,
text="\n".join(north_hand_strings),
font=(font.nametofont("TkDefaultFont"), komadai_text_size),
anchor="nw"
)
return
def on_resize(self, event):
self.canvas_width = event.width
self.canvas_height = event.height
# Redraw board after setting new dimensions
self.draw()
return
def calculate_sizes(self):
# Geometry: 9x9 shogi board, flanked by komadai area on either side
max_sq_w = self.canvas_width / (9 + 2*self.KOMADAI_W_IN_SQ)
max_sq_h = (self.canvas_height - 2*self.INNER_H_PAD) / 9
# Determine whether the width or the height is the limiting factor
sq_w = min(max_sq_w, max_sq_h*self.SQ_ASPECT_RATIO)
# Propagate other measurements
sq_h = sq_w / self.SQ_ASPECT_RATIO
komadai_w = sq_w * self.KOMADAI_W_IN_SQ
if sq_w == max_sq_w:
w_pad = 0
h_pad = self.INNER_H_PAD + (self.canvas_height - 9*sq_h) / 2
else:
w_pad = (self.canvas_width - 2*komadai_w - 9*sq_w) / 2
h_pad = self.INNER_H_PAD
sq_text_size = int(sq_w * 7/10)
komadai_text_size = int(sq_w * 2/5)
coords_text_size = int(sq_w * 2/9)
return (sq_w, sq_h, komadai_w, w_pad, h_pad,
sq_text_size, komadai_text_size, coords_text_size)
def flip_board(self, want_upside_down):
if self.is_upside_down != want_upside_down:
self.is_upside_down = want_upside_down
self.draw()
return