潍坊网站建设服务跟/谷歌推广费用
五子棋游戏禁手算法的改进
五子棋最新的禁手规则:
1.黑棋禁手判负、白棋无禁手。黑棋禁手有“三三”(包括“四三三”)、“四四”(包括“四四三”)和“长连”。黑棋只能以“四三”取胜。
2.黑方五连与禁手同时形成,判黑方胜。
3.黑方禁手形成时,白方应立即指出。若白方在之后继续落子,则禁手失效,此后指出禁手也不判黑方负。
注意:本条仅限于“三三”和“四四”禁手点,黑方走出的长连则不同:在对局结束前,白方无论何时指出黑方出现长连,都判白方胜。
禁手设置算法:
禁手有三种基本形,即三三禁手和四四禁手,以及长连禁手。
另外还有三三四,四四三类禁手,以及一些特殊形态的禁手。
三三禁手形态:00 10100 > 0 x K x 1 x 0
00 1100 > 0 x K 1 x 0
0 10010 > 0 K x x 1 0
四四禁手形态:00 11100 > 0 x K 1 1 x 0
0 11010 > 0 K 1 x 1 0
0 10110 > 0 K x 1 1 0
K 是遍历搜索点,if (K=1) 黑子时, x 点位就是三连和四连的禁手点位。
用遍历搜索算法按15 * 15 棋盘点位pn ( 1 -225 ),
分四个方向搜索,即左右,上下,右斜,斜左。遇黑子则计算加权分,赋100分值。此方法可减少计算量,无黑子位不计算。三三四四各形态同时搜索查验加权计算,一次遍历加权计分,最后查验加权分情况,超过100分的点位就是禁手点位。如有超过200分的情况就是三三四和四四三禁手。
长连禁手设置:在判胜负函数detect()时黑棋超过五连即是长连禁手,判黑负,白棋胜。
有一些特殊的形态如扁担阵暂不设置。此程序是简版,完整版本要全面设置。
代码中有显示计算的分值点标记,黄色是100分的点位,紫色是超过100分的点位,即禁手点位。这是测试算法时用来查看的,应用时可注释掉。
此算法是基本的算法,优点是简单和易于理解。
黑棋如设置禁手要想获胜就只有活四和嵌五,还有就是冲四活三,原先发布的博文有bug,当时较仓促,算法测试不充分,忽略了冲四活三的情况。今就此补充修正代码。
这里有个巧妙的算法,在原代码上改一下就成了。算法是三三计权分仍然是100而四四的计权分改为110,这样三三禁手分是200,四四禁手分是220,如是三三四就310分,四四三就320分,
if ( js[i]>110 && js[i]!=210 ) { ...... }
这样计分大于110就触发禁手,而若等于210分就是冲四活三必胜点。
图例:
黄色点是计分点,紫色点是禁手点
restrict_move ( ) { //禁手设置
//黑棋禁手,加权计算查找
for (i=1;i<=225;i++) { js[i]=0 ; } //init scan
//三三禁手,01010 此情况中间为可成三三的交点
//此点记100,若有两个三三,此点就计分200,
//即禁手点位,黑棋若下子即可判负
for (i=1;i<=15;i++){ //遍历scan 黑子
for (j=1;j<=15;j++){
k=(i-1)*15+j ; //pn(n) number
//三三禁手形 0 0 1 010 0, k前后 0位计权
//两边为空中间可成活三,有子是假活三
if (pn[k]==1){ // scan B (k)
if (pn[k-1]==0&&pn[k+1]==0&&pn[k+2]==1&&pn[k+3]==0){
js[k+1]= js[k+1]+100 ;
if ( pn[k-2]==0) js[k-1]= js[k-1]+100 ;
if (pn[k+4]==0) js[k+3]= js[k+3]+100 ;
if ( pn[k-2]==1&&pn[k+4]==1) { //101(0)101四四的特殊情况
js[k+1]= js[k+1]+200 ; } }//左右
if (pn[k-15]==0&&pn[k+15]==0&&pn[k+30]==1&&pn[k+45]==0){
js[k+15]= js[k+15]+100 ;
if ( pn[k-30]==0) js[k-15]= js[k-15]+100 ;
if (pn[k+60]==0) js[k+45]= js[k+45]+100 ;
if ( pn[k-30]==1&&pn[k+60]==1) { //四四
js[k+15]= js[k+15]+200 ; } }//上下
if (pn[k-14]==0&&pn[k+14]==0&&pn[k+28]==1&&pn[k+42]==0){
js[k+14]= js[k+14]+100 ;
if ( pn[k-28]==0) js[k-14]= js[k-14]+100 ;
if (pn[k+56]==0) js[k+42]= js[k+42]+100 ;
if ( pn[k-28]==1&&pn[k+56]==1) { //四四
js[k+14]= js[k+14]+200 ; } }//斜左
if (pn[k-16]==0&&pn[k+16]==0&&pn[k+32]==1&&pn[k+48]==0){
js[k+16]= js[k+16]+100 ;
if ( pn[k-32]==0) js[k-16]= js[k-16]+100 ;
if (pn[k+64]==0) js[k+48]= js[k+48]+100 ;
if ( pn[k-32]==1&&pn[k+64]==1) { //四四
js[k+16]= js[k+16]+200 ; } }//右斜
} //00 1 0100 四四 1(0)101的特殊情况
//禁手形 00 1 100 , k前后 0位计权
if (pn[k]==1){ //scan B (k)
if (pn[k-1]==0&&pn[k+1]==1&&pn[k+2]==0){
if (pn[k-2]==0) js[k-2]= js[k-2]+100 ;
if (pn[k-2]==0) js[k-1]= js[k-1]+100 ;
if (pn[k+3]==0) js[k+2]= js[k+2]+100 ;
if (pn[k+3]==0) js[k+3]= js[k+3]+100 ; } //左右
if (pn[k-15]==0&&pn[k+15]==1&&pn[k+30]==0){
if (pn[k-30]==0) js[k-30]= js[k-30]+100 ;
if (pn[k-30]==0) js[k-15]= js[k-15]+100 ;
if (pn[k+45]==0) js[k+30]= js[k+30]+100 ;
if (pn[k+45]==0) js[k+45]= js[k+45]+100 ; } //上下
if (pn[k-14]==0&&pn[k+14]==1&&pn[k+28]==0){
if (pn[k-28]==0) js[k-28]= js[k-28]+100 ;
if (pn[k-28]==0) js[k-14]= js[k-14]+100 ;
if (j<12&&pn[k+42]==0) js[k+28]= js[k+28]+100 ;
if (pn[k+42]==0) js[k+42]= js[k+42]+100 ; } //斜左
if (pn[k-16]==0&&pn[k+16]==1&&pn[k+32]==0){
if (pn[k-32]==0) js[k-32]= js[k-32]+100 ;
if (pn[k-32]==0) js[k-16]= js[k-16]+100 ;
if (pn[k+48]==0) js[k+32]= js[k+32]+100 ;
if (pn[k+48]==0) js[k+48]= js[k+48]+100 ; } //右斜
} //00 1 100
//禁手形 0 1 0010 , 中间 0位计权
if (pn[k]==1){ //scan B (k)
if (pn[k-1]==0&&pn[k+1]==0&&pn[k+2]==0&&pn[k+3]==1&&pn[k+4]==0){
js[k+1]= js[k+1]+100 ;
js[k+2]= js[k+2]+100 ; } //左右
if (pn[k-15]==0&&pn[k+15]==0&&pn[k+30]==0&&pn[k+45]==1&&pn[k+60]==0){
js[k+15]= js[k+15]+100 ;
js[k+30]= js[k+30]+100 ; } //上下
if (pn[k-14]==0&&pn[k+14]==0&&pn[k+28]==0&&pn[k+42]==1&&pn[k+56]==0){
js[k+14]= js[k+14]+100 ;
js[k+28]= js[k+28]+100 ; } //斜左
if (pn[k-16]==0&&pn[k+16]==0&&pn[k+32]==0&&pn[k+48]==1&&pn[k+64]==0){
js[k+16]= js[k+16]+100 ;
js[k+32]= js[k+32]+100 ; } //右斜
} //010010
//四四禁手算法同三三禁手
//四四禁手形 00 1 1100 , 前后 0 位计权
//更正:冲四加活三不是禁手!! add 110分
//加:特殊禁手 111 0 x 0 111
if (pn[k]==1){ //scan B (k)
if (pn[k+1]==1&&pn[k+2]==1){
if (pn[k-2]==0&&pn[k-1]==0){ js[k-1]= js[k-1]+110 ; js[k-2]= js[k-2]+110 ; }
if (pn[k+3]==0&&pn[k+4]==0){
js[k+3]= js[k+3]+110 ; js[k+4]= js[k+4]+110 ; } } //左右
if (pn[k+15]==1&&pn[k+30]==1){
if (pn[k-30]==0&&pn[k-15]==0){ js[k-15]= js[k-15]+110 ; js[k-30]= js[k-30]+110 ; }
if (pn[k+45]==0&&pn[k+60]==0){
js[k+45]= js[k+45]+110 ; js[k+60]= js[k+60]+110 ; } } //上下
if (pn[k+14]==1&&pn[k+28]==1){
if (pn[k-28]==0&&pn[k-14]==0){ js[k-14]= js[k-14]+110 ; js[k-28]= js[k-28]+110 ; }
if (pn[k+42]==0&&pn[k+56]==0){
js[k+42]= js[k+42]+110 ; js[k+56]= js[k+56]+110 ; } } //斜左
if (pn[k+16]==1&&pn[k+32]==1){
if (pn[k-32]==0&&pn[k-16]==0){ js[k-16]= js[k-16]+110 ; js[k-32]= js[k-32]+110 ; }
if (pn[k+48]==0&&pn[k+64]==0){
js[k+48]= js[k+48]+110 ; js[k+64]= js[k+64]+110 ; } } //右斜
} //0 1 110 ( 111 0x0 111 )
//四四禁手形 0 1 1010 , 0 1 0110 前后 0 位计权
if (pn[k]==1){ //scan B (k)
if (pn[k-1]==0&&pn[k+1]==0&&pn[k+3]==1&&pn[k+4]==0){
if (pn[k+1]==0&&pn[k+2]==1)js[k+1]= js[k+1]+110 ;
if (pn[k+1]==1&&pn[k+2]==0)js[k+2]= js[k+2]+110 ;
} //左右
if (pn[k-15]==0&&pn[k+15]==0&&pn[k+45]==1&&pn[k+60]==0){
if (pn[k+15]==0&&pn[k+30]==1)js[k+15]= js[k+15]+110 ;
if (pn[k+15]==1&&pn[k+30]==0)js[k+30]= js[k+30]+110 ;
} //上下
if (pn[k-14]==0&&pn[k+14]==0&&pn[k+42]==1&&pn[k+56]==0){
if (pn[k+14]==0&&pn[k+28]==1)js[k+14]= js[k+14]+110 ;
if (pn[k+14]==1&&pn[k+28]==0)js[k+28]= js[k+28]+110 ;
} //斜左
if (pn[k-16]==0&&pn[k+16]==0&&pn[k+48]==1&&pn[k+64]==0){
if (pn[k+16]==0&&pn[k+32]==1)js[k+16]= js[k+16]+110 ;
if (pn[k+16]==1&&pn[k+32]==0)js[k+32]= js[k+32]+110 ;
} //右斜
} //0 1 1010 0 1 0110
//********
} } //scan i , j 整个搜索过程
//禁手的基本设置就这样
//长连禁手设置:在判胜负函数 detect ( ) 时
// 黑棋超过五连即判黑负,白棋胜。
//**********
cs.SetTextSize (16);
cs.SetTextStyle (0);
cs.SetFillMode (1);//0不填色,1填色
for (i=1;i<=225;i++){ //test restrict_move
if (js[i] !=0) { //Mark it 标记禁手点
s=intToString ( js[i]) ;
dx=(i-(i/15*15))*40;
dy=(i/15)*40+40;
if (dx==0){ dx=15*40; dy=dy-40; }
cs.SetColor (255,250,250,0) ;
cs.DrawCircle (dx,dy,3) ; //draw mark
//更正:冲四加活三不是禁手!! 四加 110分
if (js[i]>110&&js[i]!=210){
cs.SetColor (255,180,0,180) ;
cs.DrawCircle (dx,dy,5) ; } //draw mark
} }
cs.Update ( ) ;
}//restrict_move ( )
图例:
在下拉菜单设置禁手
上图E 9, G 10 ,H 6
此三点位就是冲四活三必杀点
全局变量加:
int js[225]; //禁手设置 遍历棋盘点位
int jsset ; //0=on 有禁手,1=off 无禁手,下拉菜单
在白棋下子后加禁手判断:
white_do ( ){ //白棋下子
............
testAIq ( ); //AI 算法测试 ****
//scan restricted move and draw mark
if (jsset==0) restrict_move ( ) ; //禁手设置标记
}//white_do ( )
在判胜负的function detect ( ) 中加代码,
如触禁手判白棋胜
detect ( ) {
...... ......
//*****************************
if (jsset==0&&pn[n]==1&&js[n]>110&&js[i]!=210){
//禁手,判白棋胜
print "禁手 pn=", n ;
cs.SetColor(255,255,0,0);
cs.SetTextSize (16);
cs.DrawText ("( 禁手 )",655,(dn+2)*16 );
cs.SetTextSize (40);
cs.DrawText ("( 禁手 )",460,530 );
ss9="白棋胜 !";
goto heqi; }
...... ......
}//detect ( )
其他功能设置感兴趣的朋友可参阅我本站其他博文,
需要游戏程序源码可联系我:micelu@126.com
//**End**
相关文章:

