python 五子棋小游戏

1. 实现效果

Python五子棋小游戏


2. 游戏规则

规则说明,五子棋人机对战游戏规则如下:‌

Ⅰ 默认规则 - 五子棋规则

  • 对局双方‌:各执一色棋子,一方持黑色棋子,另一方持白色棋子。
  • 棋盘与开局‌:空棋盘开局,黑先、白后,交替下子,每次只能下一子。
  • 棋子落点‌:棋子下在棋盘的空白点上,下定后不得向其它点移动,也不得从棋盘上拿掉或拿起另落别处。
  • 黑方首子‌:黑方的第一枚棋子可下在棋盘任意交叉点上。
  • 轮流下子‌:轮流下子是双方的权利。

Ⅱ 设定规则

  • 双方(用户与程序)分别使用黑白两色的棋子,设定为玩家执黑,先下第一颗,程序执白。
  • 棋盘设为常规的15道盘,即15×15的方格。
  • 下在棋盘直线与横线的交叉点上,先形成五子连珠者获胜。

Ⅲ 其他规则

  • 高亮规则:动态高亮显示最新落子,便于观察程序上一步落在何处。
  • 防守机制:检查对方是否可以形成三子或四子
  • 获胜后不要退出窗口,而是停留,不然不知道怎么输的😂
  • 细节:1. 棋盘格外围边框加粗且为深色,棋盘格框线变细,高亮框线变细 2.一旦有一方赢就无法再落子了(主要是白子会在黑子赢了之后还落子) 3. 判平局 4. 棋子下在格线交叉点,而非格内。

3. 环境配置

程序中会用到的库:

import sys
import random
import pygame

其中sys库和random是python的内置库,不需要安装,pygame是三方库,需要安装。
先安装 pygame,如果还没有安装,可以使用以下命令:

pip install pygame

4. 代码实现

变量说明

# 常量定义
BOARD_SIZE = 15 					# 棋盘是15×15
CELL_SIZE = 40 						# 每个棋格的大小
WIDTH = BOARD_SIZE * CELL_SIZE		# 棋盘的大小 宽 = 15×40
HEIGHT = BOARD_SIZE * CELL_SIZE 	# 棋盘高度
BACKGROUND_COLOR = (250, 224, 161)  # 棋盘的背景色
GRID_COLOR = (0, 0, 0)				# 棋盘格线 调成(200, 200, 200)会很好看
HIGHLIGHT_COLOR = (255, 182, 193) 	# 高亮颜色, 粉色
BORDER_COLOR = (139, 69, 19)  		# 棋盘外围边框颜色# 棋盘状态
EMPTY = 0 # 未落子
BLACK = 1 # 落黑子
WHITE = 2 # 落白子

棋盘绘制

画棋盘、棋格、棋子、高亮框框、高亮圈圈

