C++围棋程序实现报告

合集下载

围棋程序设计综合报告

围棋程序设计综合报告

围棋程序设计综合报告作者:赵翔学号:201103010002专业:机械工程及其自动化一、围棋软件设计思想首先,我将软件的功能细化,细化到单个功能,直到可以通过一个函数较轻松地实现为止。

然后,从函数功能构想函数结构,通过函数调用将不同功能组合起来,从而完成软件要求的功能。

二、程序设计方案下面我由main的调用顺序,来阐述各个函数的详细信息。

Link:用于构造链表,输入值为上一个结点,返回新建的结点。

输入为空,则返回链表头;Begin:将链表头赋值,即构建棋盘;Print:打印输入的棋局,可在链表记录的位置输出两个小翅,利用了转义字符;Cheese:其实是chess,就是下棋,输入空的棋局,步数统计、黑白子统计地址,和用户输入的落子位置,可将棋盘下好,并将参数传给make_scene,返回后,将统计值完成;Make_scene:完成棋局,判断下子位置的上下左右是否有对方的子,若有,进入search,返回后,将去掉的子数减去,将删除序列中子删去;Search:对输入的子上下左右进行搜索,若均非空,计入删除序列,对上下左右与本子相同的子,判断是否已搜过,若否,递归输入本函数,返回总子数,并通过地址返回删除序列;Save:用fwrite将结构体中保存的棋局和两个整形数写入文件;Lord:其实是load,读取之前保存的文件到新建的链表,之前先将目前的链表全部释放,然后将独到的链表至于最后一步,顺便统计步数统计、黑白子统计,以便用户继续下棋,或者复盘也可以;Help:对软件的部分行为进行解释,帮助用户更好的使用;Rescene:从头查看每一步棋局,利用结构体双向指针操作,可以很方便的实现该功能;除了以上函数,菜单中还有悔棋、结束、退出操作,由于过于简单,没有专门构造函数,退出直接引用系统函数,结束加到了循环条件里,对结果的判断直接用了下棋中对子数的统计,悔棋操作就是将链表回到之前一步,释放现在的空间。

三、结果分析与体会通过做函数,我充分认识到程序规范性的重要性。

C 围棋程序实现报告

C  围棋程序实现报告

一、软件背景介绍围棋是一项广有裨益的智力竞技运动,它集休闲娱乐、陶冶性情、修心养性于一身,是中华文化的瑰宝,是人类智慧的最高象征之一。

围棋经历了数千年,久盛不衰,且至今还在不断发展。

现在的人工智能科学研究在它面前显得很是稚嫩,因而值得将它作为重要的研究对象。

在人工智能领域内,博弈是很重要的一个研究分支。

通过对博弈的研究,可以解决很多实际问题,使计算机智能向人类智能迈进。

计算机国际象棋和计算机围棋一直是人工智能的热门课题,而围棋程序的编制被称作人工智能的“试金石”,是人工智能技术的一大难题,它将会在今后相当长的时期内哺育着人工智能科学的成长。

计算机围棋是计算机博弈研究的一个重要分支,是当前人工智能研究的热点之一,一直以来吸引着大量的研究人员,产生了较大的社会影响和学术影响。

由于围棋变化复杂、棋理深奥,是一种高智能的活动,因而围棋的计算机博弈设计难度较大,同时计算机围棋热点问题的研究为人工智能带来了崭新的方法和理论。

计算机围棋的研究和实现需要多门学科的知识交叉,至少会涉及到围棋、计算机、数学、生物、逻辑学、军事学、教育、心理学乃至哲学等领域,因此其发展具有重要的研究价值和应用价值。

本系统是基于C++编程语言的立足于“人―人”围棋对弈系统的设计与实现,具有围棋记谱、打谱、查看定式、最终评分等功能,是一个适宜在计算机上联网的“人―人”的对弈系统。

围棋胜负判断与局面分析功能子系统是围棋对弈系统的重要组成部分。

围棋胜负自动判断是一个实用的围棋对弈系统所应具有的功能。

在现实的围棋胜负判断中,往往需要一个裁判员通过做棋来判断棋局最终的胜负。

如果有一个客观、准确的围棋自动判断胜负系统,一方面可以省时省力,一方面可以做到客观公正。