五子棋游戏禁手算法的改进
五子棋游戏禁手算法的改进 五子棋最新的禁手规则: 1.黑棋禁手判负、白棋无禁手。黑棋禁手有“三三”(包括“四三三”)、“四四”(包括“四四三”)和“长连”。黑棋只能以“四三”取胜。 2.黑方…...

基于 Debian 12 的 Devuan GNU+Linux 5 为软件自由爱好者而生
导读Devuan 开发人员宣布发布 Devuan GNULinux 5.0 “代达罗斯 “发行版,它是 Debian GNU/Linux 操作系统的 100% 衍生版本,不包含 systemd 和相关组件。 Devuan GNULinux 5 基于最新的 Debian GNU/Linux 12 “书虫 “操作系统系列,采用长期支…...

算法系列-力扣234-回文链表判定
回文链表判定 给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。 方法一:栈反转对比法 解题思路:找到中间节点后用栈辅助反转对比 解题方法࿱…...

算法通关村——海量数据场景下的热门算法题的处理方法
1. 从40个亿中产生一个不存在的整数 题目要求:给定一个输入文件,包含40亿个非负整数,请设计一个算法,产生一个不存在该文件中的整数,假设你有1GB的内存来完成这项任务。 ● 进阶:如果只有10MB的内存可用&a…...