def draw_board(screen, board, last_move):screen.fill(BACKGROUND_COLOR)for x in range(BOARD_SIZE):for y in range(BOARD_SIZE):rect = pygame.Rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE)pygame.draw.rect(screen, GRID_COLOR, rect, 1)if board[x][y] == BLACK:pygame.draw.circle(screen, (0, 0, 0), rect.center, CELL_SIZE // 2 - 5)elif board[x][y] == WHITE:pygame.draw.circle(screen, (255, 255, 255), rect.center, CELL_SIZE // 2 - 5)if last_move:# row, col = latest_move# 方形高亮 棋格highlight_rect = pygame.Rect(last_move[0] * CELL_SIZE, last_move[1] * CELL_SIZE, CELL_SIZE, CELL_SIZE)pygame.draw.rect(screen, HIGHLIGHT_COLOR, highlight_rect, 2)# 圆形高亮 棋子highlight_center = (last_move[0] * CELL_SIZE + CELL_SIZE // 2, last_move[1] * CELL_SIZE + CELL_SIZE // 2)highlight_radius = CELL_SIZE // 2 - 5  # 与棋子相同的半径pygame.draw.circle(screen, HIGHLIGHT_COLOR, highlight_center, highlight_radius+1.5, 2)  # 用圆形高亮, 1.5是为了补偿高亮,高亮是2pygame.draw.rect(screen, BORDER_COLOR, (0, 0, CELL_SIZE * BOARD_SIZE, CELL_SIZE * BOARD_SIZE), 5)# 绘制边框

判断赢家

在任意方达到五子的时候,判断赢了

def check_winner(board, player):for x in range(BOARD_SIZE):for y in range(BOARD_SIZE):if board[x][y] == player:# 检查水平方向if x + 4 < BOARD_SIZE and all(board[x + i][y] == player for i in range(5)):return True# 检查垂直方向if y + 4 < BOARD_SIZE and all(board[x][y + i] == player for i in range(5)):return True# 检查斜向(左上到右下)if x + 4 < BOARD_SIZE and y + 4 < BOARD_SIZE and all(board[x + i][y + i] == player for i in range(5)):return True# 检查斜向(右上到左下)if x - 4 >= 0 and y + 4 < BOARD_SIZE and all(board[x - i][y + i] == player for i in range(5)):return Truereturn False

程序落子(随机)

一开始纯随机,棋子分布散乱,很容易白子就输了,没有难度和趣味性。后来程序才加策略,提高白子获胜率。

def get_random_move(board):empty_cells = [(x, y) for x in range(BOARD_SIZE) for y in range(BOARD_SIZE) if board[x][y] == EMPTY]return random.choice(empty_cells) if empty_cells else None

防御机制

程序检测玩家连续棋子的数量是否对自身存在威胁性。

def check_threats(board, player):three_in_a_row_positions = []for x in range(BOARD_SIZE):for y in range(BOARD_SIZE):if board[x][y] == EMPTY:board[x][y] = player  # 模拟落子if check_winner(board, player):board[x][y] = EMPTYreturn [(x, y)]  # 直接获胜# 检测是否出现三子的情况if count_consecutive(board, x, y, player) == 3:three_in_a_row_positions.append((x, y))board[x][y] = EMPTYreturn three_in_a_row_positionsdef get_defensive_move(board):# 检查对方是否可以形成三子或四子for position in check_threats(board, BLACK):return position  # 返回防守位置return Nonedef count_consecutive(board, x, y, player):# 检查周围的棋子数量count = 0for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1), (-1, -1), (1, 1), (-1, 1), (1, -1)]:temp_count = 0for step in range(1, 5):  # 只检测四个方向nx, ny = x + dx * step, y + dy * stepif 0 <= nx < BOARD_SIZE and 0 <= ny < BOARD_SIZE and board[nx][ny] == player:temp_count += 1else:breakcount += temp_countreturn count

追踪策略

为了便于堵截玩家,提高难度。

def get_preferred_move(board):preferred_moves = []for x in range(BOARD_SIZE):for y in range(BOARD_SIZE):if board[x][y] == EMPTY:# 优先选择靠近黑子的位置for dx in [-1, 0, 1]:for dy in [-1, 0, 1]:nx, ny = x + dx, y + dyif 0 <= nx < BOARD_SIZE and 0 <= ny < BOARD_SIZE and board[nx][ny] == BLACK:preferred_moves.append((x, y))breakreturn random.choice(preferred_moves) if preferred_moves else get_random_move(board)

主函数

def main():pygame.init()screen = pygame.display.set_mode((WIDTH, HEIGHT))pygame.display.set_caption("五子棋")game_over = False  # 游戏是否结束board = [[EMPTY for _ in range(BOARD_SIZE)] for _ in range(BOARD_SIZE)]last_move = Nonewhile True:for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()sys.exit()if game_over:continue  # 如果游戏结束,不处理任何落子# 检查是否平局if all(board[x][y] != EMPTY for x in range(BOARD_SIZE) for y in range(BOARD_SIZE)):game_over = Trueprint("游戏平局!")if event.type == pygame.MOUSEBUTTONDOWN:x, y = event.posx //= CELL_SIZEy //= CELL_SIZEif 0 <= x < BOARD_SIZE and 0 <= y < BOARD_SIZE and board[x][y] == EMPTY:board[x][y] = BLACKlast_move = (x, y)if check_winner(board, BLACK):game_over = Trueprint("黑方获胜!")#pygame.quit()#sys.exit()# 白方落子if not game_over and not (all(board[x][y] != EMPTY for x in range(BOARD_SIZE) for y in range(BOARD_SIZE))):move = get_defensive_move(board)if move is None:  # 若没有可防守的位置,落子move = get_preferred_move(board)board[move[0]][move[1]] = WHITElast_move = moveif check_winner(board, WHITE):game_over = Trueprint("白方获胜!")# pygame.quit()# sys.exit()draw_board(screen, board, last_move)pygame.display.flip()pygame.quit()

完整代码

import pygame
import sys
import random# 常量定义
BOARD_SIZE = 15
CELL_SIZE = 40
WIDTH = BOARD_SIZE * CELL_SIZE
HEIGHT = BOARD_SIZE * CELL_SIZE
BACKGROUND_COLOR = (250, 224, 161)
GRID_COLOR = (245, 245, 220) #GRID_COLOR = (0, 0, 0)
FADED_GRID_COLOR = (200, 200, 200)  #  使用一个更亮的颜色来模仿淡化效果 淡化的格线颜色 (220, 220, 220)
HIGHLIGHT_COLOR = (255, 182, 193) # 粉色高亮颜色
BORDER_COLOR = (139, 69, 19)  # 边框颜色
# 棋盘状态
EMPTY = 0
BLACK = 1
WHITE = 2def draw_board(screen, board, last_move):screen.fill(BACKGROUND_COLOR)for x in range(BOARD_SIZE):for y in range(BOARD_SIZE):rect = pygame.Rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE)pygame.draw.rect(screen, GRID_COLOR, rect, 1)# 在每个格子内绘制2份纵横线for i in range(1, 2):# 横线pygame.draw.line(screen, FADED_GRID_COLOR, (x * CELL_SIZE, y * CELL_SIZE + i * (CELL_SIZE // 2)),(x * CELL_SIZE + CELL_SIZE, y * CELL_SIZE + i * (CELL_SIZE // 2)), 1)# 竖线pygame.draw.line(screen, FADED_GRID_COLOR, (x * CELL_SIZE + i * (CELL_SIZE // 2), y * CELL_SIZE),(x * CELL_SIZE + i * (CELL_SIZE // 2), y * CELL_SIZE + CELL_SIZE), 1)# 绘制交叉点pygame.draw.circle(screen, (0, 0, 0), (x * CELL_SIZE + CELL_SIZE - CELL_SIZE/2, y * CELL_SIZE + CELL_SIZE - CELL_SIZE/2), 2)  # 使用半径为2的圆点if board[x][y] == BLACK:pygame.draw.circle(screen, (0, 0, 0), rect.center, CELL_SIZE // 2 - 5)elif board[x][y] == WHITE:pygame.draw.circle(screen, (255, 255, 255), rect.center, CELL_SIZE // 2 - 5)if last_move:# row, col = latest_move# 方形高亮 棋格highlight_rect = pygame.Rect(last_move[0] * CELL_SIZE, last_move[1] * CELL_SIZE, CELL_SIZE, CELL_SIZE)pygame.draw.rect(screen, HIGHLIGHT_COLOR, highlight_rect, 2)# 圆形高亮 棋子highlight_center = (last_move[0] * CELL_SIZE + CELL_SIZE // 2, last_move[1] * CELL_SIZE + CELL_SIZE // 2)highlight_radius = CELL_SIZE // 2 - 5  # 与棋子相同的半径pygame.draw.circle(screen, HIGHLIGHT_COLOR, highlight_center, highlight_radius+1.5, 2)  # 用圆形高亮, 1.5是为了补偿高亮,高亮是2pygame.draw.rect(screen, BORDER_COLOR, (0, 0, CELL_SIZE * BOARD_SIZE, CELL_SIZE * BOARD_SIZE), 5)# 绘制边框def check_winner(board, player):for x in range(BOARD_SIZE):for y in range(BOARD_SIZE):if board[x][y] == player:# 检查水平方向if x + 4 < BOARD_SIZE and all(board[x + i][y] == player for i in range(5)):return True# 检查垂直方向if y + 4 < BOARD_SIZE and all(board[x][y + i] == player for i in range(5)):return True# 检查斜向(左上到右下)if x + 4 < BOARD_SIZE and y + 4 < BOARD_SIZE and all(board[x + i][y + i] == player for i in range(5)):return True# 检查斜向(右上到左下)if x - 4 >= 0 and y + 4 < BOARD_SIZE and all(board[x - i][y + i] == player for i in range(5)):return Truereturn Falsedef check_threats(board, player):three_in_a_row_positions = []for x in range(BOARD_SIZE):for y in range(BOARD_SIZE):if board[x][y] == EMPTY:board[x][y] = player  # 模拟落子if check_winner(board, player):board[x][y] = EMPTYreturn [(x, y)]  # 直接获胜# 检测是否出现三子的情况if count_consecutive(board, x, y, player) == 3:three_in_a_row_positions.append((x, y))board[x][y] = EMPTYreturn three_in_a_row_positionsdef count_consecutive(board, x, y, player):# 检查周围的棋子数量count = 0for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1), (-1, -1), (1, 1), (-1, 1), (1, -1)]:temp_count = 0for step in range(1, 5):  # 只检测四个方向nx, ny = x + dx * step, y + dy * stepif 0 <= nx < BOARD_SIZE and 0 <= ny < BOARD_SIZE and board[nx][ny] == player:temp_count += 1else:breakcount += temp_countreturn countdef get_defensive_move(board):# 检查对方是否可以形成三子或四子for position in check_threats(board, BLACK):return position  # 返回防守位置return Nonedef get_random_move(board):empty_cells = [(x, y) for x in range(BOARD_SIZE) for y in range(BOARD_SIZE) if board[x][y] == EMPTY]return random.choice(empty_cells) if empty_cells else Nonedef get_preferred_move(board):preferred_moves = []for x in range(BOARD_SIZE):for y in range(BOARD_SIZE):if board[x][y] == EMPTY:# 优先选择靠近黑子的位置for dx in [-1, 0, 1]:for dy in [-1, 0, 1]:nx, ny = x + dx, y + dyif 0 <= nx < BOARD_SIZE and 0 <= ny < BOARD_SIZE and board[nx][ny] == BLACK:preferred_moves.append((x, y))breakreturn random.choice(preferred_moves) if preferred_moves else get_random_move(board)def main():pygame.init()screen = pygame.display.set_mode((WIDTH, HEIGHT))pygame.display.set_caption("五子棋")game_over = False  # 游戏是否结束board = [[EMPTY for _ in range(BOARD_SIZE)] for _ in range(BOARD_SIZE)]last_move = Nonewhile True:for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()sys.exit()if game_over:continue  # 如果游戏结束,不处理任何落子# 检查是否平局if all(board[x][y] != EMPTY for x in range(BOARD_SIZE) for y in range(BOARD_SIZE)):game_over = Trueprint("游戏平局!")if event.type == pygame.MOUSEBUTTONDOWN:x, y = event.posx //= CELL_SIZEy //= CELL_SIZEif 0 <= x < BOARD_SIZE and 0 <= y < BOARD_SIZE and board[x][y] == EMPTY:board[x][y] = BLACKlast_move = (x, y)if check_winner(board, BLACK):game_over = Trueprint("黑方获胜!")#pygame.quit()#sys.exit()# 白方落子if not game_over and not (all(board[x][y] != EMPTY for x in range(BOARD_SIZE) for y in range(BOARD_SIZE))):move = get_defensive_move(board)if move is None:  # 若没有可防守的位置,落子move = get_preferred_move(board)board[move[0]][move[1]] = WHITElast_move = moveif check_winner(board, WHITE):game_over = Trueprint("白方获胜!")# pygame.quit()# sys.exit()draw_board(screen, board, last_move)pygame.display.flip()pygame.quit()
if __name__ == "__main__":main()

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

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

