python+pygame实现五子棋人机对战之三

上回讲过:

python+pygame实现五子棋人机对战之一

python+pygame实现五子棋人机对战之二

界面已经有了,并且可以支持鼠标操作选择菜单和人机对战开始下棋了,那电脑是如何应手落子呢?以下内容是通用的类,全部放在utils.py中

四、

最常见的基本棋型大体有以下几种:连五,活四,冲四,活三,眠三,活二,眠二了,下面简要讲解一下:

4.1 连五:五颗同色棋子连在一起

4.2 活四:由4枚同色棋子形成的两端没有对方棋子的四枚棋子

4.3 冲四一(连四):由4枚同色棋子形成的一端有对方棋子的四枚棋子

4.4 冲四二(跳四):由4枚同色棋子形成的中间没有对方棋子的四枚棋子。

4.5 眠四:由4枚同色棋子形成的两端有对方棋子的4枚棋子。  不能成五的四连。

相对比活四来说,冲四的威胁性就小了很多,此时,防守方只要跟着防守在那个唯一的连五点上,冲四就没法形成连五。

4.6 活三一(连三):由3枚同色棋子形成连三、跳三。  再走一着可以形成活四的三。 两端都是威胁的活三。简称“连三”。

4.7 活三二(跳三):由3枚同色棋子形成的中间没有对方棋子的三枚棋子。中间夹有一个威胁的活三。简称“跳三”。

4.8 眠三:由3枚同色棋子形成的两端有对方棋子的3枚棋子。  即再走一着可以形成冲四的三。眠三的形状是很丰富的。眠三的棋型与活三的棋型相比,危险系数下降不少,因为眠三棋型即使不去防守,下一手它也只能形成冲四,而对于单纯的冲四棋型,我们是可以防守住的。

活三可以形成眠三,但也能够形成活四。眠三只能够形成冲四。

4.9 活二 :由2枚同色棋子形成的连二(由2枚同色棋子连在一起形成的两头没有对方棋子的2枚棋子。)、跳二(由2枚同色棋子形成的中间没有对方棋子的2枚棋子。)、大跳二(中间有两个空白位置的跳二)。

4.10 眠二 :由2枚同色棋子形成的两端有对方棋子的2枚棋子。是能够形成眠三的二。

               

对于棋盘上每一个交叉点,会有8个方向连成五子的可能性,那么我们就利用算法算出所有的可能性,并根据它成五的概率给它打分,这样,得分最高的就是最好的落子点。

如何去实现呢?首先我们在8个方向上将其抽象成坐标的加减,例如水平向右,那么x+1,y不变,向右上,则x+1,y+1 .按正下方开始,逆时针8个方向就形成下面的数据结构:

directions = [[0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1]]

 获取当前坐标的各个方向上棋子属性,返回1代表白棋,返回2代表黑棋,返回0代表没有棋,返回5表示在棋盘外。

from params import Paramsrows = int(Params.get('ROWS'))
blocksize = int(Params.get('blockSize'))
width = int(Params.get('WIDTH'))
height = int(Params.get('HEIGHT'))# 获取当前坐标的各个方向上棋子属性,返回1代表白棋,返回2代表黑棋,返回0代表没有棋,返回5表示在棋盘外
def getpointpiece(_mapchess,pos, src, offset):# 8个方向directions = [[0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1]]x1, y1 = posx1 = x1 + directions[src - 1][0] * offset * blocksizey1 = y1 + directions[src - 1][1] * offset * blocksizeif x1 > 588 or y1 > 588 or x1 < 28 or y1 < 28:return 5else:return _mapchess[str(x1) + ',' + str(y1)]

再加上刚才分析的五子棋的基本棋型,可以设计出一个打分算法:

