五子棋游戏程序创作过程(C语言)

news/2024/11/22 14:31:38/

五子棋游戏程序创作过程(C语言 )

我是编程爱好者,对游戏程序编制很感兴趣。学习VB6语言时就编制过一些游戏程序,如独立钻石棋、伤脑筋十二块、连连看、扑克牌游戏等,都是windows标准图形界面的。感到很好玩,很有成就感。后来玩了一些PC和手机版的五子棋游戏,就萌生了自己编一个的想法。今在此借助CSDN把这个过程和经验分享给大家,当然大咖和大佬是不要的,他们自己有。那就给初学者吧,我学习时也喜欢看看人家的思路。
创作过程不是很复杂,就是一个循序渐进的过程。我很享受这个过程。首先做游戏程序就要了解这个游戏,玩过了就知道游戏的基本规则。

88991ebb23624b1e8112e03ffc187374.png

 

程序编制的第一步:启动页面,绘制棋盘

设计和绘制游戏界面,绘制棋盘,如何下子,重绘棋盘。这些都仰仗编译器的图形图像功能,VB6,VC,java这方面都很好。这些做好了,游戏的雏形也就完成了。此中主要是设置全局变量。我的思路是变量要简单直接易理解。对于15*15的棋盘,用一维数组就行。
      设int pn [225] ,0表示无子,1表示黑子,2表示白子。
      这个设置在绘制下子时就很简单明了。对于225个棋盘点位:
       一个是i=0-225,另一个是行列row,col,     用于点位选择后绘制棋子,
      棋盘格设置40*40的方格,盘面长宽是600 。定位点距40*i  。

程序编制先定义全局变量:
Canvas cs;    //画布类,绘图时图形图像载体
                      //VC是 canvas , VB是 picture ,java 是 Frame , Graphics
 int px,py;        // piece X  Y  棋子坐标,float X Y 是屏幕坐标
 int dx,dy;        //draw X  Y  绘图坐标
 int i,j,kn;           // 用于循环  
int pn[300];     // pn数组  0=无子 ,1=黑子,2=白子
                         // 棋子225个编码号,防下标越界,容错下标加大
int n;               // 下子时获取 棋子编码号
int dn;             //下子计数
int isDo;          //游戏操作控制: 1=可下子,0=不可下
int B,W,k;       //判断胜负:B黑棋 , W白棋
string cordp;   //游戏记录字串
int mode;        //模式设定:0=双人,1=人机

坐标转换:px=(int)(x/40*40) ;  py=(int)(y/40*40)  ;   
                       坐标定位点距40
                       dx=px/40  ;   dy=py/40  ;   
                       n=(dy-1)*15+dx  ;   pn(n) 棋子编码
                       i=1--225  ;  

           n= i  ;  row=15-(n/15)  ;  col=(n-(n/15*15))  ;

