基于Python的pygame库的五子棋游戏
安装pygame
pip install pygame
五子棋游戏代码
"""五子棋之人机对战"""import sys
import random
import pygame
from pygame.locals import *
import pygame.gfxdraw
from collections import namedtupleChessman = namedtuple('Chessman', 'Name Value Color')
Point = namedtuple('Point', 'X Y')BLACK_CHESSMAN = Chessman('黑子', 1, (45, 45, 45))
WHITE_CHESSMAN = Chessman('白子', 2, (219, 219, 219))offset = [(1, 0), (0, 1), (1, 1), (1, -1)]class Checkerboard:def __init__(self, line_points):self._line_points = line_pointsself._checkerboard = [[0] * line_points for _ in range(line_points)]def _get_checkerboard(self):return self._checkerboardcheckerboard = property(_get_checkerboard)# 判断是否可落子def can_drop(self, point):return self._checkerboard[point.Y][point.X] == 0def drop(self, chessman, point):"""落子:param chessman::param point:落子位置:return:若该子落下之后即可获胜,则返回获胜方,否则返回 None"""print(f'{chessman.Name} ({point.X}, {point.Y})')self._checkerboard[point.Y][point.X] = chessman.Valueif self._win(point):print(f'{chessman.Name}获胜')return chessman# 判断是否赢了def _win(self, point):cur_value = self._checkerboard[point.Y][point.X]for os in offset:if self._get_count_on_direction(point, cur_value, os[0], os[1]):return Truedef _get_count_on_direction(self, point, value, x_offset, y_offset):count = 1for step in range(1, 5):x = point.X + step * x_offsety = point.Y + step * y_offsetif 0 <= x < self._line_points and 0 <= y < self._line_points and self._checkerboard[y][x] == value:count += 1else:breakfor step in range(1, 5):x = point.X - step * x_offsety = point.Y - step * y_offsetif 0 <= x < self._line_points and 0 <= y < self._line_points and self._checkerboard[y][x] == value:count += 1else:breakreturn count >= 5SIZE = 30 # 棋盘每个点时间的间隔
Line_Points = 19 # 棋盘每行/每列点数
Outer_Width = 20 # 棋盘外宽度
Border_Width = 4 # 边框宽度
Inside_Width = 4 # 边框跟实际的棋盘之间的间隔
Border_Length = SIZE * (Line_Points - 1) + Inside_Width * 2 + Border_Width # 边框线的长度
Start_X = Start_Y = Outer_Width + int(Border_Width / 2) + Inside_Width # 网格线起点(左上角)坐标
SCREEN_HEIGHT = SIZE * (Line_Points - 1) + Outer_Width * 2 + Border_Width + Inside_Width * 2 # 游戏屏幕的高
SCREEN_WIDTH = SCREEN_HEIGHT + 200 # 游戏屏幕的宽Stone_Radius = SIZE // 2 - 3 # 棋子半径
Stone_Radius2 = SIZE // 2 + 3
Checkerboard_Color = (0xE3, 0x92, 0x65) # 棋盘颜色
BLACK_COLOR = (0, 0, 0)
WHITE_COLOR = (255, 255, 255)
RED_COLOR = (200, 30, 30)
BLUE_COLOR = (30, 30, 200)RIGHT_INFO_POS_X = SCREEN_HEIGHT + Stone_Radius2 * 2 + 10def print_text(screen, font, x, y, text, fcolor=(255, 255, 255)):imgText = font.render(text, True, fcolor)screen.blit(imgText, (x, y))def main():pygame.init()screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))pygame.display.set_caption('五子棋')font1 = pygame.font.SysFont('SimHei', 32)font2 = pygame.font.SysFont('SimHei', 72)fwidth, fheight = font2.size('黑方获胜')checkerboard = Checkerboard(Line_Points)cur_runner = BLACK_CHESSMANwinner = Nonecomputer = AI(Line_Points, WHITE_CHESSMAN)black_win_count = 0white_win_count = 0while True:for event in pygame.event.get():if event.type == QUIT:sys.exit()elif event.type == KEYDOWN:if event.key == K_RETURN:if winner is not None:winner = Nonecur_runner = BLACK_CHESSMANcheckerboard = Checkerboard(Line_Points)computer = AI(Line_Points, WHITE_CHESSMAN)elif event.type == MOUSEBUTTONDOWN:if winner is None:pressed_array = pygame.mouse.get_pressed()if pressed_array[0]:mouse_pos = pygame.mouse.get_pos()click_point = _get_clickpoint(mouse_pos)if click_point is not None:if checkerboard.can_drop(click_point):winner = checkerboard.drop(cur_runner, click_point)if winner is None:cur_runner = _get_next(cur_runner)computer.get_opponent_drop(click_point)AI_point = computer.AI_drop()winner = checkerboard.drop(cur_runner, AI_point)if winner is not None:white_win_count += 1cur_runner = _get_next(cur_runner)else:black_win_count += 1else:print('超出棋盘区域')# 画棋盘_draw_checkerboard(screen)# 画棋盘上已有的棋子for i, row in enumerate(checkerboard.checkerboard):for j, cell in enumerate(row):if cell == BLACK_CHESSMAN.Value:_draw_chessman(screen, Point(j, i), BLACK_CHESSMAN.Color)elif cell == WHITE_CHESSMAN.Value:_draw_chessman(screen, Point(j, i), WHITE_CHESSMAN.Color)_draw_left_info(screen, font1, cur_runner, black_win_count, white_win_count)if winner:print_text(screen, font2, (SCREEN_WIDTH - fwidth)//2, (SCREEN_HEIGHT - fheight)//2, winner.Name + '获胜', RED_COLOR)pygame.display.flip()def _get_next(cur_runner):if cur_runner == BLACK_CHESSMAN:return WHITE_CHESSMANelse:return BLACK_CHESSMAN# 画棋盘
def _draw_checkerboard(screen):# 填充棋盘背景色screen.fill(Checkerboard_Color)# 画棋盘网格线外的边框pygame.draw.rect(screen, BLACK_COLOR, (Outer_Width, Outer_Width, Border_Length, Border_Length), Border_Width)# 画网格线for i in range(Line_Points):pygame.draw.line(screen, BLACK_COLOR,(Start_Y, Start_Y + SIZE * i),(Start_Y + SIZE * (Line_Points - 1), Start_Y + SIZE * i),1)for j in range(Line_Points):pygame.draw.line(screen, BLACK_COLOR,(Start_X + SIZE * j, Start_X),(Start_X + SIZE * j, Start_X + SIZE * (Line_Points - 1)),1)# 画星位和天元for i in (3, 9, 15):for j in (3, 9, 15):if i == j == 9:radius = 5else:radius = 3# pygame.draw.circle(screen, BLACK, (Start_X + SIZE * i, Start_Y + SIZE * j), radius)pygame.gfxdraw.aacircle(screen, Start_X + SIZE * i, Start_Y + SIZE * j, radius, BLACK_COLOR)pygame.gfxdraw.filled_circle(screen, Start_X + SIZE * i, Start_Y + SIZE * j, radius, BLACK_COLOR)# 画棋子
def _draw_chessman(screen, point, stone_color):# pygame.draw.circle(screen, stone_color, (Start_X + SIZE * point.X, Start_Y + SIZE * point.Y), Stone_Radius)pygame.gfxdraw.aacircle(screen, Start_X + SIZE * point.X, Start_Y + SIZE * point.Y, Stone_Radius, stone_color)pygame.gfxdraw.filled_circle(screen, Start_X + SIZE * point.X, Start_Y + SIZE * point.Y, Stone_Radius, stone_color)# 画左侧信息显示
def _draw_left_info(screen, font, cur_runner, black_win_count, white_win_count):_draw_chessman_pos(screen, (SCREEN_HEIGHT + Stone_Radius2, Start_X + Stone_Radius2), BLACK_CHESSMAN.Color)_draw_chessman_pos(screen, (SCREEN_HEIGHT + Stone_Radius2, Start_X + Stone_Radius2 * 4), WHITE_CHESSMAN.Color)print_text(screen, font, RIGHT_INFO_POS_X, Start_X + 3, '玩家', BLUE_COLOR)print_text(screen, font, RIGHT_INFO_POS_X, Start_X + Stone_Radius2 * 3 + 3, '电脑', BLUE_COLOR)print_text(screen, font, SCREEN_HEIGHT, SCREEN_HEIGHT - Stone_Radius2 * 8, '战况:', BLUE_COLOR)_draw_chessman_pos(screen, (SCREEN_HEIGHT + Stone_Radius2, SCREEN_HEIGHT - int(Stone_Radius2 * 4.5)), BLACK_CHESSMAN.Color)_draw_chessman_pos(screen, (SCREEN_HEIGHT + Stone_Radius2, SCREEN_HEIGHT - Stone_Radius2 * 2), WHITE_CHESSMAN.Color)print_text(screen, font, RIGHT_INFO_POS_X, SCREEN_HEIGHT - int(Stone_Radius2 * 5.5) + 3, f'{black_win_count} 胜', BLUE_COLOR)print_text(screen, font, RIGHT_INFO_POS_X, SCREEN_HEIGHT - Stone_Radius2 * 3 + 3, f'{white_win_count} 胜', BLUE_COLOR)def _draw_chessman_pos(screen, pos, stone_color):pygame.gfxdraw.aacircle(screen, pos[0], pos[1], Stone_Radius2, stone_color)pygame.gfxdraw.filled_circle(screen, pos[0], pos[1], Stone_Radius2, stone_color)# 根据鼠标点击位置,返回游戏区坐标
def _get_clickpoint(click_pos):pos_x = click_pos[0] - Start_Xpos_y = click_pos[1] - Start_Yif pos_x < -Inside_Width or pos_y < -Inside_Width:return Nonex = pos_x // SIZEy = pos_y // SIZEif pos_x % SIZE > Stone_Radius:x += 1if pos_y % SIZE > Stone_Radius:y += 1if x >= Line_Points or y >= Line_Points:return Nonereturn Point(x, y)class AI:def __init__(self, line_points, chessman):self._line_points = line_pointsself._my = chessmanself._opponent = BLACK_CHESSMAN if chessman == WHITE_CHESSMAN else WHITE_CHESSMANself._checkerboard = [[0] * line_points for _ in range(line_points)]def get_opponent_drop(self, point):self._checkerboard[point.Y][point.X] = self._opponent.Valuedef AI_drop(self):point = Nonescore = 0for i in range(self._line_points):for j in range(self._line_points):if self._checkerboard[j][i] == 0:_score = self._get_point_score(Point(i, j))if _score > score:score = _scorepoint = Point(i, j)elif _score == score and _score > 0:r = random.randint(0, 100)if r % 2 == 0:point = Point(i, j)self._checkerboard[point.Y][point.X] = self._my.Valuereturn pointdef _get_point_score(self, point):score = 0for os in offset:score += self._get_direction_score(point, os[0], os[1])return scoredef _get_direction_score(self, point, x_offset, y_offset):count = 0 # 落子处我方连续子数_count = 0 # 落子处对方连续子数space = None # 我方连续子中有无空格_space = None # 对方连续子中有无空格both = 0 # 我方连续子两端有无阻挡_both = 0 # 对方连续子两端有无阻挡# 如果是 1 表示是边上是我方子,2 表示敌方子flag = self._get_stone_color(point, x_offset, y_offset, True)if flag != 0:for step in range(1, 6):x = point.X + step * x_offsety = point.Y + step * y_offsetif 0 <= x < self._line_points and 0 <= y < self._line_points:if flag == 1:if self._checkerboard[y][x] == self._my.Value:count += 1if space is False:space = Trueelif self._checkerboard[y][x] == self._opponent.Value:_both += 1breakelse:if space is None:space = Falseelse:break # 遇到第二个空格退出elif flag == 2:if self._checkerboard[y][x] == self._my.Value:_both += 1breakelif self._checkerboard[y][x] == self._opponent.Value:_count += 1if _space is False:_space = Trueelse:if _space is None:_space = Falseelse:breakelse:# 遇到边也就是阻挡if flag == 1:both += 1elif flag == 2:_both += 1if space is False:space = Noneif _space is False:_space = None_flag = self._get_stone_color(point, -x_offset, -y_offset, True)if _flag != 0:for step in range(1, 6):x = point.X - step * x_offsety = point.Y - step * y_offsetif 0 <= x < self._line_points and 0 <= y < self._line_points:if _flag == 1:if self._checkerboard[y][x] == self._my.Value:count += 1if space is False:space = Trueelif self._checkerboard[y][x] == self._opponent.Value:_both += 1breakelse:if space is None:space = Falseelse:break # 遇到第二个空格退出elif _flag == 2:if self._checkerboard[y][x] == self._my.Value:_both += 1breakelif self._checkerboard[y][x] == self._opponent.Value:_count += 1if _space is False:_space = Trueelse:if _space is None:_space = Falseelse:breakelse:# 遇到边也就是阻挡if _flag == 1:both += 1elif _flag == 2:_both += 1score = 0if count == 4:score = 10000elif _count == 4:score = 9000elif count == 3:if both == 0:score = 1000elif both == 1:score = 100else:score = 0elif _count == 3:if _both == 0:score = 900elif _both == 1:score = 90else:score = 0elif count == 2:if both == 0:score = 100elif both == 1:score = 10else:score = 0elif _count == 2:if _both == 0:score = 90elif _both == 1:score = 9else:score = 0elif count == 1:score = 10elif _count == 1:score = 9else:score = 0if space or _space:score /= 2return score# 判断指定位置处在指定方向上是我方子、对方子、空def _get_stone_color(self, point, x_offset, y_offset, next):x = point.X + x_offsety = point.Y + y_offsetif 0 <= x < self._line_points and 0 <= y < self._line_points:if self._checkerboard[y][x] == self._my.Value:return 1elif self._checkerboard[y][x] == self._opponent.Value:return 2else:if next:return self._get_stone_color(Point(x, y), x_offset, y_offset, False)else:return 0else:return 0if __name__ == '__main__':main()
相关文章:

