Python五子棋程序实现详解

news2025/1/17 23:25:41

Python五子棋程序实现详解

    • 引言
    • 功能实现
      • 显示棋盘
      • 点击落子
      • 判断胜负
      • 游戏结束判断
      • 交替落子
    • 运行结果
    • 完整代码
    • 总结

引言

五子棋是一种广泛传播的策略棋类游戏,两人对弈,通过在棋盘上落子,以先形成连续的相同颜色的五子棋为胜利条件。本文将介绍如何使用Python编写一个简单的五子棋程序,实现了五子棋游戏的基本功能。

功能实现

显示棋盘

首先,我们需要在程序中显示一个19x19的五子棋棋盘。使用tkinter库可以快速实现可视化界面的搭建。

# 定义常量
ROWS = 19
COLS = 19
PADDING = 30
GRID_SIZE = 20

# 创建棋盘
board = [[0] * COLS for _ in range(ROWS)]

# 创建窗口
window = tk.Tk()
window.title("五子棋")
window.geometry(str(COLS * GRID_SIZE + PADDING * 2) + "x" + str(ROWS * GRID_SIZE + PADDING * 2 + 40))

# 创建画布
canvas = tk.Canvas(window, width=COLS * GRID_SIZE + PADDING * 2, height=ROWS * GRID_SIZE + PADDING * 2, bg="burlywood")
canvas.place(x=0, y=PADDING)

# 绘制棋盘线
for i in range(ROWS):
    canvas.create_line(PADDING, i * GRID_SIZE + PADDING, COLS * GRID_SIZE + PADDING - GRID_SIZE, i * GRID_SIZE + PADDING)
for i in range(COLS):
    canvas.create_line(i * GRID_SIZE + PADDING, PADDING, i * GRID_SIZE + PADDING, ROWS * GRID_SIZE + PADDING - GRID_SIZE)

# 绘制黑点
for i in range(3, ROWS, 6):
    for j in range(3, COLS, 6):
        canvas.create_oval(j * GRID_SIZE + PADDING - 3, i * GRID_SIZE + PADDING - 3,
                           j * GRID_SIZE + PADDING + 3, i * GRID_SIZE + PADDING + 3, fill="black")

以上代码使用tkinter库创建了一个窗口,并在窗口内创建了一个棋盘。我们使用了Canvas组件来绘制棋盘上的线条和黑点。

点击落子

接下来,我们需要实现在棋盘上点击鼠标落子的功能。

