实现一个无限大小的五子棋棋盘
主要思想:创建GlobalGame类,完成大部分操作。使用tkinter进行灵活的布局
完整代码:
import tkinter
class GlobalGame:
def __init__(self, in_canvas: tkinter.Canvas, call_back, update_back):
self._in_canvas = in_canvas
self._call_back = call_back
self._update_back = update_back
self._width = 17
self._elements = []
self._now_player = -1 # -1为黑,1为白
self._datas: dict = {(0, 0): None}
self._step_datas: list = []
self._coord = [0, 0]
self._update()
# init drawing
for i in range(1, self._width + 1):
self._in_canvas.create_line(i * 30, 30, i * 30, 510, width=3, fill='#66593E')
self._in_canvas.create_line(30, i * 30, 510, i * 30, width=3, fill='#66593E')
# init event binding
self._in_canvas.bind('<ButtonRelease-1>', self._cin)
@property
def now_player(self):
return self._now_player
def _cin(self, event):
coord = self._real_to(event.x, event.y)
# print(self.real_to(event.x, event.y))
if self._datas.get(coord) is None:
self._datas[coord] = self._now_player
self._step_datas.append(coord)
# print(coord)
# 获胜判定
last_times = 0
for v, p in [(i, (coord[0] - i[0] * 4, coord[1] - i[1] * 4)) for i in ((1, 0), (1, 1), (0, 1), (-1, 1))]:
last_times_t = 0
for i in range(9):
# print(self._datas.get((p[0] + v[0] * i, p[1] + v[1] * i)))
if self._datas.get((p[0] + v[0] * i, p[1] + v[1] * i)) == self._now_player:
last_times_t += 1
last_times = max(last_times_t, last_times)
else:
last_times_t = 0
# print(last_times)
if last_times >= 5:
self._call_back('{}棋获胜!!!\n'.format({-1: '黑', 1: '白'}[self._now_player]))
self.clear()
self._now_player *= -1
else:
self._call_back('此处有棋!\n')
self._update()
# print(self.datas)
def get_output(self):
pass
def change_mod(self):
pass
def _to_real(self, ix, iy) -> tuple:
if isinstance(ix, tuple):
return (ix[0] - self._coord[0] + 9) * 30, (-ix[1] + self._coord[1] + 9) * 30
else:
return (ix - self._coord[0] + 9) * 30, (-iy + self._coord[1] + 9) * 30
def _real_to(self, rx, ry) -> tuple:
if isinstance(rx, tuple):
return (round(rx[0] / 30) - 9 + self._coord[0]), -(round(rx[1] / 30) - 9 - self._coord[1])
else:
return (round(rx / 30) - 9 + self._coord[0]), -(round(ry / 30) - 9 - self._coord[1])
def set_coord(self, x, y):
if isinstance(x, (tuple, list)):
self._coord[0] = x[0]
self._coord[1] = x[1]
else:
self._coord[0] = x
self._coord[1] = y
self._update()
def add_v_coord(self, dx, dy):
if isinstance(dx, (tuple, list)):
self._coord[0] += dx[0]
self._coord[1] += dx[1]
else:
self._coord[0] += dx
self._coord[1] += dy
self._update()
def undo(self):
try:
del self._datas[self._step_datas[-1]], self._step_datas[-1]
self._now_player *= -1
self._update()
except IndexError:
self._call_back('无棋子可撤销\n')
def clear(self):
self._datas = {(0, 0): None}
self._step_datas = []
self._update()
self._call_back('已清空\n')
self._now_player = -1
def _update(self):
self._update_back(self)
for i in self._elements:
cav.delete(i)
w = self._width
for ix, iy in tuple((i % w - 8 + self._coord[0], i // w - 8 + self._coord[1]) for i in range(w ** 2)):
rc = self._to_real(ix, iy)
if ix % 6 == 0 and iy % 6 == 0:
# print(ix, iy)
self._elements.append(self._in_canvas.create_oval(rc[0] - 5, rc[1] - 5, rc[0] + 5, rc[1] + 5,
outline='#66593E', fill='#66593E'))
if self._datas.get((ix, iy)):
self._elements.append(self._in_canvas.create_oval(rc[0] - 9, rc[1] - 9, rc[0] + 9, rc[1] + 9,
outline='#000000' if self._datas.get((ix, iy)) == -1 else '#FFFFFF',
fill='#000000' if self._datas.get((ix, iy)) == -1 else '#FFFFFF'))
ft = ('微软雅黑', 11)
self._elements.append(self._in_canvas.create_text(30, 30, text='({}, {})'.format(self._coord[0] - 8, self._coord[1] + 8), font=ft, anchor='s'))
self._elements.append(self._in_canvas.create_text(510, 30, text='({}, {})'.format(self._coord[0] + 8, self._coord[1] + 8), font=ft, anchor='s'))
self._elements.append(self._in_canvas.create_text(30, 510, text='({}, {})'.format(self._coord[0] - 8, self._coord[1] - 8), font=ft, anchor='n'))
self._elements.append(self._in_canvas.create_text(510, 510, text='({}, {})'.format(self._coord[0] + 8, self._coord[1] - 8), font=ft, anchor='n'))
def player_update(in_game: GlobalGame, in_lb: tkinter.Label):
if in_game.now_player == -1:
in_lb.config(foreground='#000000')
else:
in_lb.config(foreground='#FFFFFF')
if __name__ == '__main__':
root = tkinter.Tk()
root.title('五子棋棋盘')
root.geometry('960x540')
root.minsize(960, 540) # 设置窗口最小值
fr1 = tkinter.Frame(root, background='black', width=540)
fr1.place(relx=0.0, rely=0.0, relwidth=0.5625, relheight=1.0)
fr2 = tkinter.Frame(root, background='#A8975E')
fr2.place(relx=0.5625, rely=0.0, relwidth=0.4375, relheight=1.0)
cav = tkinter.Canvas(fr1, bg='#D6CD91', width=540, height=540)
cav.pack(side=tkinter.TOP)
fr21 = tkinter.Frame(fr2, background='#A8975E')
fr21.pack(side=tkinter.BOTTOM, fill=tkinter.X)
fr211 = tkinter.Frame(fr21, background='#A8975E', width=180, height=180)
fr212 = tkinter.Frame(fr21, background='#A8975E', width=180, height=180)
fr211.pack(side=tkinter.LEFT)
fr212.pack(side=tkinter.RIGHT)
lb = tkinter.Label(fr21, text='●', foreground='#000000', font=('微软雅黑', 60), background='#A8975E')
lb.pack(expand=True)
bt_n = tkinter.Button(fr211, text='↑', command=lambda: game.add_v_coord(0, 1))
bt_ne = tkinter.Button(fr211, text='↗', command=lambda: game.add_v_coord(1, 1))
bt_e = tkinter.Button(fr211, text='→', command=lambda: game.add_v_coord(1, 0))
bt_se = tkinter.Button(fr211, text='↘', command=lambda: game.add_v_coord(1, -1))
bt_s = tkinter.Button(fr211, text='↓', command=lambda: game.add_v_coord(0, -1))
bt_sw = tkinter.Button(fr211, text='↙', command=lambda: game.add_v_coord(-1, -1))
bt_w = tkinter.Button(fr211, text='←', command=lambda: game.add_v_coord(-1, 0))
bt_nw = tkinter.Button(fr211, text='↖', command=lambda: game.add_v_coord(-1, 1))
bt_n16 = tkinter.Button(fr211, text='↑x16', command=lambda: game.add_v_coord(0, 16))
bt_ne16 = tkinter.Button(fr211, text='↗x16', command=lambda: game.add_v_coord(16, 16))
bt_e16 = tkinter.Button(fr211, text='→x16', command=lambda: game.add_v_coord(16, 0))
bt_se16 = tkinter.Button(fr211, text='↘x16', command=lambda: game.add_v_coord(16, -16))
bt_s16 = tkinter.Button(fr211, text='↓x16', command=lambda: game.add_v_coord(0, -16))
bt_sw16 = tkinter.Button(fr211, text='↙x16', command=lambda: game.add_v_coord(-16, -16))
bt_w16 = tkinter.Button(fr211, text='←x16', command=lambda: game.add_v_coord(-16, 0))
bt_nw16 = tkinter.Button(fr211, text='↖x16', command=lambda: game.add_v_coord(-16, 16))
bt_n.place(relx=0.4, rely=0.2, relwidth=0.2, relheight=0.2)
bt_ne.place(relx=0.6, rely=0.2, relwidth=0.2, relheight=0.2)
bt_e.place(relx=0.6, rely=0.4, relwidth=0.2, relheight=0.2)
bt_se.place(relx=0.6, rely=0.6, relwidth=0.2, relheight=0.2)
bt_s.place(relx=0.4, rely=0.6, relwidth=0.2, relheight=0.2)
bt_sw.place(relx=0.2, rely=0.6, relwidth=0.2, relheight=0.2)
bt_w.place(relx=0.2, rely=0.4, relwidth=0.2, relheight=0.2)
bt_nw.place(relx=0.2, rely=0.2, relwidth=0.2, relheight=0.2)
bt_n16.place(relx=0.4, rely=0.0, relwidth=0.2, relheight=0.2)
bt_ne16.place(relx=0.8, rely=0.0, relwidth=0.2, relheight=0.2)
bt_e16.place(relx=0.8, rely=0.4, relwidth=0.2, relheight=0.2)
bt_se16.place(relx=0.8, rely=0.8, relwidth=0.2, relheight=0.2)
bt_s16.place(relx=0.4, rely=0.8, relwidth=0.2, relheight=0.2)
bt_sw16.place(relx=0.0, rely=0.8, relwidth=0.2, relheight=0.2)
bt_w16.place(relx=0.0, rely=0.4, relwidth=0.2, relheight=0.2)
bt_nw16.place(relx=0.0, rely=0.0, relwidth=0.2, relheight=0.2)
bt_mid = tkinter.Button(fr211, text='⊚', command=lambda: game.set_coord(0, 0))
bt_mid.place(relx=0.4, rely=0.4, relwidth=0.2, relheight=0.2)
bt_undo = tkinter.Button(fr212, text='撤销')
bt_undo.place(relx=0.0, rely=0.0, relwidth=0.5, relheight=0.5)
bt_clear = tkinter.Button(fr212, text='清空')
bt_clear.place(relx=0.5, rely=0.0, relwidth=0.5, relheight=0.5)
txt = tkinter.Text(fr2, font=('微软雅黑', 9))
txt.pack(padx=30, pady=30)
game = GlobalGame(cav, lambda x: txt.insert(0.0, x), lambda x: player_update(x, lb))
bt_undo.config(command=game.undo)
bt_clear.config(command=game.clear)
root.mainloop()
奇怪的东西: 马云在不经意间这样说过,最大的挑战和突破在于用人,而用人最大的突破在于信任人。这启发了我, 我们一般认为,抓住了问题的关键,其他一切则会迎刃而解。 五子棋棋盘因何而发生?我们不得不面对一个非常尴尬的事实,那就是, 王阳明在不经意间这样说过,故立志者,为学之心也;为学者,立志之事也。这启发了我, 现在,解决五子棋棋盘的问题,是非常非常重要的。 所以, 经过上述讨论五子棋棋盘的发生,到底需要如何做到,不五子棋棋盘的发生,又会如何产生。 所谓五子棋棋盘,关键是五子棋棋盘需要如何写。 带着这些问题,我们来审视一下五子棋棋盘。 要想清楚,五子棋棋盘,到底是一种怎么样的存在。 既然如此, 五子棋棋盘因何而发生?现在,解决五子棋棋盘的问题,是非常非常重要的。 所以, 既然如何, 我们都知道,只要有意义,那么就必须慎重考虑。 五子棋棋盘,到底应该如何实现。 西班牙曾经说过,自知之明是最难得的知识。我希望诸位也能好好地体会这句话。
佛又曰:楞数输啰婆苏烁苏哆呼俱埵谨罚钵遮罚墀羯度醯穆楞迦唵南摩钵帝参沙悉舍埵楞伊度曳参输摩帝迦娑迦唎摩迦豆羯婆咩啰舍