相关文章

Qt Modbus 2 通信实现

上一文章主要了解下Modbus协议和事务处理流程&#xff0c;本章则直接贴放代码实现qt 上位机与温控器通讯。项目主要实现定时读取温度、设置温度、开始加热和停止加热四个功能。 采用的是 Modbus Rtu 通信 1 Qt modbus 模块依赖 QT serialbus serialport 源代码 .h文件 #i…

033_Structure_Static_In_Matlab求解结构静力学问题两套方法

结构静力学问题 静力学问现在是已经很简单的问题&#xff0c;在材料各向同性的情况下&#xff0c;对于弹性固体材料&#xff0c;很容易通过有限元求解。特别是线弹性问题&#xff0c;方程的矩阵形式可以很容易的写出&#xff08;准确得说是很容易通过有限元表达&#xff09;&a…

rnn/lstm 项目实战

tip:本项目用到的数据和代码在https://pan.baidu.com/s/1Cw6OSSWJevSv7T1ouk4B6Q?pwdz6w2 1. RNN : 预测股价 任务&#xff1a;基于zgpa_train.csv数据,建立RNN模型,预测股价 1.完成数据预处理&#xff0c;将序列数据转化为可用于RNN输入的数据 2.对新数据zgpa_test.csv进…

jenkins 构建报错 mvn: command not found