【C++从0到王者】第二十五站:多继承的虚表
文章目录 前言一、多继承的虚函数表二、菱形继承与菱形虚拟继承的虚函数表1.菱形继承2.菱形虚拟继承的虚函数表 三、抽象类1.抽象类的概念2.接口继承与实现继承 总结 前言 其实关于单继承的虚函数表我们在上一篇文章中已经说过了,就是派生类中的虚表相当于拷贝了一…...

老程序员教你如何笑对问题,轻松培养逻辑思考和解决问题的能力
原文链接 老程序员教你如何笑对问题,轻松培养逻辑思考和解决问题的能力 故事发生在一个阳光明媚的午后,我们的主人公,老李,一位拥有十年工作经验的 Python 老程序员,正悠哉地在喝着咖啡。 这时&#x…...

Omni Recover for Mac(专业的iPhone数据恢复软件)
Omni Recover for Mac是一款专业的Mac数据恢复软件,能够帮助用户快速找回被误删除、格式化、病毒攻击等原因造成的文件和数据,包括图片、视频、音频、文档、邮件、应用程序等。同时,Omni Recover for Mac还具有数据备份和清理功能,…...

视频垂直镜像播放,为您的影片带来新鲜感
大家好!在制作视频时,我们常常希望能够给观众带来一些新鲜感和独特的视觉效果。而垂直镜像播放是一个能够让您的影片与众不同的技巧。然而,传统的视频剪辑软件往往无法直接实现视频的垂直镜像播放,给我们带来了一些困扰。现在&…...

