五子棋游戏禁手算法的改进

news2024/12/24 8:48:49

五子棋游戏禁手算法的改进

五子棋最新的禁手规则:

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分就是冲四活三必胜点。

图例:
黄色点是计分点,紫色点是禁手点

39becd15fca149bb9764d6e3951930c5.png

eae195c27fe3462d828fecf2e0a8f7a6.png 

 

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

图例:

在下拉菜单设置禁手

b8adc3eb9f404515bf356612f0d7a562.png

7ea6e7c06c0f426d97e52f45b5b7055a.png  

上图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**

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

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

相关文章

B端系统设计之【权限】详解

衡量B端产品系统好坏的一个重要标准就是它的权限是否细致&#xff0c;拓展性是否强。 权限管理是B端产品系统的基础&#xff0c;好的权限管理系统延展性较强&#xff0c;即使业务发生变化也能避免大改和推倒重建。 权限分类 1、功能权限 功能权限是指用户登录系统之后&#xff…

前端面试中Vue的有经典面试题三

11. 网页从输入网址到渲染完成经历了哪些过程&#xff1f; 大致可以分为如下7步&#xff1a; 输入网址&#xff1b; 发送到DNS服务器&#xff0c;并获取域名对应的web服务器对应的ip地址&#xff1b; 与web服务器建立TCP连接&#xff1b; 浏览器向web服务器发送http请求&a…

【自用】西门子s7-200连接显示屏和物联网盒子完整配置过程

总览 1.PLC配置 2.显示屏配置 3.物联网盒子配置 一、PLC配置 1.连接PLC软件 STEP-7MicroWIN V4.0 SP9完整版 链接&#xff1a;https://pan.baidu.com/s/17LMEXnbkQZMPI8Bte24Eug?pwdjsi3 提取码&#xff1a;jsi3 2.PLC配置 打开 PLC 上面的小盖子&#xff0c;把红色按钮…

【代码随想录day23】不同路径 II

题目 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物。那么从左上角到…

3.1.6 练习 基于GPA排名计算本专业保研名单

C自学精简教程 目录(必读) GPA概念回顾 平均学分绩点GPA(Grade Point Average)是对一个学生大学学习成绩的综合的衡量指标。 在前面的文章 本科生学分绩点GPA计算 中&#xff0c;我们知道了什么是平均学分绩点GPA&#xff0c;以及如何计算它。 基于GPA给学生排名 现在我们…

介绍几种使用工具

FileWatch&#xff0c;观测文件变化&#xff0c;源码地址&#xff1a;https://github.com/ThomasMonkman/filewatch nlohmann::json&#xff0c;json封装解析&#xff0c;源码地址&#xff1a;https://github.com/nlohmann/json optionparser&#xff0c;解析选项&#xff0c;源…

4.(Python数模)0-1规划

Python解决0-1规划问题 参考下面文章 源代码 import pulp # 导入 pulp 库# 主程序 def main():# 投资决策问题&#xff1a;# 公司现有 5个拟投资项目&#xff0c;根据投资额、投资收益和限制条件&#xff0c;问如何决策使收益最大。"""问题建模&#x…

9. 微积分 - 导数

文章目录 导数求导实例代码演示:迭代法求解二次函数最小值阶Hi, 大家好。我是茶桁。 我们终于结束了极限和连续的折磨,开启了新的篇章。 不过不要以为我们后面的就会很容易,只是相对来说, 没有那么绕而已。 那么,我们今天开始学习「导数」。 导数 在之前的导论,也就是…

【算法竞赛宝典】求分数精确值

【算法竞赛宝典】求分数精确值 题目描述思路讲解代码展示 题目描述 思路讲解 代码展示 //计算分数的精确值 #include<iostream>using namespace std; int remainder[101], quotient[101]; //remainder:存放除法的余数;quotient:依次存放商的每一位int main() {int m, n,…

[CISCN 2019初赛]Love Math

文章目录 前言考点解题过程 前言 感慨自己实力不够&#xff0c;心浮气躁根本做不来难题。难得这题对我还很有吸引力&#xff0c;也涉及很多知识。只能说我是受益匪浅&#xff0c;总的来说加油吧ctfer。 考点 利用php动态函数的特性利用php中的数学函数实现命令执行利用php7的特…