from params import Paramsrows = int(Params.get('ROWS'))
blocksize = int(Params.get('blockSize'))
width = int(Params.get('WIDTH'))
height = int(Params.get('HEIGHT'))# 判断每个点的value,用来排序该点下棋的可行性
def pointvalue(_mapchess, pos, flag1, flag2):value = 0    #加权值for i in range(1, 9):  #8个方向# 11111   连五if getpointpiece(_mapchess,pos, i, 1) == flag1 and \getpointpiece(_mapchess,pos, i, 2) == flag1 and \getpointpiece(_mapchess,pos, i, 3) == flag1 and \getpointpiece(_mapchess,pos, i, 4) == flag1 and \getpointpiece(_mapchess,pos, i, 5) == flag1:value += 1000000# *1111_ 活四if getpointpiece(_mapchess, pos, i, 1) == flag1 and \getpointpiece(_mapchess, pos, i, 2) == flag1 and \getpointpiece(_mapchess, pos, i, 3) == flag1 and \getpointpiece(_mapchess, pos, i, 4) == flag1 and \getpointpiece(_mapchess, pos, i, 5) == 0:value += 50000# *11112 冲四1,冲四指加一个点就是连五,比活四威力小得多if getpointpiece(_mapchess, pos, i, 1) == flag1 and \getpointpiece(_mapchess, pos, i, 2) == flag1 and \getpointpiece(_mapchess, pos, i, 3) == flag1 and \getpointpiece(_mapchess, pos, i, 4) == flag1 and \getpointpiece(_mapchess, pos, i, 5) == flag2:value += 30000# 1*111 冲四2if getpointpiece(_mapchess, pos, i, -1) == flag1 and \getpointpiece(_mapchess, pos, i, 1) == flag1 and \getpointpiece(_mapchess, pos, i, 2) == flag1 and \getpointpiece(_mapchess, pos, i, 3) == flag1:value += 30000# 11*11 冲四3if getpointpiece(_mapchess, pos, i, -2) == flag1 and \getpointpiece(_mapchess, pos, i, -1) == flag1 and \getpointpiece(_mapchess, pos, i, 1) == flag1 and \getpointpiece(_mapchess, pos, i, 2) == flag1:value += 30000# *111_ 活三1,活三可以形成活四的三if getpointpiece(_mapchess, pos, i, 1) == flag1 and \getpointpiece(_mapchess, pos, i, 2) == flag1 and \getpointpiece(_mapchess, pos, i, 3) == flag1 and \getpointpiece(_mapchess, pos, i, 4) == 0:value += 20000# *1_11_ 活三2if getpointpiece(_mapchess, pos, i, 1) == flag1 and \getpointpiece(_mapchess, pos, i, 2) == 0 and \getpointpiece(_mapchess, pos, i, 3) == flag1 and \getpointpiece(_mapchess, pos, i, 4) == flag1 and \getpointpiece(_mapchess, pos, i, 5) == 0:value += 20000# *1112 眠三1  眠三是只能形成冲四的三if getpointpiece(_mapchess, pos, i, 1) == flag1 and \getpointpiece(_mapchess, pos, i, 2) == flag1 and \getpointpiece(_mapchess, pos, i, 3) == flag1 and \getpointpiece(_mapchess, pos, i, 4) == flag2:value += 15000# _1_112 眠三2if getpointpiece(_mapchess, pos, i, 1) == flag1 and \getpointpiece(_mapchess, pos, i, 2) == 0 and \getpointpiece(_mapchess, pos, i, 3) == flag1 and \getpointpiece(_mapchess, pos, i, 4) == flag1 and \getpointpiece(_mapchess, pos, i, 5) == flag2:value += 15000# _11_12 眠三3if getpointpiece(_mapchess, pos, i, 1) == flag1 and \getpointpiece(_mapchess, pos, i, 2) == flag1 and \getpointpiece(_mapchess, pos, i, 3) == 0 and \getpointpiece(_mapchess, pos, i, 4) == flag1 and \getpointpiece(_mapchess, pos, i, 5) == flag2:value += 15000# 1__11 眠三4if getpointpiece(_mapchess, pos, i, -1) == flag1 and \getpointpiece(_mapchess, pos, i, 1) == 0 and \getpointpiece(_mapchess, pos, i, 2) == flag1 and \getpointpiece(_mapchess, pos, i, 3) == flag1:value += 15000# 1_1_1 眠三5if getpointpiece(_mapchess, pos, i, -1) == flag1 and \getpointpiece(_mapchess, pos, i, 1) == flag1 and \getpointpiece(_mapchess, pos, i, 2) == 0 and \getpointpiece(_mapchess, pos, i, 3) == flag1:value += 15000# 2_111_2 眠三6if getpointpiece(_mapchess, pos, i, -1) == flag2 and \getpointpiece(_mapchess, pos, i, 1) == flag1 and \getpointpiece(_mapchess, pos, i, 2) == flag1 and \getpointpiece(_mapchess, pos, i, 3) == flag1 and \getpointpiece(_mapchess, pos, i, 4) == 0 and \getpointpiece(_mapchess, pos, i, 5) == flag2:value += 15000# __11__ 活二1  活二能够形成活三的二if getpointpiece(_mapchess, pos, i, -1) == 0 and \getpointpiece(_mapchess, pos, i, 1) == flag1 and \getpointpiece(_mapchess, pos, i, 2) == flag1 and \getpointpiece(_mapchess, pos, i, 3) == 0 and \getpointpiece(_mapchess, pos, i, 4) == 0:value += 10000# _1_1_ 活二2if getpointpiece(_mapchess, pos, i, 1) == flag1 and \getpointpiece(_mapchess, pos, i, 2) == 0 and \getpointpiece(_mapchess, pos, i, 3) == flag1 and \getpointpiece(_mapchess, pos, i, 4) == 0:value += 10000# 211__ 眠二1 ,能够形成眠三的二if getpointpiece(_mapchess, pos, i, -1) == flag2 and \getpointpiece(_mapchess, pos, i, 1) == flag1 and \getpointpiece(_mapchess, pos, i, 2) == flag1 and \getpointpiece(_mapchess, pos, i, 3) == 0 and \getpointpiece(_mapchess, pos, i, 4) == 0 and \getpointpiece(_mapchess, pos, i, 5) == 0:value += 1000#21_1__ 眠二2if getpointpiece(_mapchess, pos, i, -1) == flag2 and \getpointpiece(_mapchess, pos, i, 1) == flag1 and \getpointpiece(_mapchess, pos, i, 2) == 0 and \getpointpiece(_mapchess, pos, i, 3) == flag1 and \getpointpiece(_mapchess, pos, i, 4) == 0 and \getpointpiece(_mapchess, pos, i, 5) == 0:value += 1000#21__1_ 眠二3if getpointpiece(_mapchess, pos, i, -1) == flag2 and \getpointpiece(_mapchess, pos, i, 1) == flag1 and \getpointpiece(_mapchess, pos, i, 2) == 0 and \getpointpiece(_mapchess, pos, i, 3) == 0 and \getpointpiece(_mapchess, pos, i, 4) == flag1 and \getpointpiece(_mapchess, pos, i, 5) == 0:value += 1000#*1___1 眠二4if getpointpiece(_mapchess, pos, i, 1) == flag1 and \getpointpiece(_mapchess, pos, i, 2) == 0 and \getpointpiece(_mapchess, pos, i, 3) == 0 and \getpointpiece(_mapchess, pos, i, 4) == 0 and \getpointpiece(_mapchess, pos, i, 5) == flag1:value += 1000# *1__if getpointpiece(_mapchess, pos, i, 1) == flag1 and \getpointpiece(_mapchess, pos, i, 2) == 0 and \getpointpiece(_mapchess, pos, i, 3) == 0:value += 30# *1_if getpointpiece(_mapchess, pos, i, 1) == flag1 and \getpointpiece(_mapchess, pos, i, 2) == 0:value += 20# *1if getpointpiece(_mapchess, pos, i, 1) == flag1:value += 10return value# 获取当前坐标的各个方向上棋子属性,返回1代表白棋,返回2代表黑棋,返回0代表没有棋,返回5表示在棋盘外
def getpointpiece(_mapchess,pos, src, offset):# 8个方向directions = [[0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1]]x1, y1 = posx1 = x1 + directions[src - 1][0] * offset * blocksizey1 = y1 + directions[src - 1][1] * offset * blocksizeif x1 > 588 or y1 > 588 or x1 < 28 or y1 < 28:return 5else:return _mapchess[str(x1) + ',' + str(y1)]