但实现一个具有人(裁判员)一样的判断能力的胜负判断系统,存在着许多困难和挑战。

本系统通过建立棋局的记录来判断棋盘上每一点的归属,从而确定棋局中双方地域,故能够对提掉死子后的终局棋盘用中国规则判断胜负;通过建立棋子的影响模型、力学模型以及度量公式,将棋子向棋盘其它部分辐射的影响量化,从而判断对弈双方的影响领域。

C语言。围棋程序

C语言。围棋程序
cout<<" 选择难度(3):两个斜对角线都为X或O,则获胜。"<<endl;
cout<<" 输入必须为一个两位整数,如11,代表棋盘第一行第一列,输完后按回车键。"<<endl;
cout<<endl;
cout<<endl;
cout<<"简单---------1"<<endl;
{
bz=0;
}
else if(ab.cboard[1][1]=='o'&&ab.cboard[3][3]=='o'&&ab.cboard[5][5]=='o'&&ab.cboard[7][7]=='o'&&ab.cboard[9][9]=='o')
{
bz=0;
}
else if(ab.cboard[7][1]=='x'&&ab.cboard[7][3]=='x'&&ab.cboard[7][5]=='x'&&ab.cboard[7][7]=='x'&&ab.cboard[7][9]=='x')
{
bz=0;
}
else if(ab.cboard[5][1]=='x'&&ab.cboard[5][3]=='x'&&ab.cboard[5][5]=='x'&&ab.cboard[5][7]=='x'&&ab.cboard[5][9]=='x')

【报告】c五子棋实验报告

【报告】c五子棋实验报告

【关键字】报告c五子棋实验报告篇一:五子棋对战实验报告实验项目五子棋网络对战和聊天实验日期XX0406实验报告要求:一、实验目的:学习和使用socket编程,熟练软件开发二、实验原理:使用socket进行网络通信,java作为编程语言三、实验要求:编写五子棋程序可以实现联机网络对战,并且可以进行聊天四、实验步骤、结果(程序+注释+截图)及分析:首先拟定编程语言与开发方案,选择java语言,考虑到java可以跨平台运行,然后决定把这个程序拆分为客户端、服务器两个部分,每个部分再分成5个小的部分实现不同功能。

1、然后考虑使用java的swing包,创建ClientChessPanel类负责棋盘部分,包括判断输赢,使用数组chesses[i][j]记录棋盘上棋子的分布,对数组进行不同的赋值表示网格节点上无棋、黑棋、白棋;使用playChessHandler作为鼠标单击事件,单击事件调用Clientskt中的函数传送棋子坐标以及输赢信息。

drawChess函数画棋子,drawGrids画网格,gameOver判断棋盘棋子分布,输赢情况。

