基于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()

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

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

相关文章

python 基础知识点(蓝桥杯python科目个人复习计划63)

今日复习内容&#xff1a;做题 例题1&#xff1a;蓝桥骑士 问题描述&#xff1a; 小蓝是蓝桥王国的骑士&#xff0c;他喜欢不断突破自我。 这天蓝桥国王给他安排了N个对手&#xff0c;他们的战力值分别为a1,a2,...,an&#xff0c;且按顺序阻挡在小蓝的前方。对于这些对手小…

【LeetCode】动态规划--题目练习

有关动态规划算法的整理&#xff1a;添加链接描述 1.爬楼梯 爬楼梯:LeetCode70 int climbStairs(int n) {//1.确定dp数组和意义 dp[n]表示第n阶的方法//2.确定递推关系式 dp[n] dp[n-1]dp[n-2];//3.初始化int dp[50] {0};dp[1] 1;dp[2] 2;for(int i 3;i<n;i){dp[i] …

C++核心高级编程

文章目录 C++核心高级编程1.内存分区模型1.1 程序运行前1.2 程序运行后1.3 new操作符2.引用2.1 使用2.2 注意事项2.3 做函数参数2.4 做函数返回值2.5 本质2.6 常量引用3.函数提高3.1 函数默认参数3.2 函数占位参数3.3 函数重载3.3.1 函数重载概述3.3.2 注意事项4.类和对象4.1 封…

注意力机制Attention、CA注意力机制

一、注意力机制 产生背景&#xff1a; 大数据时代&#xff0c;有很多数据提供给我们。对于人来说&#xff0c;可以利用重要的数据&#xff0c;过滤掉不重要的数据。那对于模型来说&#xff08;CNN、LSTM&#xff09;&#xff0c;很难决定什么重要、什么不重要&#xff0c;因此…

GRPC服务端和客户端DEMO

proto文件 syntax "proto3";option java_multiple_files true; //指定该proto文件编译成的java源文件的包名 option java_package "com.protobuf"; // 表示下面的message编译成的java类文件的名字 option java_outer_classname "HelloProto"…

vue3+ts动态表单渲染,antd的useForm改造

let fieldList: any getFormFields(fieldInfo.coreNavigationList[0].list[0].list,fieldInfo.positionCodeRespVO,isCanBeUpdateProcess.value,isDetail.value 1); fieldInfo数据格式&#xff1a; {"name": "默认模板","status": "ENA…

Holoens2 发布 错误 DEP6957: 未能使用“通用身份验证”连接到设备“127.0.0.1”

DEP6957: Failed to connect to device 127.0.0.1 using Universal Authentication. Please verify the 解决时看到有人说是usb线没连好&#xff0c;重新连了一下就好了。确定在电脑上能看到hololens设备 错误 DEP6957: 未能使用“通用身份验证”连接到设备“127.0.0.1”_holo…

1688跨境无货源铺货API上货API跨境电商无货源对接

1688 API 接入说明 点此获取API地址 调用示例&#xff1a; 参数说明 通用参数说明 version:API版本key:调用key,测试key:test_api_keyapi_name:API类型[item_get,item_search]cache:[yes,no]默认yes&#xff0c;将调用缓存的数据&#xff0c;速度比较快result_type:[json,xml…

day-20 跳跃游戏 II

思路&#xff1a;用一个数字来存储到对应索引i的最少跳跃次数&#xff0c;ans[j]Math.min(ans[j],ans[i]1) code: class Solution {public int jump(int[] nums) {int nnums.length;int ans[]new int[n];for(int i0;i<n;i){ans[i]Integer.MAX_VALUE;}ans[0]0;for(int i0;i…

从VUCA到BANI时代:如何打造企业韧性经营?

