【Python】Tkinter制作简单五子棋小游戏

目录

  • 一、效果预览
  • 二、预处理
  • 三、__init__()函数
  • 四、自定义函数
    • 1. def start()
    • 2. def callback1() / def callback2()
    • 3. def rand()
    • 4. def check_win()
    • 5. def is_repeat()
    • 6. def destroy_buttons()
    • 7. def is_continue_game()
    • 8. def regret_chess()
  • 五、主要功能的具体实现
    • 1.先后手判定
    • 2.悔棋
    • 3.自动落白子
    • 4.防止自动生成的白子将原来的黑子覆盖
    • 5.判断重复落子
    • 6.销毁按钮
  • 整体代码
  • 图片素材


一、效果预览

  • 主页面【Python】Tkinter制作简单五子棋小游戏_第1张图片
  • 游戏页面

二、预处理

  • 导入模块
import itertools
from tkinter.messagebox import *
from tkinter import *
import random
  • 函数声明
    在本程序中使用了几个自定义的函数,这些函数的功能及声明形式代码如下:
自定义函数 功能
def start(self, event) 初始化游戏页面
def callback1(self, event) 双人模式控制黑棋
def callback2(self, event) 双人模式控制白棋
def rand(self, event) 单人模式控制黑棋
def check_win(self, x, y) 判断胜负
def is_repeat(self, x, y) 判断棋子是否重复
def destroy_buttons(self) 销毁按钮,防止误触从而重新进入游戏界面
def is_continue_game(self, event) 游戏结束后,判断用户是否继续游戏还是结束游戏
def regret_chess(self, event) 悔棋

三、init()函数

在程序中,可以把一局游戏看作一个class,每个环节是它的一个函数,而__init__()的函数总是在class被初始化时执行
它的主要功能是:传递参数,比如赋值给对象属性

功能:

  • 为游戏创建了一个基于Tkinter的GUI窗口
  • 添加了三个按钮用于选择游戏模式和退出游戏
  • 由于进入游戏后防止误触以及不美观等因素,需要创建一个列表来保存按钮的引用,以便销毁双人模式和单人模式

实现代码及注释如下:

	
    def __init__(self):
        self.root = Tk()  # 创建窗口
        self.root.geometry("1000x1000")  # 窗口大小

        self.r = Canvas(self.root, width=1000, height=1000)  # 创建画布
        self.r.pack(pady=20)  # 画布位置
        self.pic = PhotoImage(file='D:\\code\\2024\\Python\\python\\task\\Gomoku_game\\data\\Gomoku_main_page.png')
        self.r.create_image(500, 450, image=self.pic)  # 图片位置

        # 创建一个退出游戏的按钮,以便退出游戏
        self.b1 = Button(self.root, text="退出游戏", width=8, font=("楷体", 13), command=self.root.destroy)   
        self.b1.pack()  # 显示
        self.b1.place(x=870, y=950)     # 位置

        self.buttons = []  # 创建一个列表来保存按钮的引用,以便销毁
        s = ["双人", "单人"]
        for i in range(len(s)):
            self.b = Button(self.root, text=s[i], width=10, font=("楷体", 17))  # 添加按钮
            self.b.bind('', self.start)  # 绑定self.start方法
            self.b.place(x=(i + 1) * 300, y=950)  # 按钮位置
            self.buttons.append(self.b)  # 将按钮引用添加到列表中

        self.root.mainloop()  # 运行窗口

四、自定义函数

1. def start()

功能:

  • 销毁以前的画布,并新建一个画布绘制棋盘和交叉点,初始化棋盘
  • 创建悔棋按钮,并绑定到regret_chess方法
  • 根据被点击的模式选择按钮,将画布上的鼠标点击事件绑定到不同的方法。
  • 随后销毁选择模式的按钮
    def start(self, event):
        self.r.destroy()  # 销毁上面的画布,为了进入游戏

        self.c = Canvas(self.root, width=1000, height=930)  # 创建新的画布
        self.c.pack()
        self.c.place(x=0, y=0)  # 防止用户重复点击造成画布位置移动
        self.pic = PhotoImage(file='D:\\code\\2024\\Python\\python\\task\\Gomoku_game\\data\\Gomoku_background.png')
        self.c.create_image(400, 340, image=self.pic)  # 图片位置

        self.r_chess = Button(self.root, text="悔棋", width=8, font=("楷体", 17))  # 放置悔棋按钮
        self.r_chess.bind('', self.regret_chess)   #绑定一个方法
        self.r_chess.pack()
        self.r_chess.place(x=447, y=940)

        # 绘制棋盘网格
        for i in range(1, 16):  # 绘制棋盘的水平和垂直线
            self.c.create_line(60, 60 * i, 900, 60 * i)
            self.c.create_line(60 * i, 60, 60 * i, 900)

        # 绘制棋盘的交叉点
        for i in range(60, 901, 60):
            for j in range(60, 901, 60):
                self.c.create_oval(i - 2, j - 2, i + 2, j + 2, fill="black")  # 在棋盘的每个交叉点上绘制一个小的蓝色圆形

        self.matrix = [[0 for y in range(16)] for x in range(16)]  # 初始化矩阵的每个位置为0,用于存储棋盘的状态
                                                                   # 实际上棋子是落在前14x14,为防止白子的自动生成造成越界访问将其初始化为16x16

        # isinstance()方法:检查了widget是否真的是一个Button实例
        if isinstance(event.widget, Button) and (event.widget["text"]) == "双人":
            self.c.bind("", self.callback1)  # 如果点击双人使用左键,调用callback1
            self.c.bind("", self.callback2)  # 如果点击双人使用右键,调用callback2
        elif isinstance(event.widget, Button) and (event.widget["text"]) == "单人":
            self.c.bind("", self.rand)  # 如果左键点击单人,调用rand

        self.destroy_buttons()	# 点击之后进入游戏,因此需要销毁按钮

2. def callback1() / def callback2()

功能:

  • 使用 try...except 块来捕捉可能出现的异常,确保程序不会因为意外情况而崩溃
  • 全局变量 temp:使用 global temp 声明全局变量,用于跟踪当前是黑方还是白方的回合(callback1为黑方,callback2为白方)
  • 判断当前位置是否有棋子,若无,则在棋盘上放置一个黑子,更新矩阵并在画布上绘制一个黑子
  • 判断是否有玩家获胜
  • 如果用户点击了棋盘以外的地方,提示用户
    def callback1(self, event):
        try:    # 捕捉异常防止崩溃
            global temp     #声明全局变量
            if temp % 2 == 0:   #为偶数
                u, v = event.x, event.y  # 获取鼠标点击的位置:从event中提取鼠标的x和y坐标,并分别赋值给u和v
                temp += 1
            else:
                showinfo("ERROR", "现在是白方回合!")

            # 确定鼠标点击的棋盘格子
            for i in range(1, 16):  # 用于确定x坐标(即u)对应的棋盘列索引zx
                if 30 * i < u < 30 * (2 * i + 1):
                    zx = i - 1
                    break
            for i in ra

你可能感兴趣的:(python,开发语言)