十一、MySQL(DQL)聚合函数
1、聚合函数 注意:在使用聚合函数时,所有的NULL是不参与运算的。 2、实际操作: (1)初始化表格 (2)统计该列数据的个数 基础语法: select count(字段名) from 表名; ;统…...

C语言:三子棋小游戏
简介: 目标很简单:实现一个 三子棋小游戏。三子棋大家都玩过,规则就不提及了。本博文中实现的三子棋在对局中,电脑落子是随机的,不具有智能性,玩家的落子位置使用键盘输入坐标。下面开始详细介绍如何实现一…...

JAVA - PO DTO 生成器
PO DTO 生成器 假设你是一个Java 高级程序员,我会提供一些信息,你需要帮我自动生成Java的PO、DTO 对象。 这些信息有着固定的形式,第一行是对象的类名,其后的每一行都是该对象的属性(简称“属性”)。 对于我属性,格式…...

tcpdump
TCPDump是一个用于抓取网络数据包的命令行工具。它可以帮助网络管理员和开发人员分析网络流量、故障排除以及安全问题。下面是一些TCPDump的详细用法: 基本用法: 监听指定网络接口:tcpdump -i eth0通过IP地址过滤:tcpdump host 19…...

数据通信——传输层TCP(可靠传输原理的ARQ)
引言 上一篇讲述了停止等待协议的工作流程,在最后提到了ARQ自动请求重传机制。接下来,我们就接着上一篇的篇幅,讲一下ARQ这个机制 还是这个图来镇楼 ARQ是什么? 发送端对出错的数据帧进行重传是自动进行的,因而这种…...