这样就可以实现:当人下了棋后,电脑通过这个算法找出最有利的落子点,然后就在那里下棋。

注:本程序只是提供一个思路而已,并不是最优解。代码中value值可以自行修改,算法可以自己再设计,例如可以假如双活三之类的必须防御的应手。

如何判断胜负呢?待续。。。

python+pygame实现五子棋人机对战之四

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

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

相关文章

全球高端销量第一 凯迪仕智能锁建博会获重磅大奖再次遥遥领先

2024年7月11日&#xff0c;第26届中国广州建博会圆满落幕。Kaadas凯迪仕第11年受邀参展&#xff0c;凭借超吸睛的赛博风展馆和重磅旗舰传奇大师K70系列智能锁震撼亮相&#xff0c;吸引抖音网红云集打卡直播以及众多主流及行业媒体聚集报道。在大家居建装行业全球第一展的舞台上…

问题清除指南|Dell OptiPlex 7070 升级 win11 开启 TPM 2.0 教程

前言&#xff1a;最近想把实验室台式机的系统从 Windows 10 升级到 Windows 11&#xff0c;遇到一点小问题&#xff0c;在此记录一下解决办法。 ⚠️ 注&#xff1a;本教程仅在 Dell OptiPlex 7070 台式机系统中测试有效&#xff0c;并不保证其余型号机器适用此教程。 参考链接…