def on_click(event):
    # 处理鼠标点击事件
    row = round((event.y - PADDING) / GRID_SIZE)
    col = round((event.x - PADDING) / GRID_SIZE)

    if row < 0 or row >= ROWS or col < 0 or col >= COLS:
        # 落子在棋盘外侧
        messagebox.showinfo("提示", "不可以落子在棋盘外哦!")
        return

    if not is_valid_move(row, col):
        # 提示落子位置已有棋子
        messagebox.showinfo("提示", "此处已有棋子,不可重复落子")
        return

    global current_player
    if current_player == 1:  # 蓝方玩家
        color = "blue"
        label.config(text="红方玩家的回合")
    else:  # 红方玩家
        color = "red"
        label.config(text="蓝方玩家的回合")

    board[row][col] = current_player
    x = col * GRID_SIZE + PADDING
    y = row * GRID_SIZE + PADDING
    canvas.create_oval(x - GRID_SIZE // 2, y - GRID_SIZE // 2, x + GRID_SIZE // 2, y + GRID_SIZE // 2, fill=color)

    if is_winner(current_player):
        if current_player == 1:
            messagebox.showinfo("游戏结束", "蓝方玩家获胜")
        else:
            messagebox.showinfo("游戏结束", "红方玩家获胜")
        window.quit()
    else:
        current_player = 2 if current_player == 1 else 1

# 绑定鼠标点击事件
canvas.bind("<Button-1>", on_click)  # 左键点击
canvas.bind("<Button-3>", on_click)  # 右键点击

以上代码定义了一个on_click函数来处理鼠标点击事件。函数首先根据点击的位置计算出对应的行列索引,然后检查是否落子在有效位置上。如果位置无效(落子在棋盘外侧或已有棋子),则弹出提示信息。如果位置有效,根据当前玩家的不同,设置棋子的颜色,并绘制出棋子。然后检查是否有玩家获得胜利,如果有,则弹出提示信息并退出游戏。如果没有胜利,切换当前玩家。

判断胜负

接下来,我们需要编写一个函数来判断当前是否有玩家已经胜利。

def is_winner(player):
    # 检查玩家是否胜利
    for row in range(ROWS):
        for col in range(COLS):
            if board[row][col] == player:
                # 检查水平方向
                if col + 4 < COLS and all(board[row][col + i] == player for i in range(5)):
                    return True
                # 检查垂直方向
                if row + 4 < ROWS and all(board[row + i][col] == player for i in range(5)):
                    return True
                # 检查对角线方向(左上到右下)
                if row + 4 < ROWS and col + 4 < COLS and all(board[row + i][col + i] == player for i in range(5)):
                    return True
                # 检查对角线方向(右上到左下)
                if row + 4 < ROWS and col - 4 >= 0 and all(board[row + i][col - i] == player for i in range(5)):
                    return True
    return False

以上代码定义了一个is_winner函数来判断指定玩家是否获胜。函数首先遍历棋盘上的每个位置,如果该位置的棋子颜色与指定玩家相同,则进行进一步检查。检查水平方向、垂直方向以及两个对角线方向上是否有连续的五个相同颜色的棋子,如果有,则返回True表示获胜,否则返回False表示未获胜。

游戏结束判断

on_click函数中,每当有玩家落子后,会检查是否有玩家获胜,如果有,则弹出提示信息并退出游戏。

交替落子

on_click函数中,每当有玩家落子后,会切换当前玩家。这通过全局变量current_player实现,初始值为1(蓝方玩家),当某一方落子后,将current_player的值切换为另一方(2表示红方玩家)。

运行结果

通过以上的代码实现,我们可以得到一个能够实现基本五子棋功能的程序。

程序运行时,会弹出一个窗口,窗口中显示了一个19x19的五子棋棋盘。玩家可以通过鼠标左键或右键点击棋盘上的格子进行落子。每当有玩家落子后,程序会自动判断是否有玩家获胜,并在弹出提示信息后结束游戏。

在程序运行过程中,程序会在窗口底部显示当前是哪一方玩家的回合,玩家可以根据该提示进行操作,避免出现误操作。同时,程序还会对一些错误的操作给出相应的提示,提高了游戏的友好度。

在这里插入图片描述

在这里插入图片描述

完整代码

import tkinter as tk
from tkinter import messagebox

# 定义常量
ROWS = 19
COLS = 19
PADDING = 30
GRID_SIZE = 20

# 创建棋盘
board = [[0] * COLS for _ in range(ROWS)]


def is_valid_move(row, col):
    # 检查落子是否有效
    return board[row][col] == 0


def is_winner(player):
    # 检查玩家是否胜利
    for row in range(ROWS):
        for col in range(COLS):
            if board[row][col] == player:
                # 检查水平方向
                if col + 4 < COLS and all(board[row][col + i] == player for i in range(5)):
                    return True
                # 检查垂直方向
                if row + 4 < ROWS and all(board[row + i][col] == player for i in range(5)):
                    return True
                # 检查对角线方向(左上到右下)
                if row + 4 < ROWS and col + 4 < COLS and all(board[row + i][col + i] == player for i in range(5)):
                    return True
                # 检查对角线方向(右上到左下)
                if row + 4 < ROWS and col - 4 >= 0 and all(board[row + i][col - i] == player for i in range(5)):
                    return True
    return False


def on_click(event):
    # 处理鼠标点击事件
    row = round((event.y - PADDING) / GRID_SIZE)
    col = round((event.x - PADDING) / GRID_SIZE)

    if row < 0 or row >= ROWS or col < 0 or col >= COLS:
        # 落子在棋盘外侧
        messagebox.showinfo("提示", "不可以落子在棋盘外哦!")
        return

    if not is_valid_move(row, col):
        # 提示落子位置已有棋子
        messagebox.showinfo("提示", "此处已有棋子,不可重复落子")
        return

    global current_player
    if current_player == 1:  # 蓝方玩家
        color = "blue"
        label.config(text="红方玩家的回合")
    else:  # 红方玩家
        color = "red"
        label.config(text="蓝方玩家的回合")

    board[row][col] = current_player
    x = col * GRID_SIZE + PADDING
    y = row * GRID_SIZE + PADDING
    canvas.create_oval(x - GRID_SIZE // 2, y - GRID_SIZE // 2, x + GRID_SIZE // 2, y + GRID_SIZE // 2, fill=color)

    if is_winner(current_player):
        if current_player == 1:
            messagebox.showinfo("游戏结束", "蓝方玩家获胜")
        else:
            messagebox.showinfo("游戏结束", "红方玩家获胜")
        window.quit()
    else:
        current_player = 2 if current_player == 1 else 1


# 创建窗口
window = tk.Tk()
window.title("五子棋")
window.geometry(str(COLS * GRID_SIZE + PADDING * 2) + "x" + str(ROWS * GRID_SIZE + PADDING * 2 + 40))

# 创建画布
canvas = tk.Canvas(window, width=COLS * GRID_SIZE + PADDING * 2, height=ROWS * GRID_SIZE + PADDING * 2, bg="burlywood")
canvas.place(x=0, y=PADDING)

# 绘制棋盘线
for i in range(ROWS):
    canvas.create_line(PADDING, i * GRID_SIZE + PADDING, COLS * GRID_SIZE + PADDING - GRID_SIZE, i * GRID_SIZE + PADDING)
for i in range(COLS):
    canvas.create_line(i * GRID_SIZE + PADDING, PADDING, i * GRID_SIZE + PADDING, ROWS * GRID_SIZE + PADDING - GRID_SIZE)


# 绘制黑点
for i in range(3, ROWS, 6):
    for j in range(3, COLS, 6):
        canvas.create_oval(j * GRID_SIZE + PADDING - 3, i * GRID_SIZE + PADDING - 3,
                           j * GRID_SIZE + PADDING + 3, i * GRID_SIZE + PADDING + 3, fill="black")

# 绑定鼠标点击事件
canvas.bind("<Button-1>", on_click)  # 左键点击
canvas.bind("<Button-3>", on_click)  # 右键点击

# 创建游戏信息标签
label = tk.Label(window, text="蓝方玩家的回合", font=("宋体", 14))
label.place(x=PADDING, y=PADDING * 2 + ROWS * GRID_SIZE + 10)

# 初始化当前玩家为蓝方玩家
current_player = 1

# 运行窗口的主循环
window.mainloop()

总结

本文通过使用Python编写了一个简单的五子棋程序,实现了五子棋游戏的基本功能。通过tkinter库创建了一个可视化界面,实现了显示棋盘和点击落子的功能。通过编写相应的函数实现了胜负判断和游戏结束判断的功能。整个游戏流程简洁明了,代码结构清晰。通过本文的学习,相信读者们已经掌握了使用Python编写简单游戏的基本方法。希望本文的内容对读者们有所帮助,谢谢阅读!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1340348.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于Zoom ZTP和AudioCodes Ltd桌面电话缺陷暴露,导致用户遭受窃听的动态情报

一、基本内容 近期SySS安全研究员发布分析报告显示&#xff0c;Zoom的零接触&#xff08;ZTP&#xff09;和AudioCodes Ltd桌面电话配置功能中发现高危漏洞&#xff0c;可以获得对设备的完全远程控制并不受限制的访问可以被武器化&#xff0c;以窃听房间或电话、通过设备并攻击…

JAVA语言—AOP基础

1、AOP概述 AOP&#xff1a;AOP&#xff08;Aspect Oriented Programming&#xff09;&#xff0c;即面向切面编程&#xff0c;可以说是OOP&#xff08;Object Oriented Programming&#xff0c;面向对象编程&#xff09;的补充和完善。 场景&#xff1a;案例部分功能运行较慢&…

Linux操作系统——进程(六) 进程地址空间

进程地址空间 C/C程序员一般将我们所写的程序看成如下这种结构&#xff1a; 我们所写的程序通过编译编译之后就可以以这样的方式进行分布. 我们先通过编写一段C语言代码来进行验证&#xff1a; 运行结果&#xff1a; 我们可以看出来上述地址遵循的就是我们上面画的一种结构。…

TSINGSEE青犀智能分析网关V4人体行为检测算法在视频监控中的应用

旭帆科技智能分析网关的算法十分繁多&#xff0c;其中可分为人体事件、车辆事件、环境事件、行为检测、着装检测等等&#xff0c;可覆盖绝大多数场景&#xff0c;如智慧校园、智慧工地、智慧景区等&#xff0c;今天小编就TSINGSEE青犀智能分析网关的行为检测算法和大家进行研讨…

Leetcode算法系列| 8. 字符串转换整数 (atoi)

目录 1.题目2.题解C# 解法一&#xff1a;及其臃肿的代码C# 解法二&#xff1a;DFA&#xff08;确定有穷自动机&#xff09; 1.题目 请你来实现一个 myAtoi(string s) 函数&#xff0c;使其能将字符串转换成一个 32 位有符号整数&#xff08;类似 C/C 中的 atoi 函数&#xff09…

2024年中职“网络安全“—数字调查取证(attack817.pcapng)

目录 ​1.通过分析数据包找出恶意用户最初访问HTTP服务的包号&#xff0c;将该值作为Flag值提交, Flag格式为flag{xxx}&#xff1b; 2.继续查看数据包文件分析出恶意用户扫描了哪些端口&#xff0c;将全部的端口号按照一定顺序作为Flag值&#xff0c;提示&#xff1a;注意端口…

Spring Boot整合 EasyExcel 实现复杂 Excel 表格的导入与导出功能

文章目录 1. 简介2. 引入依赖3. 导入功能实现3.1 创建实体类3.2 编写导入 Controller3.3 编写导入页面 4. 导出功能实现4.1 编写导出 Controller4.2 编写导出页面 5. 启动应用 &#x1f388;个人主页&#xff1a;程序员 小侯 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &…

2023年中职“网络安全”——B-5:网络安全事件响应(Server2216)

B-5&#xff1a;网络安全事件响应 任务环境说明&#xff1a; 服务器场景&#xff1a;Server2216&#xff08;开放链接&#xff09; 用户名:root密码&#xff1a;123456 1、黑客通过网络攻入本地服务器&#xff0c;通过特殊手段在系统中建立了多个异常进程&#xff0c;找出启…

NFC物联网智能锁安全测试研究

针对短距离无线通信在物联网智能锁实际运用中的安全机制问题&#xff0c;通过理论分析和实际操作演示潜在的攻击流程&#xff0c;发现其存在的安全漏洞并提出可行的加固方法&#xff0c;并对加固后的通信系统进行CPN建模与安全性分析&#xff0c;对无线通信协议的安全性能提升、…

数据结构学习 Leetcode474 一和零

关键词&#xff1a;动态规划 01背包 一个套路&#xff1a; 01背包&#xff1a;空间优化之后dp【target1】&#xff0c;遍历的时候要逆序遍历完全背包&#xff1a;空间优化之后dp【target1】&#xff0c;遍历的时候要正序遍历 目录 题目&#xff1a; 思路&#xff1a; 复杂…

算法时间空间复杂度计算—空间复杂度

算法时间空间复杂度计算—空间复杂度 空间复杂度定义影响空间复杂度的因素算法在运行过程中临时占用的存储空间讲解 计算方法例子1、空间算法的常数阶2、空间算法的线性阶&#xff08;递归算法&#xff09;3、二分查找分析方法一&#xff08;迭代法&#xff09;方法二&#xff…

lenovo联想拯救者8.8英寸掌上游戏机Legion Go 8APU1(83E1)原装出厂Windows11预装系统

链接&#xff1a;https://pan.baidu.com/s/1d586XWXcAWVxlLyV2Oku7Q?pwdd74t 提取码&#xff1a;d74t 系统自带所有驱动、出厂主题壁纸、Office办公软件、联想电脑管家等预装程序 所需要工具&#xff1a;16G或以上的U盘 文件格式&#xff1a;ISO 文件大小&#xff1a;…

iframe展示pdf、png、jpg

iframe展示pdf、png、jpg&#xff1a; 1、前端定义div&#xff1a; <div id"pdf-container"></div>/*dpf的div*/ <iframe id"imageFrame"></iframe>/*图片的div*/2、后端查询base64的流&#xff0c;前端页面初始化js方法&#x…

100V降压芯片H6603 外围简洁无过冲 12V 24V 36V 48V 60V 转5V 3.3V

H6603是一款优秀的降压恒压电源芯片&#xff0c;具有外围元器件少、电路简单、效率高、发热量低等特点。 H6603 是一款内置功率 MOSFET降压开关转换器。在宽输入范围内&#xff0c;其峰值输出电流可达到 0.8A&#xff0c;具有极好的负载和线性调整率。 电流控制模式提供了快速瞬…

uniapp 输入手机号并且正则校验

1.<input input“onInput” :value“phoneNum” type“number” maxlength“11”/> 3. method里面写 onInput(e){ this.phoneNum e.detail.value }, 4.调用接口时候校验正则 if (!/^1[3456789]\d{9}$/.test(this.phoneNum)) {uni.showToast({title: 请输入正确的手机号…

硅像素传感器文献调研(二)

写在前面&#xff1a;从上篇文章的参考文献中看到一篇文献&#xff0c;现在也精读一下&#xff0c;今天还有一个任务是把上篇文献整体脉络用流程图的形式完整梳理一下。 哈哈哈哈哈哈&#xff1a;代表没太搞明白的部分 如何写论文&#xff1a; 引言部分&#xff1a;基础理论…

收藏!光伏发电量计算最全公式整理

随着可再生能源的日益普及&#xff0c;光伏发电已经成为一种重要的清洁能源。了解光伏发电量的计算方法对于投资者、工程师和研究者来说都是非常重要的。本文将为您整理光伏发电量计算的最全公式&#xff0c;帮助您更好地理解和评估光伏系统的性能。 1、光伏电池板转换效率 光…

UI自动化Selenium 元素定位之Xpath

一、元素定位方式 selenium中定位元素&#xff0c;通常有几种方式&#xff1a; 1、通过id定位&#xff1a;By.ID 2、通过Name定位&#xff1a;By.Name 3、通过元素其他属性定位&#xff0c;如class、type、text文本。。。。。。等等&#xff0c;如果要用属性定位那就需要使…

tecplot导入多个.dat文件,并激活solution time

在对流场数据进行提取的时候&#xff0c;需要提取不同时刻的某一点流场值&#xff0c;这时候导入多个.dat文件时&#xff0c;就需要激活solution time! 该怎么做讷&#xff1f; 具体请参考我提供的python文件&#xff0c;需要的可以找我要&#xff0c;我就不放在CSDN上让大家…

【K8S 二进制部署】部署单Master Kurbernetes集群

目录 一、基本架构和系统初始化 1、集群架构&#xff1a; 2、操作系统初始化配置&#xff1a; 2.1、关闭防火墙和安全机制&#xff1a; 2.2、关闭swap 2.3、根据规划设置主机名 2.4、三台主机全部互相映射 2.5、调整内核参数 3、时间同步&#xff08;所有节点时间必须同…