当下&#xff0c;国际局势波谲云诡&#xff0c;国内经济也充满着不确定性&#xff0c;给众多企业带来了前所未有的压力。 然而&#xff0c;在这充满挑战的时刻&#xff0c;一些企业凭借强大的数字化能力&#xff0c;展现出惊人的经营韧性和逆流而上的精神&#xff0c;实现了业绩…

java城市公交车调度安排(司机工作安排管理)-393-(源码+说明资料)

转载地址: http://www.3q2008.com/soft/search.asp?keyword393 添加驾驶员 驾驶员管理 添加车辆 车辆管理 添加公交线路 公交线路管理 车站管理 车站添加 车站配置管理 车站配置 调度配置 调度管理 调度查询 修改资料 工作查询 修改资料 用户管理 网站用户管理 l 1、设计&a…

电梯机房秀 系列二

上次小伍带大家看了部分机房的照片&#xff0c;并且简单介绍了一下电梯能量回馈装置&#xff0c;小伙伴们表示很新奇&#xff0c;没看够&#xff0c;今天小伍又来了&#xff0c;带大家看一下电梯能量回馈装置到底安装在电梯什么位置。跟着小伍去看看吧。Lets go&#xff01; 电…

C++等级3题

鸡兔同笼 #include<bits/stdc.h> using namespace std; void f(int n); int n; int main() {cin>>n;int x0;int ma-1;int mi1000;for(int i0;i<n;i){for(int j0;j<n;j){if(i*2j*4n){x1;mamax(ma,ij);mimin(mi,ij);}}}if(x1){cout<<mi<<" &…

科技回顾,飞凌嵌入式受邀亮相第八届瑞芯微开发者大会「RKDC2024」

2024年3月7日~8日&#xff0c;第八届瑞芯微开发者大会&#xff08;RKDC2024&#xff09;在福州举行&#xff0c;本届大会以“AI芯片AI应用AloT”为主题&#xff0c;邀请各行业的开发者共启数智化未来。 本届大会亮点颇多&#xff0c;不仅有13大芯片应用展示、9场产品和技术论坛…

学生时期学习资源同步-1 第一学期结业考试题8

原创作者&#xff1a;田超凡&#xff08;程序员田宝宝&#xff09; 版权所有&#xff0c;引用请注明原作者&#xff0c;严禁复制转载

296.【华为OD机试】污染水域 (图的多源BFS—JavaPythonC++JS实现)

🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目-污染水域二.解题思路三.题解代码Python题解代码…

GIS入门,GeoServer介绍,GeoServer如何发布WMTS地图服务,GeoServer如何自动切割瓦片

GeoServer介绍 GeoServer是一个开源的地理空间数据服务器,它允许用户共享、处理和编辑地理空间数据。GeoServer基于Java开发,可以将各种空间数据格式(如Shapefile、PostGIS、Oracle Spatial等)转换为标准的地理空间数据服务,比如Web Map Service (WMS)、Web Feature Serv…

超分辨率(2)--基于EDSR网络实现图像超分辨率重建

目录 一.项目介绍 二.项目流程详解 2.1.构建网络模型 2.2.数据集处理 2.3.训练模块 2.4.测试模块 三.测试网络 一.项目介绍 EDSR全称Enhanced Deep Residual Networks&#xff0c;是SRResnet的升级版&#xff0c;其对网络结构进行了优化(去除了BN层)&#xff0c;省下来…

避免阻塞主线程 —— Web Worker 示例项目

前期回顾 迄今为止易用 —— 的 “盲水印“ 实现方案-CSDN博客https://blog.csdn.net/m0_57904695/article/details/136720192?spm1001.2014.3001.5501 目录 CSDN 彩色之外 &#x1f4dd; 前言 &#x1f6a9; 技术栈 &#x1f6e0;️ 功能 &#x1f916; 如何运行 ♻️ …

《JAVA与模式》之工厂方法模式

系列文章目录 文章目录 系列文章目录前言一、工厂方法模式二、工厂方法模式的活动序列图三、工厂方法模式和简单工厂模式前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码…