python-分享篇-五子棋

文章目录

  • 代码
  • 效果

代码

"""五子棋之人机对战"""import sys
import random
import pygame
from pygame.locals import *
import pygame.gfxdraw
from checkerboard import Checkerboard, BLACK_CHESSMAN, WHITE_CHESSMAN, offset, PointSIZE = 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/682644.shtml

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

相关文章

JVM(1)基础篇

1 初始JVM 1.1 什么是JVM JVM 全称是 Java Virtual Machine&#xff0c;中文译名 Java虚拟机。JVM 本质上是一个运行在计算机上的程序&#xff0c;他的职责是运行Java字节码文件。 Java源代码执行流程如下&#xff1a; 分为三个步骤&#xff1a; 编写Java源代码文件。 使用…

Android实现底部导航栏方法(Navigation篇)

Navigation实现底部导航栏 前言导入和基本使用导入基础使用创建nav文件编辑Nav文件添加页面&#xff08;代码版&#xff09;添加页面&#xff08;图解版&#xff09; 创建导航动作 action创建action&#xff08;代码版&#xff09;创建action&#xff08;图解版&#xff09; 编…

「C++ 类和对象篇 12」static成员

目录 一、static成员是什么&#xff1f; 二、为什么需要static成员&#xff1f; 三、怎么使用static成员&#xff1f; 1. 定义static成员变量 2. 定义static成员函数 3. 访问static成员 四、特性 【面试题】 【总结】 一、static成员是什么&#xff1f; 被static修饰的类成…

品牌之门:概率与潜力的无限延伸

在品牌的世界里&#xff0c;每一个成功的推广都像是打开一扇门&#xff0c;从未知走向已知&#xff0c;从潜在走向显现。这扇门&#xff0c;既是品牌的起点&#xff0c;也是品牌发展的无限可能。 品牌&#xff0c;就像一扇紧闭的门&#xff0c;它静静地矗立在那里&#xff0c;…

微信强制分享红包裂变系统源码

这是一款新型的微信裂变引流系统源码&#xff0c;支持试看、直播、朋友圈转发、分享任务、 邀请入群、群聊、红包等多种裂变引流方式&#xff0c;让你的广告流量引流、吸粉变现更加高效。 该系统源码还优化了整个页面&#xff0c;减少了繁重多余的代码&#xff0c;让访问速度…

【51单片机】直流电机驱动(PWM)(江科大)

1.直流电机介绍 直流电机是一种将电能转换为机械能的装置。一般的直流电机有两个电极,当电极正接时,电机正转,当电极反接时,电机反转 直流电机主要由永磁体(定子)、线圈(转子)和换向器组成 除直流电机外,常见的电机还有步进电机、舵机、无刷电机、空心杯电机等 2.电机驱动…

对(一维)数组与指针的深入理解(1)

目录 1.数组名的理解2.使用指针访问&#xff08;一维&#xff09;数组3.&#xff08;一维&#xff09;数组传参的本质 1.数组名的理解 以前我们在使用指针访问数组内容时&#xff0c;有这样的代码&#xff1a; #include <stdio.h>int main() {int arr[10] { 1,2,3,4,5…

详解Qt多线程(包含:什么是CPU,单核处理器和多核处理器,举餐厅和QQ音乐的例子详解进程和线程,Qt多线程案例)

目录 一.什么是CPU&#xff1f;二.单核处理器与多核处理器三.什么是进程和线程&#xff1f;3.1 定义3.2 以餐厅为例子解释进程和线程3.2 以QQ音乐为例子&#xff0c;解释QQ音乐里面的进程和线程 四.Qt中的多线程五.Qt多线程案例任务描述案例演示设置显示内容的字体大小和位置运…

pands常用操作