首先安装过 maven&#xff0c;并且配置过环境变量 win r ,输入 cmd 键入 mvn -v 出现上图输出&#xff0c;则证明安装成功。 原因 jenkins 没有 maven 配置全局属性, 导致无法找到 mvn 命令。 解决方案 找到全局属性&#xff0c;点击新增&#xff0c;配置 MAVEN_HOME 路…

轮廓图【HTML+CSS+JavaScript】

给大家分享一个很好看的轮播图&#xff0c;这个也是之前看到别人写的效果感觉很好看&#xff0c;所以后面也自己实现了一下&#xff0c;在这里分享给大家&#xff0c;希望大家也可以有所收获 轮播图效果&#xff1a; 视频效果有点浑浊&#xff0c;大家凑合着看&#xff0c;大家…

ChatGPT变AI搜索引擎!以后还需要谷歌吗?

前言 在北京时间11月1日凌晨&#xff0c;正值ChatGPT两岁生日之际&#xff0c;OpenAI宣布推出最新的人工智能搜索体验&#xff01;具备实时网络功能&#xff01;与 Google 展开直接竞争。 ChatGPT搜索的推出标志着ChatGPT成功消除了即时信息这一最后的短板。 这项新功能可供 …

Linux系统性能调优

在Linux系统中&#xff0c;性能调优是确保系统高效运行的重要任务。优化可以涵盖多个方面&#xff0c;包括文件系统、内存管理、网络和进程管理等。以下是一些常用的Linux性能调优策略&#xff1a; 1. 系统监控工具 在开始优化之前&#xff0c;首先需要监控系统的性能&#x…