中国科学院地理所牛书丽团队《Global Change Biology 》最新成果!

本文首发于“生态学者”微信公众号&#xff01; 在全球气候变化的背景下&#xff0c;干旱地区的扩张对生态系统的氮循环产生了深远影响。氮同位素&#xff08;δ15N&#xff09;的天然丰度&#xff0c;尤其是土壤中的δ15N&#xff0c;是评估陆地生态系统氮循环动态和氮限制的关…

【ARMv8/v9 GIC 系列 1.7 -- GIC PPI | SPI | SGI | LPI 中断使能配置概述】

请阅读【ARM GICv3/v4 实战学习 】 文章目录 GIC 各种中断使能配置PPIs(每个处理器私有中断)SPIs(共享外设中断)SGIs(软件生成的中断)LPIs(局部中断)GIC 各种中断使能配置 在ARM GICv3和GICv4架构中,不同类型的中断(如PPIs、SPIs、SGIs和LPIs)可以通过不同的方式进…

分享:2024好的ai文章生成器下载资源 tzqsbic

在当今数字化的时代&#xff0c;ai技术的发展日新月异&#xff0c;为我们的生活和工作带来了诸多便利。其中&#xff0c;ai文章生成器作为一项创新的工具&#xff0c;给当代人们带来了很多好处&#xff0c;尤其是对于很多创作者&#xff0c;不仅能解决创作困难&#xff0c;而且…

【开发工具】webStrom2024版-永久使用

1、解压文件 2、安装步骤 先执行unistall-current-user.vbs&#xff0c;确保当前环境变量下没有历史使用记录。再执行install-current-user.vbs。运行的时候&#xff0c;会有第一个弹窗&#xff0c;点击确定&#xff0c;稍微等待一会&#xff0c;会出现 Done 的弹窗&#xff0…

【Linux】进程间通信之System V共享内存

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;Linux &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵&#xff0c;希望大佬指点一二 如果文章对…

Prometheus+Grafana监控Linux主机

1、安装Prometheus 1.1 、下载Prometheus 下载网址 https://github.com/prometheus/prometheus/releases选择需要的版本 wget https://github.com/prometheus/prometheus/releases/download/v2.53.0/prometheus-2.53.0.linux-amd64.tar.gz1.2、安装Prometheus软件 1.2.1、…

解决鸿蒙开发中克隆项目无法签名问题

文章目录 问题描述问题分析解决方案 问题描述 在一个风和日丽的早晨&#xff0c;这是我学习鸿蒙开发的第四天&#xff0c;把文档过了一遍的我准备看看别人的项目学习一下&#xff0c;于是就用git去clone了一个大佬的开源项目&#xff0c;在签名的时候遇到了问题&#xff1a; h…