项目验收有哪些流程?

验收流程 科技计划项目验收/课题验收测试服务的被测对象是国家重大专项、科研课题的软件成果物&#xff0c;可以是一个模块、软件或系统等&#xff0c;也可以是软件套件或软件原型等。测试范围主要来源于课题的合同书/可行吧报告/申报书中的技术指标要求。所出具的科技项目验收…

中东 Shopify 如何使用 Bytebase 构建一站式数据库开发工作流

公司简介 Salla 是一家 2016 年成立&#xff0c;位于沙特麦加的自建站电商平台。 作为中东 Shopify&#xff0c;其最大的特点是支持阿拉伯语建站&#xff0c;并且提供更多适应中东地区特点的本地化服务。截止目前&#xff0c;已有 47,000 家店铺入驻 Salla&#xff0c;商品销售…

并发测试工具 apache-jmeter使用发送post请求JSON数据

目录 1 下载安装 2 汉化 3 创建高并发测试 配置线程组 创建web请求 创建监听器 结果树 汇总报告 为web请求添加token 添加Content-Type用于发送json 4 启动测试 5 查看结果 1 下载安装 官网Apache JMeter - Download Apache JMeter 解压运行 2 2 汉化 打开软件…

CS144环境配置问题

使用wsl来做CS144实验&#xff0c;可能会在编译的时候遇到以下问题&#xff0c;很明显是找不到LIBPCAP&#xff0c;参考链接 使用sudo apt-get install libpcap-dev命令下载该库即可。 CMake Error: The following variables are used in this project, but they are set to N…

什么是精益生产?企业如何实现精益生产?

国内的很多制造企业之所以对“精益生产”持怀疑甚至否度态度&#xff0c;大都经历过实施过程中的“水土不服”难题。抛砖引玉讲一下&#xff1a; 1、精益生产的最典型案例 1991年&#xff0c;在当时整个美国处于一种将被“日本人支配”的恐惧背景下&#xff0c;“精益生产”一…

【FPGA项目】第1个项目,来点个灯吧~

前言 你会FPGA吗&#xff1f;我会点灯&#xff01; 一、概述 作为一名点灯高手&#xff0c;今天就来实际操练一下。 如何点亮&#xff1f; 开发板上带有8个LED灯&#xff0c;我们只需要控制它对应的管脚电平输入即可。 1&#xff1a;灭&#xff1b;0&#xff1a;亮。 如何实…

大语言模型之七- Llama-2单GPU(T4 16G)微调(Fine-tune)

模型预训练colab脚本在github主页面。详见Finetuning_LLama_2_0_on_Colab_with_1_GPU.ipynb 在上一篇博客提到两种改进预训练模型性能的方法Retrieval-Augmented Generation (RAG) 或者 finetuning。本篇博客过一下模型微调。 微调&#xff1a;这是采用预训练的LLM并在较小的…

ESP8266+继电器+MQTT+VUE 实现远程开关灯

超详细教程 – ESP8266继电器MQTTVUE 实现远程开关灯 超详细教程 – ESP8266继电器MQTTVUE 实现远程开关灯 接线图 NC&#xff08;通常闭合&#xff09;与COM&#xff08;公共&#xff09;、NO&#xff08;通常开放&#xff09;与COM 是继电器引脚的不同配置&#xff0c;用于不…

JAVA实现SAP接口

JAVA实现SAP接口 环境spring-bootmaven 1.maven依赖 <dependency><groupId>com.github.virtualcry</groupId><artifactId>sapjco-spring-boot-starter</artifactId><version>3.1.4</version></dependency>2.配置文件 applic…

AI+认知行为疗法,治愈心灵的良药丨青源Workshop「AI+心理干预」观点集锦

当前&#xff0c;抑郁症、焦虑症等心理障碍成为社会关注的焦点&#xff0c;如何有效地缓解和治疗这些心理问题成为一个重要的研究方向。在这样的背景下&#xff0c;如何利用AI等先进技术手段来辅助心理疾病的治疗备受关注。例如&#xff0c;通过语音、脑部MRI辅助诊断器质性抑郁…