Netty 组件介绍 - ByteBuf

直接内存&堆内存 ByteBuf buffer ByteBufAllocator.DEFAULT.heapBuffer(10);ByteBuf byteBuf ByteBufAllocator.DEFAULT.directBuffer(10); 组成 ByteBuf维护了两个不同的索引&#xff0c;一个用于读取&#xff0c;一个用于写入。 写入 内存回收 堆内存使用的是JVM内…

都快2025年了,来看看哪个编程语言才是时下热门吧

早上好啊&#xff0c;大佬们&#xff0c;今天咱们不讲知识&#xff0c;今天我们来看看时下热门的编程语言都是哪些&#xff0c;大佬们又都是在学哪些语言呢。 最近一些朋友和我在讨论哪个编程语言是现在 最好用 最厉害 的编程语言。 有人说&#xff0c;Python简单好用&#xf…

【雷达信号数据集】雷达脉冲活动分段的多级学习算法【附下载链接】

摘要 无线电信号识别是电子战中的一项重要功能。电子战系统需要精确识别和定位雷达脉冲活动&#xff0c;以产生有效的对抗措施。尽管这些任务很重要&#xff0c;但基于深度学习的雷达脉冲活动识别方法在很大程度上仍未得到充分探索。虽然之前已经探索了用于雷达调制识别的深度…