有了转换算法,绘制棋盘棋子,这样就写了board( ) {  棋板函数,用于
起始界面画棋盘,游戏时画已下的黑白子,更新屏幕输出。
这是游戏程序的根基,游戏设计的雏形就成了。
board( )函数,加绘制桌面黑子白子下子按钮,设置按钮是为用户选择下子位后确认落子,避免误操作。比赛时落子计时。

 

接下来是第二步:双人模式,胜负判定

主要是下子操作,胜负判定。既然是博弈就要分胜负,所以胜负判定算法是游戏程序的关键。
下子操作:棋盘区域鼠标移动显示下子位选择标记,我设置在点位上加红色框线和红色标记点。友好界面设计,添加提示,黑棋选子还是白棋选子。同时显示用户选取棋子的序号。此序号就是记录的数据。至此游戏下子操作就成了。
能下子后就要由机器来自动判定胜负,于是就添加胜负判定函数detect( )。胜负判定要点是遍历棋盘点位,向右向下,右斜左斜,四个方向搜索,若有黑子白子就查看是否有五连子。
需要注意的是:向右搜索时col=1 to 11,大了就到下一行了,其他方向亦如此。
正确的遍历搜索是:
向右搜索:i = 1-15 行 ,  j = 1-11 列
向下搜索:i = 1- 11行 ,  j = 1-15列
向右斜搜索:i = 1-11行 ,  j = 1-11列
向斜左搜索:i = 1-11行 ,  j = 5-15列
这样的四个方向搜索下标就不会出界越界。
部分代码如下所示:
 for (i=1;i<=15;i++){     // B 黑子
       for (j=1;j<=11;j++){    
          k=(i-1)*15+j ;    //pn(B) number
       if (pn[k]==1){
      if ( pn[k+1]==1&&pn[k+2]==1&&pn[k+3]==1&&pn[k+4]==1){  goto showwin ;  }         
            }   }    }   //黑子向右搜索五连
双人模式的游戏程序就大功告成了。

b13ec477196f452d8349360817cf3fde.png

 

功能改进是第三步:盘面记录,复盘功能

作为一个能耐人寻味的游戏程序,就要再加些功能。有人要悔棋功能就加一个。其实悔棋功能是鸡肋。下棋是博弈,讲究落子无悔高棋品。
接下来是研究人机对战的电脑智能应子算法。我玩五子棋是低手,要了解博弈的算法很难。参阅了站内一些高手关于AI的智能算法,参阅很多五子棋书籍棋谱和五子棋竞赛的对抗棋谱。为了摆谱,就在此游戏程序上添加了复盘功能。程序没关闭就能复现出上一次的盘面。要复盘就要由有复盘的数据,此复盘数据也就是记录。据此就先加了记录功能。这个记录就是下子的序号。每盘棋都打印黑白双方下子的文本记录,界面上也显示记录。有一点就是程序关闭记录也就没了。解决的方法是把记录存为文本文件,需要时可作为复盘数据。有了记录数据也就完成了复盘功能的设置。
另一个改进:界面记录显示的是序数号,没能明了地表达棋子的点位。于是就需把序数转换成标准的棋盘点位标记。
    如pn(n)=113 --->H8
    n=fudat( i ) ;  复盘记录 ,走子记录
        row=15-(n/15) ;
        col=(n-(n/15*15)) ;
        if (col==0){ col=15 ;    row=row+1 ;   }
        swapabc () ;   //传入col ,输出字母A to O  ,return ss
        cordp=" B   "+intToString (n);    //走子记录,存盘数据 n = 1 to 225
        cordp1=" B  "+ss+intToString (row) ;    //pn(n)=113桌面显示 H8

    abc$="sABCDEFGHIJKLMNO" ;    col(8)="H"    ,  row=8
样例可参阅本站博文《五子棋游戏程序记录和复盘功能设置》,该文有游戏程序示例源码。

5bb6e9cc299241bebf6585392631c8ce.png

 
 游戏程序完善是第四步:AI智能游戏设置人机模式,禁手设置

编制五子棋游戏很有趣,尤其是AI智能算法很烧脑。网上介绍有什么贪心算法,剪枝算法,博弈树算法等等,不一而足。

对于人机对战的电脑智能应子算法,参阅很多五子棋书籍棋谱和五子棋竞赛的对抗棋谱。我感到白棋的后手防御算法很难取胜,棋界有黑棋高手先手必胜一说。算法么想了很多,既然是人工智能下棋就得按人的思路来算计。棋书阐述有许多思路和棋局解说。如活四冲四,嵌五,活三嵌四,活二嵌二。这些是高级棋手的总结。我就按此思路用加权计权方法来表现此类各种情况。

算法可参阅本站博文”五子棋游戏程序禁手设置算法”。此是五子棋游戏AI智能版的完整的设计源码。程序代码写出了基本算法。代码是function   testAIq ( )。

792d9cad03454e4d9d57000bf3e0b9d3.png
另外代码中有一算法测试的方法autotest( ) 可供参考。
此测试黑白双方用同一算法互斗难分胜负,这就像周伯通双手互搏,难分高下。想来要另写白棋防守算法,设置白棋VS黑棋才可看出哪个算法好。我的思路是博弈双方的白棋后手防守点也就是黑棋的加权高分点,白棋加权高分点就是进攻点。我就以计算的高分点为AI下子点。
本人五子棋是初识,水平不高,故写出的AI博弈算法也一般。也就是能人机对战而已。程序中界面显示有加权分,这是算法设计时查看和检测加权计分的情况,以此来修正和改进算法。

 

还有一种说法五子棋博弈要算杀,算杀就是计算必杀之局,如嵌四加活三,冲四加活三,嵌五加活三,嵌五加冲四,这些就是必杀局,就是必胜法宝。算杀的最高境界是做杀,预判算出必杀点提前几子做出必杀局。此谓奕道高手中的高手,乃高高手也。此种算法也就是编程界的高手,是谓大咖也。我望之有些高仰,自感境界还没到。锲而不舍,持之以恒,努力吧。

070f2a118c4a4a8bba150a6bb1f33110.png

 

为了使自己的程序高级一些就加了黑棋的禁手设置。
禁手设置算法:
禁手有三种,即三三禁手和四四禁手,以及长连禁手。
三三禁手形态:00 1  0100,  00 1  100,  0 1 0010 
四四禁手形态:00 1 1100 ,  00 1 1010,  0 1 0110
用遍历搜索算法按15 * 15 棋盘点位pn ( 1 -225 ),
分四个方向搜索,即左右,上下,右斜,斜左。遇黑子则计算加权分,赋100分值。此方法可减少计算量,无黑子位不计算。三三四四各形态同时搜索查验加权计算,一次遍历加权计分,最后查验加权分情况,超过100分的点位就是禁手点位。如有超过200分的情况就是有复合的三三四四禁手。
长连禁手设置:在判胜负函数detect()时黑棋超过五连即是长连禁手,判黑负,白棋胜。
有一些特殊的形态如扁担阵暂不设置。此程序是简版,完整版本要全面设置。
代码中有显示计算的分值点标记,黄色是100分的点位,紫色是超过100分的点位,即禁手点位。这是测试算法时用来查看的,应用时可注释掉。
此算法是基本的算法,优点是简单和易于理解。

下面是禁手设置变量:
int js[255];         //禁手设置,遍历搜索225个点位
int jsset ;            //有无禁手标志

white_do (){    //白棋下子时设置,检测禁手点位
  <  ............>
      if (jsset==1)  restrict_move () ;   // 菜单选择有无禁手,有禁手就执行此函数
      //***  scan restricted move and draw mark
 }//white_do ()
禁手设置restrict_move( ) 
完整的源码可参阅我在本站的博文《五子棋游戏程序禁手设置算法》。
该博文是有禁手设置算法的完整的游戏程序源码。

48320f2cc500466097ef85b6abbecb97.png

 

游戏程序设计的前瞻
以上几个步骤是五子棋游戏程序设计从想做一个五子棋程序到设计完成整个游戏程序设计制作的概要。介绍的是设计者的思路和一些关键的算法。
对于五子棋游戏程序设计的扩展有些想法,试做娱乐版的手机程序,供初学者练手用。做windows版的标准的可供比赛用的专业版五子棋游戏程序。也可做网络版的手机对战游戏程序。程序要有计时功能,完整的记录功能,比赛记录或棋谱的文本数据输入可复盘的功能。
当然如你有超高的手段,就研究现在时兴的AI智能算法,做一个黑先手必胜,白后手不败的独孤不败的五子棋程序。哈哈,我功力不够,开玩笑了。
新生代的学子们,你们年轻,你们有希望登上顶峰。


http://www.ppmy.cn/news/59486.html

相关文章

java获取文件名乱码

Java读linux系统文件文件名乱码的解决办法 1&#xff0c;问题描述 web应用想通过Java读取linux系统文件显示到web页面上&#xff0c;结果中文文件名出现乱码&#xff1f; 问题场景描述&#xff1a;当用户通过浏览器访问tomcat服务器&#xff0c;请求查看某一路径下文件列表信…

VSCode正确使用方式,你知道多少?

VSCode正确使用方式&#xff0c;你知道多少&#xff1f; 目录 VSCode正确使用方式&#xff0c;你知道多少&#xff1f;VSCode 是一款非常流行的代码编辑器&#xff0c;它支持丰富的插件扩展&#xff0c;可以帮助开发者提高开发效率。以下是一些常用的 VSCode 插件及其安装方法&…

day10 TCP是如何实现可靠传输的

TCP最主要的特点 1、TCP是面向连接的运输层协议。&#xff08; 每一条TCP连接只能有两个端点&#xff08;endpoint&#xff09;&#xff0c;每一条TCP连接只能是点对点的&#xff08;一对一&#xff09;&#xff09; 2、TCP提供可靠交付的服务。 3、TCP提供全双工通信。 4…

idea中maven的几个操作按钮:clean、validate、compile...

idea中Maven生命周期指令 clean命令 清除由项目编译创建的target validate命令 验证项目是否正确&#xff0c;并且所有必要的信息均可用 compile命令 编译项目的源代码 test命令 使用合适的单元测试框架来测试编译的源代码。 这些测试不应要求将代码打包或部署 verify命令 …

Java 中的线程是什么,如何创建和管理线程-中(十二)

书接上文 三、Java 线程的同步 Java 中的线程同步是通过 synchronized 关键字实现的。在多线程环境下&#xff0c;当多个线程同时访问共享资源时&#xff0c;如果不进行同步控制&#xff0c;就会出现数据不一致、死锁等问题。为了保证多个线程之间的安全访问&#xff0c;需要…

【Git 入门教程】第六节、Git高级操作

Git是一种非常强大的分布式版本控制系统&#xff0c;可以帮助开发者轻松地管理和协调代码库。在本文中&#xff0c;我们将介绍一些Git高级操作&#xff0c;包括如何管理Git仓库、标签、子模块和忽略文件。 一、管理Git仓库 Git提供了许多命令来管理本地Git仓库。以下是一些常用…

利用文本描述替换万物(Inpaint-Anything-Description)

文章目录 引言安装Demo github&#xff1a; https://github.com/Atlas-wuu/Inpaint-Anything-Description 引言 前段时间看了万物分割SAM、文生图Stable Diffusion、开集检测Grounding DINO&#xff0c;它们之间可以互相补充&#xff0c;AIGC变得更加可控。Inpaint Anything将…

一文打通java中内存泄露

目录 前置知识 内存泄漏&#xff08;memory leak&#xff09; 内存溢出&#xff08;out of memory&#xff09; Java中内存泄露的8种情况 静态集合类 单例模式 内部类持有外部类 各种连接&#xff0c;如数据库连接、网络连接和IO连接等 变量不合理的作用域 改变哈希值 …