importjavax.swing.*;importjava.awt.*;;importChatOneToOneClient.Clientskt;classClientChessPanel extends JPanel{private static final long serialVersionUID = 1L;private int space=20; //网格间的距离private int grids=30; //棋盘的网格数private int radius=space/2; //棋的半径Clientsktskt;//当chesses[i][j]=0,表示网格节点(i,j)上无棋//当chesses[i][j]=1,表示网格节点(i,j)上放白棋//当chesses[i][j]=2,表示网格节点(i,j)上放黑棋privateint[][] chesses=new int[grids+1][grids+1];private intcurrColor=1; //当前棋的颜色privateMouseListenerplayChessHandler=new MouseAdapter(){public void mouseClicked(MouseEvent e){if(skt.reMouseGo()){int x=e.getX();int y=e.getY();//放一颗棋子if(x=0 && y=0)if(chesses[round(x)][round(y)]==0){chesses[round(x)][round(y)]=currColor;repaint(); //刷新图形skt.dataout("x:"+String.valueOf(round(x)));skt.dataout("y:"+String.valueOf(round(y)));skt.setMouseGo(false);if(gameOver(currColor)){skt.dataout("g:你输了");ClientMyDialog(skt.chat,"你赢了");;}currColor=currColor==1?2:1; //切换棋子的颜色}}}};public int round(float a){ //获得接近a的网格节点坐标float f=a/space;returnMath.round(f);}publicClientChessPanel(intspace,intgrids,Clientsktskt){ this.space=space;this.grids=grids;this.radius=space/2;this.skt=skt;setBackground(Color.BLUE);setSize(space*grids,space*grids);addMouseListener(playChessHandler);startChess();}public void startChess(){clearGrids(); //清空棋盘currColor=1;repaint(); //刷新图形private void clearGrids(){for(inti=0;i for(int j=0;j chesses[i][j]=0;}//画一颗棋子private void drawChess(Graphics g,intx,inty,int color){g.setColor(color==1?Color.GREEN:Color.BLACK);g.fillOval(x*space-radius,y*space-radius,radius*2,radius*2);}//画网格private void drawGrids(Graphics g){g.setColor(Color.DARK_GRAY);for(inti=0;i g.drawLine(0,i*space,grids*space,i*space);g.drawLine(i*space,0,i*space,grids*space);}}//接收对方下的棋坐标public void paintChess(intx,int y){if(x=0 && y=0){if(chesses[x][y]==0){chesses[x][y]=currColor;currColor=currColor==1?2:1; //切换棋子的颜色skt.setMouseGo(false);skt.setMouseGo(true);repaint(); //刷新图形}}}//判断游戏是否结束publicbooleangameOver(intgameOver){int five=0;//用于判断是否有连续5个子for(inti=0;i for(int j=0;j if(chesses[i][j]==gameOver){five++;for(in(本文来自:小草范文网:c五子棋实验报告)t k=1;k if(chesses[i][j+k]==gameOver){five++;if(five==5){return true;}else{five=1;k=5;}}for(int k=1;k if(chesses[i+k][j]==gameOver){ five++;if(five==5){return true;}}else{five=1;k=5;}}for(int k=1;k if(chesses[i+k][j+k]==gameOver){ five++;if(five==5){return true;}}else{five=1;k=5;}}for(int k=1;k4;k++){//左斜向比较if(chesses[i+k][j-k]==gameOver){five++;if(five==5){return true;}}else{five=1;}}}}five=0;}return false;}public void paintComponent(Graphics g){ //覆盖paintComponent()方法super.paintComponent(g); //必须先调用父类的方法drawGrids(g); //画网格for(inti=0;i for(int j=0;j if(chesses[i][j]!=0)drawChess(g,i,j,chesses[i][j]); //画棋子}}2、ClientComponentPopupMenu类主要负责聊天的部分,使用JTextField并且对其添加单击事件以及鼠标事件,可以实现文本的剪贴、复制粘贴等功能。

c 五子棋实验报告

c  五子棋实验报告

c 五子棋实验报告
C五子棋实验报告
引言
五子棋是一种古老的策略游戏,它既考验了玩家的思维能力,又具有很高的娱乐性。

在本次实验中,我们将利用C语言编程,设计一个简单的五子棋游戏,并对其进行实验测试。

实验目的
1. 学习使用C语言进行游戏开发;
2. 设计并实现一个简单的五子棋游戏;
3. 对游戏进行功能测试和性能评估。

实验方法
1. 使用C语言编写五子棋游戏的程序代码;
2. 设计游戏界面和用户交互功能;
3. 实现游戏规则和胜负判定功能;
4. 进行功能测试和性能评估。

实验结果
经过实验,我们成功地设计并实现了一个简单的五子棋游戏。

游戏具有清晰的界面和简单的操作方式,玩家可以轻松上手。

在功能测试中,游戏能够正确判定胜负,且没有出现明显的bug。

在性能评估中,游戏在常见的操作系统上都能够流畅运行,响应速度较快。

实验结论
通过本次实验,我们学习到了使用C语言进行游戏开发的基本方法和技巧。


们成功地设计并实现了一个简单的五子棋游戏,并对其进行了功能测试和性能
评估。

实验结果表明,我们的游戏具有良好的稳定性和性能表现,能够满足玩
家的基本需求。

展望
在未来,我们可以进一步完善游戏的功能和界面设计,增加更多的游戏模式和
挑战性。

我们也可以考虑将游戏移植到其他平台上,以提供更广泛的游戏体验。

同时,我们还可以利用更先进的技术和算法,进一步优化游戏的性能和用户体验。

总之,我们将继续努力,不断改进和完善我们的五子棋游戏,为玩家提供
更好的游戏体验。

C语言编写的与电脑下棋程序代码

C语言编写的与电脑下棋程序代码

#include<iostream>using namespace std;void check(int i,int j); //检查每条直线上的各方棋子的数量int other(int b,int c);void check_win(); //检查是否胜利void begin(char ch);void computer(); //电脑下棋void user(); //用户下棋int a[4][4],deep;int line[3][3][2]; //全局变量,用来存放每条直线上的各方棋子数!//第一维下标表示是行列还是对角线,第二维下标表示第几条直线//第三维下标表示各方的棋子数!void main(){char ch;cout<<"欢迎与本机下#字棋!您的棋子将用#表示,电脑的棋子用X表示\n请选择先后手,输入u则您先手,输入c则电脑先手!(小写)\n"<<endl;do{cin>>ch;if(ch!='u'&&ch!='c') cout<<"您输入的数据不合法,请重新输入!"<<endl;}while(ch!='u'&&ch!='c'); //非法处理if(ch=='u') cout<<"您选择了您先手!\n"<<endl;else if(ch=='c') cout<<"您选择了电脑先手\n"<<endl;begin(ch);}void begin(char ch){int i,j,k;a[1][1]=1;cout<<"\n 1 | 2 | 3 \n ——————\n 4 | 5 | 6 \n ——————\n 7 | 8 | 9for(i=1;i<4;i++)for(j=1;j<4;j++){if(j==1)if(i==1);else a[i][j]=a[i-1][3]+1;else a[i][j]=a[i][j-1]+1;} //初始化棋盘for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)line[i][j][k]=0;deep=0;if(ch=='u') user();else computer();}void computer(){int i,j,flag=0,m; //flag判断是否落子for(i=0;i<3;i++)for(j=0;j<3;j++){if (line[i][j][0]==2&&line[i][j][1]==0&&flag==0){m=other(i,j);if(m%3==0) {a[m/3][3]=40;check(m/3,3);}else {a[m/3+1][m%3]=40; check(m/3+1,m%3);} //40是#的ASCII码减48flag=1;} //当某条直线上用户有两棋子而我方无棋子时,在该直线的另一点落子if (line[i][j][1]==2&&line[i][j][0]==0&&flag==0){m=other(i,j);if(m%3==0) {a[m/3][3]=40;check(m/3,3);}else {a[m/3+1][m%3]=40; check(m/3+1,m%3);} //当某条直线上我方有两棋子而对方无棋子时,在该直线的另一点落子flag=1;}if (line[i][j][1]==1&&line[i][j][0]==0&&flag==0){m=other(i,j);if(m%3==0) {a[m/3][3]=40;check(m/3,3);}else {a[m/3+1][m%3]=40; check(m/3+1,m%3);} //当某条直线上我方有一棋子而对方无棋子时,在该直线的另一点落子flag=1;}}if(flag==0)if (a[2][2]==5){a[2][2]=72;flag=1;check(2,2);} //优先下第5个位置else{for(i=2;i<9&&flag==0&&a[i][j]==(i-1)*3+j;i+=2){if(i%3==0) {a[i/3][3]=40;check(i/3,3);}else {a[i/3+1][i%3]=40; check(i/3+1,i%3);}flag=1;} //2,4,6,8其次for(i=1;i<9&&flag==0&&a[i][j]==(i-1)*3+j;i+=2){if(i%3==0) {a[i/3][3]=40;check(i/3,3);}else {a[i/3+1][i%3]=40; check(i/3+1,i%3);}flag=1;} //1,3,7,9再次for(i=1;i<=3;i++){cout<<" ";for(j=1;j<=3;j++)cout<<" "<<char(a[i][j]+48)<<" |";cout<<"\n ——————"<<endl;}deep++;if(flag==1) user();else check_win();}void user(){int down;cout<<"\n轮到您下了,请输入您要下的棋子位置:"<<endl;do{cin>>down;if(down<1||down>9)cout<<"数字不合法,请重新输入\n"<<endl;if ((down%3==0&&a[down/3][3]!=down)||(down%3!=0&&a[down/3+1][down%3]!=down)) cout<<"您所输入的位置已经有棋子了,请重新输入\n"<<endl;}while(down<1||down>9||((down%3==0&&a[down/3][3]!=down)||(down%3!=0&&a[down/3+ 1][down%3]!=down)));//判断输入是否异常if(down%3==0) {a[down/3][3]=-13; check(down/3,3);}else {a[down/3+1][down%3]=-13;check(down/3+1,down%3);} //-13是X的ASCII码减48deep++;computer();}int other(int b,int c)int i,m;if(b<2){if (b==0)m=3*c+1;if (b==1)m=c+1;for(i=m;i<m+3;i++){if(i%3==0)if(a[i/3][3]==i) return i;else;else if(a[i/3+1][i%3]) return i;}} //水平与垂直直线的情况 if(b==2){if(c==0){if(a[1][1]==1) return 1;if(a[2][2]==5) return 5;if(a[3][3]==9) return 9;}if(c==1){if(a[1][3]==3) return 3;if(a[2][2]==5) return 5;if(a[3][1]==7) return 7;}} //对角线的情况}void check(int i,int j){if(a[i][j]==-13)line[0][i-1][0]++;line[1][j-1][0]++;if((i==1&&j==1)||(i==3&&j==3)||(i==2&&j==2))line[2][0][0]++;if((i==1&&j==3)||(i==3&&j==1)||(i==2&&j==2))line[2][1][0]++;}if(a[i][j]==40){line[0][i-1][1]++;line[1][j-1][1]++;if((i==1&&j==1)||(i==3&&j==3)||(i==2&&j==2))line[2][0][1]++;if((i==1&&j==3)||(i==3&&j==1)||(i==2&&j==2))line[2][1][1]++;}check_win();}void check_win(){int i,j,k;bool end=false;char ch;for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<2;k++)if(line[i][j][k]==3){if(k==1) cout<<"您失败了,电脑获得了胜利"<<endl;if(k==0) cout<<"恭喜您,您获得了胜利"<<endl;end=true;}if(deep>=9) {cout<<"和棋!"<<endl;end=true;}if(end){cout<<"\n您是否继续是输入Y,按其余任意键结束本游戏!:"<<endl;cin>>ch;if(ch!='y') exit(0);else{cout<<"\n请选择先后手,输入U则您先手,输入C则电脑先手!\n"<<endl;do{cin>>ch;if(ch!='u'&&ch!='c') cout<<"您输入的数据不合法,请重新输入!"<<endl;}while(ch!='u'&&ch!='c'); //非法处理if(ch=='u') cout<<"您选择了您先手!\n"<<endl;else if(ch=='c') cout<<"您选择了电脑先手\n"<<endl;begin(ch);}}}。

c语言围棋程序代码

c语言围棋程序代码

c语言围棋程序代码以下是一个简单的C语言围棋程序的示例代码:```c#include <stdio.h>#define BOARD_SIZE 9enum Stone {EMPTY,BLACK,WHITE};enum Stone board[BOARD_SIZE][BOARD_SIZE];void init_board() {for (int i = 0; i < BOARD_SIZE; i++) {for (int j = 0; j < BOARD_SIZE; j++) {board[i][j] = EMPTY;}}}void print_board() {for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) { switch (board[i][j]) {case EMPTY:printf(".");break;case BLACK:printf("X");break;case WHITE:printf("O");break;}}printf("\n");}}int main() {init_board();print_board();return 0;}```这个程序定义了一个9x9的围棋棋盘,使用`enum Stone`枚举类型表示棋盘上的三种棋子状态:空、黑子、白子。

`init_board()`函数用于初始化棋盘,将所有位置都设为EMPTY。

`print_board()`函数用于打印当前棋盘状态。

在`main()`函数中,首先调用`init_board()`初始化棋盘,然后调用`print_board()`打印初始棋盘状态。

你可以根据需要进一步扩展和完善这个程序,例如添加下子功能、判断胜负等等。

c语言围棋程序代码

c语言围棋程序代码

c语言围棋程序代码你可以参考以下围棋程序代码,希望对你有所帮助:```cpp// 这个实现 vector 首尾颠倒template< typename Vector_Reverse>void Reserve_Vector(vector< Vector_Reverse> & arr){for (int i = 0; i < (arr.size() >> 1); i++){Vector_Reverse temp = arr(i);arr(i) = arr(arr.size() - i - 1);arr(arr.size() - i - 1) = temp;}}// 这个是函数模板template< typename VectorInclude>bool ifNotInVector(vector< VectorInclude> arr, VectorInclude num){for (VectorInclude i : arr){if (i == num)return false;}return true;}// 这个实现判断两个 vector 是否相等template< typename VectorEqual>bool ifTwoVectorEqual(vector< VectorEqual> arr, vector< VectorEqual> ano){if (arr.size() != ano.size())return false;for (int i = 0; i < arr.size(); i++){if (arr(i) != ano(i))return false;}return true;}MapPoint地图点的类,由 indexX 存放列数,indexY 存放行数,有 PathDir 枚举类型枚举四个方向,能通过 MapPoint getDirPoint(PathDir turn) 这个函数获得四个方向的点,这个函数长这样MapPoint getDirPoint(PathDir turn){switch (turn){case path_up:return MapPoint(this-> indexX, this-> indexY - 1);break;case path_down:return MapPoint(this-> indexX, this-> indexY + 1);break;case path_left:return MapPoint(this-> indexX - 1, this-> indexY);break;case path_right:return MapPoint(this-> indexX + 1, this-> indexY);break;default:break;}}同时这个类也用于保存 BoundingBox 类的坐标,因为 easyx 里的每个点都是整型,所以保存的坐标也是整型。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、软件背景介绍围棋是一项广有裨益的智力竞技运动,它集休闲娱乐、陶冶性情、修心养性于一身,是中华文化的瑰宝,是人类智慧的最高象征之一。

围棋经历了数千年,久盛不衰,且至今还在不断发展。

现在的人工智能科学研究在它面前显得很是稚嫩,因而值得将它作为重要的研究对象。

在人工智能领域内,博弈是很重要的一个研究分支。

通过对博弈的研究,可以解决很多实际问题,使计算机智能向人类智能迈进。

计算机国际象棋和计算机围棋一直是人工智能的热门课题,而围棋程序的编制被称作人工智能的“试金石”,是人工智能技术的一大难题,它将会在今后相当长的时期内哺育着人工智能科学的成长。

计算机围棋是计算机博弈研究的一个重要分支,是当前人工智能研究的热点之一,一直以来吸引着大量的研究人员,产生了较大的社会影响和学术影响。

由于围棋变化复杂、棋理深奥,是一种高智能的活动,因而围棋的计算机博弈设计难度较大,同时计算机围棋热点问题的研究为人工智能带来了崭新的方法和理论。

计算机围棋的研究和实现需要多门学科的知识交叉,至少会涉及到围棋、计算机、数学、生物、逻辑学、军事学、教育、心理学乃至哲学等领域,因此其发展具有重要的研究价值和应用价值。

本系统是基于C++编程语言的立足于“人―人”围棋对弈系统的设计与实现,具有围棋记谱、打谱、查看定式、最终评分等功能,是一个适宜在计算机上联网的“人―人”的对弈系统。

围棋胜负判断与局面分析功能子系统是围棋对弈系统的重要组成部分。

围棋胜负自动判断是一个实用的围棋对弈系统所应具有的功能。

在现实的围棋胜负判断中,往往需要一个裁判员通过做棋来判断棋局最终的胜负。

如果有一个客观、准确的围棋自动判断胜负系统,一方面可以省时省力,一方面可以做到客观公正。

但实现一个具有人(裁判员)一样的判断能力的胜负判断系统,存在着许多困难和挑战。

本系统通过建立棋局的记录来判断棋盘上每一点的归属,从而确定棋局中双方地域,故能够对提掉死子后的终局棋盘用中国规则判断胜负;通过建立棋子的影响模型、力学模型以及度量公式,将棋子向棋盘其它部分辐射的影响量化,从而判断对弈双方的影响领域。

论文主要介绍了围棋对弈系统中胜负判断与局面分析功能子系统具有的功能,论述了子系统的开发和实现的过程。

该围棋游戏的主界面如图1。

图1 围棋主界面二、核心算法思想该围棋软件主要是由以下三种算法组成的:1、使每个棋子周围产生某种影响,这种影响随着距离的增加而减少,用一定的公式计算叠加种影响,以判断形势和估计着点的价值。

这与围棋的棋理相通,即对于每个棋子可估算其“势力”。

此中就有著名的“气位”理论。

2、建立模式库,贮存了大量模式(定式、棋形等),以供匹配。

这其实涉及到围棋的许多棋谚与棋理。

如“二子头必扳”、“镇以飞应”、“断从一边长”、三子正中、点方等等。

这些都是根据围棋的具体情况而设计的。

3、对目标明确的局部,用人工智能中的搜索法探求其结果。

(一)围棋局面分析功能的实现这里定义了Stone的数据结构,用于记录每一点与棋盘上已落棋子的距离和受到的影响值,定义如下:Public Type StoneValue As IntegerDistance As IntegerEnd Type需要定义显示地域时的棋谱Public Map(1 To 19, 1 To 19) As Stone ,用于记录最后的累加影响。

其中Map上每一点Map(i,j)的Distance与value的关系为:Value = 2 的 (6 - Distance)次方。

Map(i,j)的最终影响要通过计算影响模型,递减定律以及反射定律,经过度量公式计算,大于定值A的点显示为黑棋地域,小于-A的点显示为白棋地域。

(二)影响模型由于棋盘上的每个棋子都要对盘面发出影响,设黑棋影响为正,白棋影响为负。

棋盘上的每一点要受到多个棋子的累加影响,其中,受到该点最近的棋子影响最大,依次递减。

设这影响在棋子的紧邻(距离为1)为最大值32,并随距离增加而按比例衰减,衰减因子为1/2。

就是距离每增加1时影响值减半。

此时一黑子对其周围辐射的影响如图2。

11 2 11 2 4 2 11 2 4 8 4 2 11 2 4 8 16 8 4 2 11 2 4 8 16 32 16 8 4 2 11 2 4 8 16 32 64 32 16 8 4 2 11 2 4 8 16 32 16 8 4 2 11 2 4 8 16 8 4 2 11 2 4 8 4 2 11 2 4 2 11 2 11图2 系统使用的影响模型影响模型的实现,采用循环嵌套,对一已落的棋子(i,j),计算其对周边的影响,定义变量row,column,对于满足i-6<=row<=i+6, i-6<=column<=i+6的点,(row,column)的距离distance为︱row-i︱+︱column-j︱,并记录到显示棋谱Map(19,19)中。

(三)力学模型棋盘上的每一个棋子,都向周围四个方向发出影响,通过这种影响实现对空点的占领和棋子之间的相互作用,这种影响可以被视为一种控制力,沿四个方向大小相等,而黑白棋子产生的控制力符号相反。

控制力产生后,沿它的方向向前传播,其传播方式遵守如下规律:1、递减规律控制力遇到一个点后,力的大小被减弱,符号方向不变地继续向前传播。

如果遇到空点,减弱后的控制力变为原来的一个常数倍(取1/2),该常数被称为传播率;如果遇到有子点,沿原方向的控制力消减。

棋子(i,j)在传播过程中,如遇到另一棋子(m,n),则同方向的距离distance+2,即受到的影响值减1/4倍。

2、反射定律由于在围棋中边角更容易受到棋子的影响,有“金角银边”之称。

故在实现时设计了反射定律。

控制力到达棋盘边缘后,会被反射回来,该反射力与原控制力方向相反,符号相同,大小为原控制力的一个常数倍,该常数被称为反射率。

实现时,棋子(i,j)在传播过程中,利用row,column双重循环,如遇到row=1或19,则同方向的距离distance-︱row-i︱;如遇到column=1或19,则同方向的距离distance-︱column-j︱。

每一个点都受到四个方向的控制力的作用,任一方向的控制力的大小是这个点所受这个方向所有控制力的代数和。

在实际计算时,取:(1)任意棋子产生的初始控制力的大小为64;(2)黑子的影响为正、白子的影响为负;(3)传播率为1/2;(4)反射率为1;3、度量公式在得到任一棋盘状态下个空点影响的分布图后,可以由这些影响值经过计算得到一些棋盘状态的深层信息,一些常用的度量公式如下。

设一个点受到的四个控制力大小为:向上F0,向右F1,向下F2,向左F3。

总力:F=F0+F1+F2+F3表示一个点受到某一方影响的度量。

F﹥0:受黑的影响强一些;F﹤0:受白的影响强一些;F=0:双方的影响基本平衡。

4、判定双方的势力范围对于每一点,它受到的总控制力F=F0+F1+F2+F3,当|F|大于某一数值n时,将其显示为地域。

当F﹥0时受黑的影响强一些,该点能被黑方所控制,作为黑方实地,显示为黑方地域,反之,为白棋的势力范围。

在显示中规定:如果该点所受四个方向的力均大于0,且F大于20,则该点为黑方势力范围。

对于白方的势力范围有类似的判断规则。

(四)围棋胜负的判断方法双方下子完毕的棋局,计算胜负采用数子法。

先将双方死子全部清理出盘外,然后对一方的活棋(包括活棋围住的点)以子为单位进行计数。

双方活棋之间的空点各得一半,一个点即为一子。

胜负的基准以棋局总点数的一半180又1/2点为归本数。

凡一方活棋与所属空点的总和大于此数者为胜,小于此数者为负,等于此数者为和。

三、核心算法流程图(一)判定双方的势力范围对于每一点,它受到的总控制力F=F0+F1+F2+F3,当|F|大于某一数值n时,将其显示为地域。

当F﹥0时受黑的影响强一些,该点能被黑方所控制,作为黑方实地,显示为黑方地域,反之为白棋的势力范围。

在显示中规定:如果该点所受四个方向的力均大于0,且F大于20,则该点为黑方势力范围。

对于白方的势力范围有类似的判断规则。

双方的势力范围的实现流程图如图3。

图3 局面分析实现流程图(二)判断围棋输赢这里定义了Item的数据结构,用于记录每一枚棋子的颜色及搜索的状态:Public Type ItemsValue As IntegerChecked As BooleanEnd Type定义终局棋谱数组:Public m_GameOverMap(1 To 19, 1 To 19) As Items,终局的每一结点存储为Item结构,记录每一点的归属。

对待盘棋局(用m_Map(19,19)记录)上每一点用循环扫描,记录每一点是哪一方的领域。

下图为判断围棋胜负的流程图。

图 4 胜负判断实现流程图四、源代码下面给出的是实现联网对战游戏的源代码:#include "MyStack.h"#include "MyList.h"#include "MyOutFunction.h"#pragma once#include <string>using namespace std;#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000struct point{int p_x; //x坐标,1-19间的整数int p_y; //y坐标,1-19间的整数int color; //所放棋子颜色,1为黑,2为白};struct _node{point data;_node* next;_node* pre;};class CChessPos{public:BOOL visit_for_DeadOrLive; //访问标识,用于递归算法BOOL visit_for_DeleteDead;CRect chessman(CPoint point); //该位置所在矩形区域int nFlag; //该位置状态标识CPoint point; //该位置坐标CChessPos* pLeft; //指向该位置的四个邻接点CChessPos* pRight;CChessPos* pTop;CChessPos* pBottom;CChessPos();virtual ~CChessPos();};#include "mscomm.h"#include "SelectComm.h"#include "ChessPos.h"#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000const int DIE = 0; //表示空位或死棋const int BLACK = 1; //黑棋const int WHITE = 2; //白棋const int EDGE = 3; //边界以外class MyList{public:void init();MyList();virtual ~MyList();_node* head;_node* now;_node* tail;int size;void add(_node* newNode);void add(int x, int y,int color);bool isEmpty();void printList(); //根据函数format定义的格式遍历链表,step记录结点遍历到了第几个结点void printList(void(*format)(void* e,void* steptag),int step);void del(); //删除链表最后一个元素void clearList(); //清空链表bool searchele(int x, int y);//遍历链表};struct _state//保存棋盘中每个格子的临时状态,以判别处于该位置的棋子是否能存活{int x; //在棋盘中的横坐标int y; //在棋盘中的纵坐标int fangxiang;int color;int footprint;int dead; //处于此格子的棋子可能死亡};struct _statenode{_state s;_statenode* next;};class MyStack{public:_statenode* head;int size; //堆栈大小MyStack();virtual ~MyStack();void init(); //初始化void push(_state* s); //入栈_state* pop(); //出栈bool isEmpty(); //判断是否为空void print(); //输出};};ON_COMMAND(ID_APP_ABOUT, OnAppAbout) //ClassWizard将添加和删除映射宏。

相关文档
最新文档