Tkinter Tic Tac Toe 在某个盒子里画一个形状
Tkinter Tic Tac Toe Drawing a shape in a certain box
我是编程新手,正在努力学习 python 我决定为我的第一个项目制作井字游戏。我已经制作了绘制 X 和 O 的函数,但我无法在我单击的框中绘制它们。到目前为止,这是代码:
ttt = Tk()
ttt.title("Tic Tac Toe")
w = Canvas(ttt, width = 902, height = 902)
w.configure (bg = "white")
w.pack()
m = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
def drawx(event):
x, y = event.x, event.y
w.create_line(49, 49, 249, 249, fill = "black")
w.create_line(49, 249, 249, 49, fill = "black")
def drawo(event):
x2, y2 = event.x, event.y
x0 = x2 - 100
y0 = y2 - 100
x1 = x2 + 100
y1 = y2 + 100
return w.create_oval(x0, y0, x1, y1)
w.create_line(0, 300, 901, 300, fill = "black")
w.create_line(0, 601, 901, 601, fill = "black")
w.create_line(300, 0, 300, 901, fill = "black")
w.create_line(601, 0, 601, 901, fill = "black")
在这里,形状将根据我的光标坐标绘制,我知道应该修改它。如有任何帮助或建议,我们将不胜感激。
您可以 "discretize" x
和 y
值,方法是整数除法,然后乘以各个单元格的宽度(并为中心添加一些偏移量)。
def drawo(event):
x2, y2 = event.x, event.y
x2 = x2 // 300 * 300 + 150
y2 = y2 // 300 * 300 + 150
...
与 drawx
相同。
或者,您可以对网格中的不同单元格使用不同的 canvas 元素(或按钮、标签或类似元素),并从 event
中获得点击的 widget
。
为了向 tobias_k 的回答添加更多细节,下面的代码将在单击鼠标右键时绘制一个 X,在单击鼠标左键时绘制一个 O。
代码的改进可能是使用变量来定义 canvas 和每个 X/O 的大小,而不是硬编码 200 或 300。
from tkinter import *
ttt = Tk()
ttt.title("Tic Tac Toe")
w = Canvas(ttt, width = 902, height = 902)
w.configure (bg = "white")
w.pack()
m = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
def drawx(event):
print("drawx")
x, y = event.x, event.y
x0 = x // 300 * 300 + 50
y0 = y // 300 * 300 + 50
x1 = x0 + 200
y1 = y0 + 200
#return w.create_oval(x0, y0, x1, y1)
w.create_line(x0,y0,x1,y1, fill = "black")
w.create_line(x0,y0+200,x1,y1-200, fill = "black")
def drawo(event):
print("drawo")
x, y = event.x, event.y
x0 = x // 300 * 300 + 50
y0 = y // 300 * 300 + 50
x1 = x0 + 200
y1 = y0 + 200
return w.create_oval(x0, y0, x1, y1)
w.create_line(0, 300, 901, 300, fill = "black")
w.create_line(0, 601, 901, 601, fill = "black")
w.create_line(300, 0, 300, 901, fill = "black")
w.create_line(601, 0, 601, 901, fill = "black")
w.bind('<Button-1>',drawo)
w.bind('<Button-3>',drawx)
ttt.mainloop()
需要绑定鼠标点击事件canvas:
w.bind('<Button-1>', on_click)
然后确定在 on_click
处理程序中单击了哪个单元格:
SIZE = 300
player = 1 # 1 for O, 2 for X
def on_click(event):
global m
global player
row = event.y // SIZE
col = event.x // SIZE
# check whether the cell is not filled yet
if m[row][col] == 0:
# calculate the center of the cell
cx = col * SIZE + SIZE // 2
cy = row * SIZE + SIZE // 2
# draw X or O based on current player
if player == 1:
draw_O(cx, cy)
else:
draw_X(cx, cy)
# set cell is filled
m[row][col] = player
# now you need to check whether current player wins
...
# if no one wins, toggle player
player = 2 if player == 1 else 1
def draw_O(x, y):
radius = SIZE // 3
w.create_oval(x-radius, y-radius, x+radius, y+radius, width=5, tag='cell') # tag is used for resetting the game
def draw_X(x, y):
radius = SIZE // 3
w.create_line(x-radius, y-radius, x+radius, y+radius, width=5, tag='cell')
w.create_line(x+radius, y-radius, x-radius, y+radius, width=5, tag='cell')
如果您想重置游戏:
def reset_game():
global m
global player
# remove all 'O' and 'X'
w.delete('cell')
m = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
player = 1
为了更好的设计,将以上逻辑全部放在一个class中(继承自Canvas
)。然后你可以使用实例变量而不是全局变量。
我是编程新手,正在努力学习 python 我决定为我的第一个项目制作井字游戏。我已经制作了绘制 X 和 O 的函数,但我无法在我单击的框中绘制它们。到目前为止,这是代码:
ttt = Tk()
ttt.title("Tic Tac Toe")
w = Canvas(ttt, width = 902, height = 902)
w.configure (bg = "white")
w.pack()
m = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
def drawx(event):
x, y = event.x, event.y
w.create_line(49, 49, 249, 249, fill = "black")
w.create_line(49, 249, 249, 49, fill = "black")
def drawo(event):
x2, y2 = event.x, event.y
x0 = x2 - 100
y0 = y2 - 100
x1 = x2 + 100
y1 = y2 + 100
return w.create_oval(x0, y0, x1, y1)
w.create_line(0, 300, 901, 300, fill = "black")
w.create_line(0, 601, 901, 601, fill = "black")
w.create_line(300, 0, 300, 901, fill = "black")
w.create_line(601, 0, 601, 901, fill = "black")
在这里,形状将根据我的光标坐标绘制,我知道应该修改它。如有任何帮助或建议,我们将不胜感激。
您可以 "discretize" x
和 y
值,方法是整数除法,然后乘以各个单元格的宽度(并为中心添加一些偏移量)。
def drawo(event):
x2, y2 = event.x, event.y
x2 = x2 // 300 * 300 + 150
y2 = y2 // 300 * 300 + 150
...
与 drawx
相同。
或者,您可以对网格中的不同单元格使用不同的 canvas 元素(或按钮、标签或类似元素),并从 event
中获得点击的 widget
。
为了向 tobias_k 的回答添加更多细节,下面的代码将在单击鼠标右键时绘制一个 X,在单击鼠标左键时绘制一个 O。
代码的改进可能是使用变量来定义 canvas 和每个 X/O 的大小,而不是硬编码 200 或 300。
from tkinter import *
ttt = Tk()
ttt.title("Tic Tac Toe")
w = Canvas(ttt, width = 902, height = 902)
w.configure (bg = "white")
w.pack()
m = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
def drawx(event):
print("drawx")
x, y = event.x, event.y
x0 = x // 300 * 300 + 50
y0 = y // 300 * 300 + 50
x1 = x0 + 200
y1 = y0 + 200
#return w.create_oval(x0, y0, x1, y1)
w.create_line(x0,y0,x1,y1, fill = "black")
w.create_line(x0,y0+200,x1,y1-200, fill = "black")
def drawo(event):
print("drawo")
x, y = event.x, event.y
x0 = x // 300 * 300 + 50
y0 = y // 300 * 300 + 50
x1 = x0 + 200
y1 = y0 + 200
return w.create_oval(x0, y0, x1, y1)
w.create_line(0, 300, 901, 300, fill = "black")
w.create_line(0, 601, 901, 601, fill = "black")
w.create_line(300, 0, 300, 901, fill = "black")
w.create_line(601, 0, 601, 901, fill = "black")
w.bind('<Button-1>',drawo)
w.bind('<Button-3>',drawx)
ttt.mainloop()
需要绑定鼠标点击事件canvas:
w.bind('<Button-1>', on_click)
然后确定在 on_click
处理程序中单击了哪个单元格:
SIZE = 300
player = 1 # 1 for O, 2 for X
def on_click(event):
global m
global player
row = event.y // SIZE
col = event.x // SIZE
# check whether the cell is not filled yet
if m[row][col] == 0:
# calculate the center of the cell
cx = col * SIZE + SIZE // 2
cy = row * SIZE + SIZE // 2
# draw X or O based on current player
if player == 1:
draw_O(cx, cy)
else:
draw_X(cx, cy)
# set cell is filled
m[row][col] = player
# now you need to check whether current player wins
...
# if no one wins, toggle player
player = 2 if player == 1 else 1
def draw_O(x, y):
radius = SIZE // 3
w.create_oval(x-radius, y-radius, x+radius, y+radius, width=5, tag='cell') # tag is used for resetting the game
def draw_X(x, y):
radius = SIZE // 3
w.create_line(x-radius, y-radius, x+radius, y+radius, width=5, tag='cell')
w.create_line(x+radius, y-radius, x-radius, y+radius, width=5, tag='cell')
如果您想重置游戏:
def reset_game():
global m
global player
# remove all 'O' and 'X'
w.delete('cell')
m = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
player = 1
为了更好的设计,将以上逻辑全部放在一个class中(继承自Canvas
)。然后你可以使用实例变量而不是全局变量。