Compose - 交互组合项
按钮 Button OutLinedButton带外边框、TextButton只是文字、IconButton只是图标形状。 Button(onClick { }, //点击回调modifier Modifier,enabled true, //启用或禁用interactionSource MutableInteractionSource(),elevation ButtonDefaults.elevatedButtonElevation( /…...

【发版公告】Virbox Protector 3.1.3.19051 发版- elf 文件支持导入表保护
深盾安全-软件保护工具 Virbox Protector 3 ( 3.1.3.19051)迎来了版本升级.本次升级支持了 elf 文件导入表保护。 以下是本次 Virbox Protector 发版的主要功能: 新功能 1. ELF格式的程序支持导入表保护(Beta);; 2…...

点云数据做简单的平面的分割 三维场景中有平面,杯子,和其他物体 实现欧式聚类提取 对三维点云组成的场景进行分割
点云分割是根据空间,几何和纹理等特征对点云进行划分,使得同一划分内的点云拥有相似的特征,点云的有效分割往往是许多应用的前提,例如逆向工作,CAD领域对零件的不同扫描表面进行分割,然后才能更好的进行空洞修复曲面重建,特征描述和提取,进而进行基于3D内容的检索,组合…...

C++之std::search应用实例(一百八十九)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…...

一文详解 requests 库中 json 参数和 data 参数的用法
在requests库当中,requests请求方法,当发送post/put/delete等带有请求体的请求时,有json和data2个参数可选。 众所周知,http请求的请求体格式主要有以下4种: application/json applicaiton/x-www-from-urlencoded mu…...

Django学习笔记-AcApp端授权AcWing一键登录
笔记内容转载自 AcWing 的 Django 框架课讲义,课程链接:AcWing Django 框架课。 AcApp 端使用 AcWing 一键授权登录的流程与之前网页端的流程一样,只有申请授权码这一步有一点细微的差别: 我们在打开 AcApp 应用之后会自动向 AcW…...

如何在小红书进行学习直播
诸神缄默不语-个人CSDN博文目录 因为我是从B站开始的,所以一些直播常识型的东西请见我之前写的如何在B站进行学习直播这一篇。 本篇主要介绍一些小红书之与B站不同之处。 小红书在手机端是可以直接点击“”选择直播的。 文章目录 1. 电脑直播-小红书直播软件2. 电…...

F5服务器负载均衡能力如何?一文了解
但凡知道服务器负载均衡这个名词的,基本都知道 F5,因为负载均衡是 F5 的代表作,换句话来说,负载均衡就是由 F5 发明的。提到F5服务器负载均衡能力如何?不得不关注F5提出的关于安全、网络全面优化的解决方案,…...

Ubuntu18.04安装docker-io
1. 安装docker 1.1 网上一搜,全是更新仓库、下载依赖、添加docker的gpg密钥、添加docker仓库、安装docker-ce的步骤,但是在安装docker-ce时却提示“package "docker-ce" has no installation candidate”,就很迷。 1.2 安装docke…...

代码随想录笔记--栈与队列篇
目录 1--用栈实现队列 2--用队列实现栈 3--有效的括号 4--删除字符串中的所有相邻重复项 5--逆波兰表达式求值 6--滑动窗口的最大值 7--前k个高频元素 1--用栈实现队列 利用两个栈,一个是输入栈,另一个是输出栈; #include <iostrea…...

【力扣】55. 跳跃游戏 <贪心>
【力扣】55. 跳跃游戏 给一个非负整数数组 nums ,最初位于数组的第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。 示例 1…...

在iPhone 15发布之前,iPhone在智能手机出货量上占据主导地位,这对安卓来说是个坏消息
可以说这是一记重拳,但似乎没有一个有价值的竞争者能与苹果今年迄今为止的智能手机出货量相媲美。 事实上,根据Omdia智能手机型号市场跟踪机构收集的数据,苹果的iPhone占据了前四名。位居榜首的是iPhone 14 Pro Max,2023年上半年…...

题目:2620.计数器
题目来源: leetcode题目,网址:2620. 计数器 - 力扣(LeetCode) 解题思路: 定义两个全局变量,一个判断 n 是否改变,另一个记录上一次出现的数。 解题代码: /*** par…...

【MySQL】MySQL系统变量(system variables)列表(SHOW VARIABLES 的结果例)
文章目录 【MySQL】MySQL系统变量(system variables)列表(SHOW VARIABLES 的结果例)SHOW VARIABLES 的结果例参考 【免责声明】文章仅供学习交流,观点代表个人,与任何公司无关。 编辑|SQL和数据库技术(ID:S…...

【多AZ】浅述云计算多az
多AZ(Availability Zone)是云计算中一种重要的容灾和冗余策略,它通过在不同的地理位置或不同的设备上存储数据副本以及网络切换策略,以保证在单个设备或地理位置发生故障时,云加计算集群仍然能够提供服务。 多AZ的特点…...

Element浅尝辄止13:Collapse 折叠面板
通过折叠面板收纳内容区域 1.如何使用? 可同时展开多个面板,面板之间不影响 <el-collapse v-model"activeNames" change"handleChange"><el-collapse-item title"一致性 Consistency" name"1">&l…...

51 单片机包含头文件 BIN51.H 直接写二进制数字
51 单片机包含头文件 BIN51.H 直接写二进制 最近学习 51 单片机,写代码的时候感觉用二进制的形式更直观。就是每次都需要宏定义,太麻烦。干脆把所有的8位二进制数字全部用宏定义写出来,放进头文件,下次使用直接包含头文件就行。 …...