五子棋实现 学习

五子棋

五子棋简介

实现思路

程序分为两端。
首先一开始的一种思路就是一个服务器端,同时也是玩家的一位。另一端是客户端,连接上服务端即可。

界面实现

这里使用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

你可能感兴趣的:(五子棋)