基于Python的pygame库的五子棋游戏
安装pygame pip install pygame五子棋游戏代码 """五子棋之人机对战"""import sys import random import pygame from pygame.locals import * import pygame.gfxdraw from collections import namedtupleChessman namedtuple(Chessman, Name…...

【Java基础】IO流(二)字符集知识
目录 字符集知识 1、GBK字符集 2、Unicode字符集(万国码) 3、乱码 4、Java中编码和解码的方法 字符集知识 字符(Character):在计算机和电信技术中,一个字符是一个单位的字形、类字形单位或符号的基本信…...

TimescaleDB 开源时序数据库
文章目录 1.TimescaleDB介绍2.Hypertable 和 chunk3.Hypertable4.Hypertable操作 开源中间件 # TimescaleDBhttps://iothub.org.cn/docs/middleware/ https://iothub.org.cn/docs/middleware/timescale/timescale-summary/1.TimescaleDB介绍 TimescaleDB是基于PostgreSQL数据…...

如何保证Redis和数据库数据一致性
缓存可以提升性能,减轻数据库压力,在获取这部分好处的同时,它却带来了一些新的问题,缓存和数据库之间的数据一致性问题。 想必大家在工作中只要用了咱们缓存势必就会遇到过此类问题 首先我们来看看一致性: 强一致性…...

css3常见选择器
使用工具 Visual Studio Code 1.CSS3基础选择器 1.1 标签选择器 1.2.1 标签选择器的语法 一个完整的HTML5页面是由很多不同的标签组成的,而标签选择器则决定标签应采用的CSS样式,语法如下:标签名{ 属性1:属性值1; 属性2&…...

List(CS61B学习记录)
问题引入 上图中,赋给b海象的weight会改变a海象的weight,但x的赋值又不会改变y的赋值 Bits 要解释上图的问题,我们应该从Java的底层入手 相同的二进制编码,却因为数据类型不同,输出不同的值 变量的声明 基本类型…...

Python 导入Excel三维坐标数据 生成三维曲面地形图(面) 1、线条折线曲面
环境和包: 环境 python:python-3.12.0-amd64包: matplotlib 3.8.2 pandas 2.1.4 openpyxl 3.1.2 代码: import pandas as pd import matplotlib.pyplot as plt import numpy as np from mpl_toolkits.mplot3d import Axes3D from matplotlib.colors import ListedColor…...

2024年华为HCIA-DATACOM新增题库(H12-811)
801、[单选题]178/832、在系统视图下键入什么命令可以切换到用户视图? A quit B souter C system-view D user-view 试题答案:A 试题解析:在系统视图下键入quit命令退出到用户视图。因此答案选A。 802、[单选题]“网络管理员在三层交换机上创建了V…...

离线安装数据库 mysql 5.7 linux
离线安装数据库 mysql 5.7 linux 方法一 参考链接Linux(Debian10.2)安装MySQL5.7.24环境 赋予文件执行权限chmod x 文件名 使用root用户sudo su解压文件tar xvf mysql-5.7.42-linux-glibc2.12-x86_64.tar.gz重命名mv mysql-5.7.42-linux-glibc2.12-x86_64 mysql将桌面的mys…...

2024-03-14学习笔记(YoloV9)
1.认知越高的人,越敬畏因果 摘要:本文讲述了认知越高的人越敬畏因果的道理。通过故事和名人案例,阐述了敬畏因果对于个人成长和成功的重要性。文章强调了遵循规律、不走捷径、正向思维的重要性,以及思维、行动、习惯、性格和命运…...

Cookie和Session介绍
1、Cookie的一些重要结论(令牌,类似就诊卡记住我们的信息): (1)Cookie从哪里来:服务器返回给浏览器的,通常是首次访问/登录成功之后(cookie是在header中传输)…...

OpenCV 将rgb图像转化成字符图像
将RGB图像转换成字符图像(ASCII art)通常涉及到灰度化、降采样、映射字符等一系列步骤。以下是一个简化的OpenCVC实现示例: #include <opencv2/opencv.hpp> #include <iostream> #include <string>// 字符映射表ÿ…...

ios开发错误积累
1.xcode 下载模拟器报错 Could not download iOS 报错: 解决: 1、去官网下载自己需要 地址(https://developer.apple.com/download/all) 2、下载完成后,执行以下命令添加:xcrun simctl runtime add /路径…...

软件实际应用实例,物流打印用什么软件,佳易王物流货运快运单打印查询管理系统软件,可以在已经印刷好的单子上打印,也可直接打印
软件实际应用实例,物流打印用什么软件,佳易王物流货运快运单打印查询管理系统软件,可以在已经印刷好的单子上打印,也可直接打印 一、前言 以下软件教程以 佳易王物流单打印查询管理系统软件V17.0为例说明 软件文件下载可以点击…...

第六届上海国际垃圾焚烧发电展将于12月11-13日上海举办
第六届上海国际垃圾焚烧发电暨固废处理技术展览会 2024年12月11-13日 上海新国际博览中心 主办单位:中华环保联合会 废弃物发电专委会 支持单位:垃圾焚烧技术与装备国家工程实验室 承办单位:上海怡涵展览服务有限公司 展会介绍:…...

pytorch(十)循环神经网络
文章目录 卷积神经网络与循环神经网络的区别RNN cell结构构造RNN例子 seq2seq 卷积神经网络与循环神经网络的区别 卷积神经网络:在卷积神经网络中,全连接层的参数占比是最多的。 卷积神经网络主要用语处理图像、语音等空间数据,它的特点是局部…...

【黑马程序员】Python文件、异常、模块、包
文章目录 文件操作文件编码什么是编码为什么要使用编码 文件的读取openmodel常用的三种基础访问模式读操作相关方法 文件的写入注意代码示例 异常定义异常捕获捕获指定异常捕获多个异常捕获所有异常异常else异常finally 异常的传递 python 模块定义模块的导入import模块名from …...

导入fetch_california_housing 加州房价数据集报错解决(HTTPError: HTTP Error 403: Forbidden)
报错 HTTPError Traceback (most recent call last) Cell In[3], line 52 from sklearn.datasets import fetch_california_housing3 from sklearn.model_selection import train_test_split ----> 5 X, Y fetch_california_housing(retu…...

后勤管理系统|基于SSM 框架+vue+ Mysql+Java+B/S架构技术的后勤管理系统设计与实现(可运行源码+数据库+设计文档+部署说明+视频演示)
目录 文末获取源码 前台首页功能 员工注册、员工登录 个人中心 公寓信息 员工功能模块 员工积分管理 管理员登录 编辑管理员功能模块 个人信息 编辑员工管理 公寓户型管理 编辑公寓信息管理 系统结构设计 数据库设计 luwen参考 概述 源码获取 文末获取源…...

【办公类-40-01】20240311 用Python将MP4转MP3提取音频 (家长会系列一)
作品展示: 背景需求: 马上就要家长会,我负责做会议前的照片滚动PPT,除了大量照片视频,还需要一个时间很长的背景音乐MP3 一、下载“歌曲串烧” 装一个IDM 下载三个“串烧音乐MP4”。 代码展示 家长会背景音乐: 歌曲串…...

人类的谋算与量子计算
量子计算并不等价于并行计算。量子计算和并行计算是两种不同的计算模型。 在经典计算中,通过增加计算机的处理器核心和内存等资源,可以实现并行计算,即多个任务同时进行。并行计算可以显著提高计算速度,尤其是对于可以被细分为多个…...

【数据结构和算法初阶(C语言)】栈的概念和实现(后进先出---后来者居上的神奇线性结构带来的惊喜体验)
目录 1.栈 1.1栈的概念及结构 2.栈的实现 3.栈结构对数据的处理方式 3.1对栈进行初始化 3.2 从栈顶添加元素 3.3 打印栈元素 3.4移除栈顶元素 3.5获取栈顶元素 3.6获取栈中的有效个数 3.7 判断链表是否为空 3.9 销毁栈空间 4.结语及整个源码 1.栈 1.1栈的概念及结构 栈&am…...

搭建mysql主从复制(主主复制)
1:设主库允许远程连接(注意:设置账号密码必须使用的插件是mysql_native_password,其他的会连接失败) #切换到mysql这个数据库,修改user表中的host,使其可以实现远程连接 mysql>use mysql; mysql>update user se…...

centos 系统 yum 无法安装(换国内镜像地下)
centos 系统 yum 因为无法连接到国外的官网而无法安装,问题如下图: 更换阿里镜像,配置文件路径:/etc/yum.repos.d/CentOS-Base.repo(如果目录有多余的文件可以移动到子目录,以免造成影响) bas…...

【python绘图】turle 绘图基本案例
文章目录 0. 基础知识1. 蟒蛇绘制2. 正方形绘制3. 六边形绘制4. 叠边形绘制5. 风轮绘制 0. 基础知识 资料来自中国mooc北京理工大学python课程 1. 蟒蛇绘制 import turtle turtle.setup(650, 350, 200, 200) turtle.penup() turtle.fd(-250) turtle.pendown() turtle.pen…...

损失函数和反向传播
1. 损失函数的基础 import torch from torch.nn import L1Loss from torch import nninputs torch.tensor([1, 2, 3], dtypetorch.float32) targets torch.tensor([1, 2, 5], dtypetorch.float32)inputs torch.reshape(inputs, (1, 1, 1, 3)) targets torch.reshape(targe…...

Nginx:配置拦截/禁用ip地址
分析nginx日志 1、分析截止目前为止访问量最高的ip排行 awk {print $1} access.log |sort |uniq -c|sort -nr |head -20过滤出access.log日志文件中访问量前20的ip sort :将文件进行排序,并将排序结果标准输出uniq -nr : 去重并在右边显示…...

css超出部分显示省略号
目录 前言 一、CSS单行实现 二、CSS多行实现(CSS3出的,兼容性需要注意) 三、微信小程序超过2行出现省略号实现 四、JavaScript脚本实现 前言 CSS文本溢出就显示省略号,就是在样式中指定了盒子的宽度与高度,有可能出现某些内…...

python-0001-安装虚拟环境
版本 软件版本python3.9.10django2.2.5sqlite33.45.1pycharm2023.3.4 安装python3.9.10 升级sqlite3 下载地址:https://download.csdn.net/download/qq_41833259/88944701 升级命令: tar -zxvf sqlite-autoconf-3399999.tar.gz cd sqlite-autoconf-…...

Python爬虫:原理与实战
引言 在当今的信息时代,互联网上的数据如同浩瀚的海洋,充满了无尽的宝藏。Python爬虫作为一种高效的数据抓取工具,能够帮助我们轻松地获取这些数据,并进行后续的分析和处理。本文将深入探讨Python爬虫的原理,并结合实战…...