1.导入库和文件读取和文件分信息分析 import pandas as pd import numpy as np csvf pd.read_csv(D:/各个站程序版本说明.csv) csvf.info() <class pandas.core.frame.DataFrame> RangeIndex: 51 entries, 0 to 50 Data columns (total 6 columns):# Column Non-Nul…

java面试题整理

2023.2.14&#xff08;第二天&#xff09; 数组是不是对象&#xff1f; 在Java中&#xff0c;数组是对象。数组是一种引用类型&#xff0c;它可以存储固定大小的相同类型的元素序列。在Java中&#xff0c;数组是通过new关键字创建的&#xff0c;它们在内存中被分配为对象&…

「数据结构」MapSet

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;Java数据结构 &#x1f387;欢迎点赞收藏加关注哦&#xff01; Map&Set &#x1f349;概念&#x1f349;模型&#x1f349;Map&#x1f34c;TreeMap和HashMap的区别&#x1f34c;Map常用方…

2048游戏C++板来啦!

个人主页&#xff1a;PingdiGuo_guo 收录专栏&#xff1a;C干货专栏 大家好呀&#xff0c;我是PingdiGuo_guo&#xff0c;今天我们来学习如何用C编写一个2048小游戏。 文章目录 1.2048的规则 2.步骤实现 2.1: 初始化游戏界面 2.1.1知识点 2.1.2: 创建游戏界面 2.2: 随机…

Days 31 ElfBoard 自启脚本中打开看门狗

1.在开机自启脚本中打开看门狗 rootELF1:~# vi /etc/rc.local 2.在自启脚本中添加上之后&#xff0c;然后在咱们的QT界面中找到看门狗应用&#xff0c; 发现显示打开看门狗失败&#xff1a; 3.修改看门狗源码&#xff0c;设置了超时时间后&#xff0c;关闭/dev/dev/watchdog节…

【Tomcat】:One or more listeners failed to start.报错解决方案

报错信息:One or more listeners failed to start. Full details will be found in the appropriate container log file. 具体就是web.xml此配置报错: 服务器启动错误Tomcat:One or more listeners failed to start.报错解决方案 IDEA:在使用IDEA运行SSM项目的时候 , Tomcat运…

error MSB8008: 指定的平台工具集(v143)未安装或无效。请确保选择受支持的 PlatformToolset 值解决办法

右击解决方案&#xff0c;选择属性 将工具集为143的修改为其他&#xff0c;如图 重新编译即可运行

网络原理(3)--以太网协议,DNS

&#x1f495;"Echo"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;网络原理(3)–以太网协议,DNS 在网络原理(2)中介绍了网络层中的一个重要的协议–ip协议,网络层关注的通信时的起点和终点,而数据链路层更加"底层"一些,关注的是传输过程…

【Effective Objective - C 2.0】——读书笔记(四)

文章目录 二十三、通过委托与数据源协议进行对象间通信二十四、将类的实现代码分散到便于管理的数个分类之中二十五、总是为第三方的分类名称加前缀二十六、切勿在分类里面声明属性二十七、使用“class-continuation分类”隐藏实现细节二十八、通过协议提供匿名对象 二十三、通…

springboot187社区养老服务平台的设计与实现

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

MySQL 基础知识(六)之数据查询(一)

目录 1 基本查询 1.1 查询相关列 (select * / 列名) 1.2 别名 (as) 1.3 去重 (distinct) 1.4 对列中的数据进行运算 (、-、*、/) 2 条件查询 (where) 2.1 等值查询 () 2.2 非等值查询 (>、<、>、<、!、><) 2.3 逻辑判断 (and、or、not) 2.4 区间判…

源码推荐:hello-algo @ github

github https://github.com/krahets/hello-algo 本项目旨在创建一本开源、免费、对新手友好的数据结构与算法入门教程。全书采用动画图解&#xff0c;结构化地讲解数据结构与算法知识&#xff0c;内容清晰易懂&#xff0c;学习曲线平滑。算法源代码皆可一键运行&#xff0c;支…