在攻防演练中遇到的一个“有马蜂的蜜罐”

在攻防演练中遇到的一个“有马蜂的蜜罐” 有趣的结论&#xff0c;请一路看到文章结尾 在前几天的攻防演练中&#xff0c;我跟队友的气氛氛围都很好&#xff0c;有说有笑&#xff0c;恐怕也是全场话最多、笑最多的队伍了。 也是因为我们遇到了许多相当有趣的事情&#xff0c;其…

【leetcode】滑动窗口专题

文章目录 1.长度最小的子数组2.无重复字符的最长子串3.最大连续1的个数III4.将x减小到0的最小操作数5.水果成篮6.找到字符串中所有字母异位词7.串联所有单词的子串8.最小覆盖子串 1.长度最小的子数组 leetcode 209.长度最小的子数组 看到这个题目&#xff0c;第一眼肯定想到的…

科普文:深入理解Mybatis

概叙 (1) JDBC JDBC(Java Data Base Connection,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成.JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。 优点…

Vue3 + Echarts堆叠折线图的tooltip不显示问题

问题介绍 使用Echarts在Vue3Vite项目中绘制堆叠折线图的的时候&#xff0c;tooltip总是不显示&#xff0c;经过很长时间的排查和修改&#xff0c;最后发现是在使用上有错误导致的。 错误图片展示 问题原因 由于Vue3底层使用proxy代理创建示例&#xff0c;使用其创建出来的实…

FPGA-Verilog-Vivado-软件使用

这里写目录标题 1 软件配置2 FPGA-7000使用2.1 运行启动方式 1 软件配置 编辑器绑定为Vscode&#xff0c;粘贴VS code运行文件的目录&#xff0c;后缀参数保持不变&#xff1a; 如&#xff1a; D:/Users/xdwu/AppData/Local/Programs/Microsoft VS Code/Code.exe [file name]…

(19)夹钳(用于送货)

文章目录 前言 1 常见的抓手参数 2 参数说明 前言 Copter 支持许多不同的抓取器&#xff0c;这对送货应用和落瓶很有用。 按照下面的链接&#xff08;或侧边栏&#xff09;&#xff0c;根据你的设置了解配置信息。 Electro Permanent Magnet v3 (EPMv3)Electro Permanent M…

职业教育人工智能实验实训室建设应用案例

随着人工智能技术的快速发展&#xff0c;其在职业教育领域的应用逐渐深入。唯众作为一家专注于教育技术领域的企业&#xff0c;积极响应国家关于人工智能教育的政策号召&#xff0c;通过建设人工智能实验实训室&#xff0c;为学生提供了一个实践操作与创新思维相结合的学习平台…

34 超级数据查看器 关联图片

超级数据查看器app&#xff08;excel工具&#xff0c;数据库软件&#xff0c;表格app&#xff09; 关联图片讲解 点击 打开该讲的视频 点击访问app下载页面 豌豆荚 下载地址 大家好&#xff0c;今天我们讲一下超级数据查看器的关联图片功能 这个功能能让表中的每一条信息&…

数据结构-散列表(hash table)

6.1 散列表的概念 散列表又叫哈希&#xff08;hash&#xff09;表&#xff0c;是根据键&#xff08;key&#xff09;直接访问在内存存储位置的值&#xff08;value&#xff09;的数据结构&#xff0c;由数组演化而来&#xff08;根据数组支持按照下标进行随机访问数据的特性&a…

力扣爆刷第163天之TOP100五连刷81-85(回文链表、路径和、最长重复子数组)

力扣爆刷第163天之TOP100五连刷81-85&#xff08;回文链表、路径和、最长重复子数组&#xff09; 文章目录 力扣爆刷第163天之TOP100五连刷81-85&#xff08;回文链表、路径和、最长重复子数组&#xff09;一、234. 回文链表二、112. 路径总和三、169. 多数元素四、662. 二叉树…

Python高级(三)_正则表达式

Python高级-正则表达式 第三章 正则表达式 在开发中会有大量的字符串处理工作,其中经常会涉及到字符串格式的校验。 1、正则表达式概述 正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expression,在代码中常简写为regex、…