vscode php Launch built-in server and debug, PHP内置服务xdebug调试,自定义启动参数配置使用示例

在vscode中&#xff0c;当我们安装了插件 PHP Debug&#xff08;xdebug.php-debug&#xff09;或者 xdebug.php-pack 后 我们通过内置默认的 php xdebug配置启动php项目后&#xff0c;默认情况下我们在vscode中设置断点是不会生效的&#xff0c;因为我们的内置php服务默认启动时…

(二 上)VB 2010 设计初步

目录 一、常用类应用 1.Console类控制台 2.窗体基本控件 二、面向对象程序设计 1.类和对象 2.对象的属性、方法、事件属 1.属性 2.方法 3.事件、事件过程 1.事件 2.事件过程 3.对象浏览器 三、.NET类库与命名空间 1.命名空间 常用命名空间 1.System命名空间 2.…

[CARLA系列--01]CARLA 0.9.15 在Windows下的安装教程(一)

Carla是一款开源的自动驾驶仿真器&#xff0c;它基本可以用来帮助训练自动驾驶的所有模块&#xff0c;包括感知系统&#xff0c;Localization, 规划系统等等.Carla这个产品目前已经更新到了最新的0.9.15版本,目前遇到好多人在windows系统上如何安装可编辑版的Carla遇到了好多问…

禾川HCQ1控制器程序编译报错如何解决

1、第一次打开用户程序 2、提示库未安装 3、安装库文件 4、脉冲轴库未安装 5、没有错误 去禾川自动化官网,把可以安装的包和库都安装下,程序编译就没有错误了。 6、下载相关包文件

Go语言sync.WaitGroup与errgroup.Group用法详解

errgroup.Group 和 sync.WaitGroup 的主要区别在于它们的错误处理和协程管理方式。 errgroup.Group 专为并发操作中的错误捕获设计&#xff0c;任意goroutine返回错误时&#xff0c;会立即终止其他goroutine的执行。 而 sync.WaitGroup 主要用于等待多个 goroutine 完成&…

ubuntu20安装opencv3.2记录

系统环境 ubuntu20安装了ros-noetic&#xff0c;所以系统默认装了opencv4.2.0&#xff0c;但是跑fastlivo推荐的是opencv3.2.0&#xff0c;而且海康相机别人写的ros驱动&#xff08;海康相机ros驱动&#xff09;也是需要opencv3.2.0&#xff0c;最终还是选择安装多版本的openc…

基于NVIDIA NIM平台实现盲人过马路的demo(一)

前言:利用NVIDIA NIM平台提供的大模型进行编辑,通过llama-3.2-90b-vision-instruct模型进行初步的图片检测 step1: 部署大模型到本地,引用所需要的库 import os import requests import base64 import cv2 import time from datetime import datetimestep2: 观看官方使用文…

MATLAB下的四个模型的IMM例程(CV、CT左转、CT右转、CA四个模型),附源代码可复制

文章目录 基于IMM算法的目标跟踪概述源代码运行结果代码结构与功能1. 初始化2. 仿真参数设置3. 模型参数设置4. 生成量测数据5. IMM算法初始化6. IMM迭代7. 绘图8. 辅助函数总结基于IMM算法的目标跟踪 概述 该MATLAB代码实现了基于交互式多模型(IMM)算法的目标跟踪,旨在估…

Redis-README官方入门文档

文章目录 Redis是什么&#xff1f;什么是Redis社区版&#xff1f;构建Redis修复依赖项或缓存构建选项的构建问题修复构建32位二进制文件的问题分配器单调时钟详细构建运行Redis运行支持TLS的Redis玩转Redis安装Redis代码贡献Redis商标Redis内部结构源代码布局server.hserver.cc…

Netty 组件介绍 - Future Promise

在异步处理时&#xff0c;经常用到这两个接口 netty 中的 Future 继承 jdk 中的 FutuFuture&#xff0c;而Promise 又对 netty Future 进行了扩展。 idk Future 只能同步等待任务结束&#xff08;或成功或失败)才能得到结果netty Future 可以同步等待任务结束得到结也可以异…