程序分为两端。
首先一开始的一种思路就是一个服务器端,同时也是玩家的一位。另一端是客户端,连接上服务端即可。
这里使用Python的tkinter来实现,是tk提供给Python使用的一套内置GUI接口。
self.num = 18 # 棋盘网格数量
self.K = 0.9 # 点击的灵敏度 0~1 之间
self.Qr = 7 # 棋子的大小,前面的系数在0~0.5之间选取
self.px = 5
self.py = 50
self.wide = 60
self.high = 30
self.mesh = round(400 / self.num)
self.key = ["黑方", "白方"]
self.color = ["black", "white"]
# 初始化棋盘
self.QP = []
for i in range(self.num):
self.QP.append([-1] * self.num)
tk = Tk()
# 设置大小和位置。
tk.geometry(str((self.num + 1) * self.mesh + 2 * self.px) + 'x' + str((self.num + 1) * self.mesh + self.py + self.px))
tk.title('五子棋')
# 构造棋盘界面
# 设置Canvas帆布大小位置。
self.asdf = Canvas(tk, width=(self.num + 1) * self.mesh + 2 * self.px, height=(self.num + 1) * self.mesh + self.py + self.px)
self.asdf.place(x=0, y=0)
self.asdf.create_rectangle(0, 0, (self.num + 1) * self.mesh + 2 * self.px, (self.num + 1) * self.mesh + self.py + self.px, fill="#d7a605")
self.canvas = Canvas(tk, width=str((self.num + 1) * self.mesh), height=str((self.num + 1) * self.mesh))
self.canvas.place(x=self.px, y=self.py)
self.canvas.create_rectangle(self.mesh - 20, self.mesh - 20, self.mesh * self.num + 20, self.mesh * self.num + 20, fill="#d7a65b")
for i in range(self.num):
self.canvas.create_line(self.mesh, self.mesh * (i + 1), self.mesh * self.num, self.mesh * (i + 1))
self.canvas.create_line(self.mesh * (i + 1), self.mesh, self.mesh * (i + 1), self.mesh * self.num)
self.canvas.bind("" , self.callback)
# 中间的文字
self.a = Label(tk, text=self.key[self.tag], fg=self.color[self.tag], bg='green', font=("Times", "14", "bold"))
self.b = Label(tk, text="走棋", fg=self.color[self.tag], bg='green', font=("Times", "14", "bold"))
self.a.place(x=2 * self.px + 60 + 10 + 90, y=(self.py - self.high) / 2 + 4)
self.b.place(x=(self.num + 1) * self.mesh + self.px - self.wide - self.px - 10 - 42 - 90, y=(self.py - self.high) / 2 + 4)
t1 = threading.Thread(target=self.acceptMessage, args=(self.server,self.x,self.y,self))
t1.start()
tk.mainloop()
就是先创建一个TK窗口,然后创建一个小矩形框,写上一些标题描述,然后下面一个矩形框内,通过画行列直线完成一个棋盘。
点击的时候,发送消息以及相关处理:
def callback(self,event):
if self.te:
data = str(event.x)+":"+str(event.y)
self.sock.send(data.encode("utf-8"))
color = ["white", "white"]
x = round(event.x / self.mesh) - 1
y = round(event.y / self.mesh) - 1
errorX = self.mesh * (x + 1) - event.x
errorY = self.mesh * (y + 1) - event.y
dis = (errorX ** 2 + errorY ** 2) ** 0.5
if self.QP[x][y] == -1 and dis < self.K / 2 * self.mesh and self.stop == 0:
self.a.config(text=self.key[(self.tag + 1) % 2], fg=color[(self.tag + 1) % 2])
self.QP[x][y] = self.tag
self.canvas.create_oval(self.mesh * (x + 1) - self.Qr, self.mesh * (y + 1) - self.Qr, self.mesh * (x + 1) + self.Qr, self.mesh * (y + 1) + self.Qr,
fill=color[self.tag])
v = [[0, 1], [1, 0], [1, 1], [1, -1]]
for i in v:
x1, y1 = x, y
while x1 < self.num - 1 and x1 > 0 and y1 > 0 and y1 < self.num - 1:
x1 += i[0]
y1 += i[1]
count = 0
while x1 <= self.num - 1 and x1 >= 0 and y1 >= 0 and y1 <= self.num - 1:
if self.QP[x1][y1] == self.tag:
count += 1
if count == 5:
self.win()
else:
count = 0
x1 -= i[0]
y1 -= i[1]
self.tag = (self.tag + 1) % 2
self.tagx, self.tagy = x, y
self.te = 0
开启一个线程,用来接收消息:接收收到的x,y信息,为下棋的位置。
def acceptMessage(self,server, x, y, theSystem):
sock, addr = server.accept()
theSystem.sock = sock
while True:
x, y = sock.recv(1024).decode("gbk").split(":")
eventx = int(x)
eventy = int(y)
self.callbackServer(eventx, eventy)
接收到消息后,调用相应的服务器回调函数:
def callbackServer(self,eventx,eventy):
#global tag, tagx, tagy, a
color = ["black", "black"]
x = round(eventx / self.mesh) - 1
y = round(eventy / self.mesh) - 1
errorX = self.mesh * (x + 1) - eventx
errorY = self.mesh * (y + 1) - eventy
dis = (errorX ** 2 + errorY ** 2) ** 0.5
if self.QP[x][y] == -1 and dis < self.K / 2 * self.mesh and self.stop == 0:
self.a.config(text=self.key[(self.tag + 1) % 2], fg=color[(self.tag + 1) % 2])
self.QP[x][y] = self.tag
self.canvas.create_oval(self.mesh * (x + 1) - self.Qr, self.mesh * (y + 1) - self.Qr, self.mesh * (x + 1) + self.Qr, self.mesh * (y + 1) + self.Qr,
fill=color[self.tag])
v = [[0, 1], [1, 0], [1, 1], [1, -1]]
for i in v:
x1, y1 = x, y
while x1 < self.num - 1 and x1 > 0 and y1 > 0 and y1 < self.num - 1:
x1 += i[0]
y1 += i[1]
count = 0
while x1 <= self.num - 1 and x1 >= 0 and y1 >= 0 and y1 <= self.num - 1:
if self.QP[x1][y1] == self.tag:
count += 1
if count == 5:
self.win()
else:
count = 0
x1 -= i[0]
y1 -= i[1]
self.tag = (self.tag + 1) % 2
self.tagx, self.tagy = x, y
self.te = 1
如棋盘大小,棋子大小、棋盘行列数,行动方、行动方行动了没有。
然后设置一个棋子变量,用0,-1,1表示三种状态。
通过tcp来发消息。
然后每次下完后,判断一下4个方向是否胜利即可。
github:gobang-LAN-Python