五子棋源码实验报告及人机对战说明

合集下载

五子棋实验报告(含代码)

五子棋实验报告(含代码)

实验报告实验一五子棋游戏北方工业大学 2013级计算机技术米鹏一、实验原理及方法五子棋游戏开发借用Visual Studio 2012软件开发平台,选用C#语言进行编写。

整体程序主要分为三部分:界面操作部分、AI逻辑部分和棋子定点分析部分。

1、界面操作部分界面操作部分代码主要针对图像呈现、对应矩阵存储、下棋过程控制等可见的操作环节进编写。

同时负责整个程序的初始化工作。

图像呈现采用C#中Graphics进行绘制。

棋盘被划分为15行15列,每个划分出的小方格均为30*30的正方形,棋盘可操作的范围规定在(20,20)、(460,460)两点的确定的正方形区域内。

通过鼠标左击来确定下子地点。

程序会根据鼠标鼠标点击的位置进行计算,计算得到时对应矩阵的行列,之后再改变对应矩阵的内容后,在通过行列值乘以小方格边长计算得到在显示区域中的具体位置,再稍加变动后画到显示区域中。

以X点坐标为例,下面是计算X(Column)的流程图:在对应矩阵存储方面,后面AI逻辑和棋子分析所用到的矩阵都是来源这里。

同时AI 逻辑和棋子分析不能去修改对应矩阵内容。

图像呈现点的位置、重绘的根据都是来源这里。

在下棋过程控制方面采用信号亮的机制,当操作者下过后,根据信号AI会立即计算将要下点的位置同时改变信号亮变量。

当AI下过棋子后,由于信号亮的的限制就等待操作者去下棋,同时改变信号亮变量内容。

AI和操作者的所有下子、修改矩阵、显示棋子的过程都是统一的。

在每一盘游戏开始时程序会对一些重要的变量进行初始化这里包括矩阵、信号亮、第一步棋子颜色、呈现图像等内容进行初始化。

同时AI会在棋盘中央下第一子。

2、AI逻辑部分AI逻辑部分算是整个程序策略的灵魂。

其中的一些关键性判别的前后关系将影响AI 的下棋的结果。

同时加大和降低AI的难度也是这里。

下面是我设计的策略过程:从下棋者的考虑角度进行考虑,尽可能保证每一次下子都是有必要的、都是在情理当中的。

我所设计的策略并不是完整,漏洞在与没有考虑三棋子连续的情况。

人工智能五子棋实验报告

人工智能五子棋实验报告

题目:智能五子棋游戏一、实验目的理解和掌握博弈树的启发式搜索过程和α-β减枝技术,能够用某种程序语言开发一个五子棋博弈游戏。

二、实验要求(1)设计一个15行15列棋盘,要求自行给出估价函数,按极大极小搜索方法,并采用α-β减枝技术。

(2)采用人机对弈方式,对弈双方设置不用颜色的棋子,一方走完后,等待对方走步,对弈过程的每个棋局都在屏幕上显示出来。

当某一方在横、竖或斜方向上先有5个棋子连成一线时,该方为赢。

(3)提交一篇实验论文,以及完整的软件(包括源程序和可可执行程序)和相关文档。

三、实验原理①估价函数的设计:下子后,求在该点的所有8个方向上4格之内的所有的没有阻隔的白子的和加上没有阻隔的黑子的数目之和,和为估价函数的值。

直观来说就是,如果在该点下子后连成同颜色的棋子越多,该点的估价值越大,同时阻挡另一种颜色的棋子越多,估价值也越大。

②判断是否有一方胜出:设计is_win函数,在每一次下子后检查是否是终局(一方胜出或者棋盘下满和局)。

对于棋盘上每一个已经下了棋子的点,检查其4个方向上是否有连续5颗同颜色的棋子,若有,则有一方胜出。

③寻找候选点,用于建立博弈树:对于棋盘上每一个还没有下子的点,测试其附近8个点是否已经下了棋子,若有,把该点加入候选点。

④搜寻最佳着点:根据候选点建立3层的博弈树,再利用估价函数对节点进行比较,得出最佳着点。

四、代码人主要代码public void refreshMax(int n){switch(n){case 1:{ //更新预测棋盘1最大值及其坐标maxValue1=0;number1=0;for(int i=0;i<size;i++){for(int j=0;j<size;j++){if(preBoard1[i][j]>maxValue1){maxX1.clear();maxY1.clear();maxX1.add(i);maxY1.add(j);number1=1;}else if(preBoard1[i][j]==maxValue1){maxX1.add(i);maxY1.add(j);number1++;}}}break;}case 2:{ //更新预测棋盘2最大值及其坐标maxValue2=0;number2=0;for(int i=0;i<size;i++){for(int j=0;j<size;j++){if(preBoard2[i][j]>maxValue2){maxX2.clear();maxY2.clear();maxX2.add(i);maxY2.add(j);number2=1;}else if(preBoard2[i][j]==maxValue2){maxX2.add(i);maxY2.add(j);number2++;}}}break;}case 3:{ //更新预测棋盘3最大值及其坐标maxValue3=0;number3=0;for(int i=0;i<size;i++){for(int j=0;j<size;j++){if(preBoard3[i][j]>maxValue3){maxX3.clear();maxY3.clear();maxX3.add(i);maxY3.add(j);number3=1;}else if(preBoard3[i][j]==maxValue3){maxX3.add(i);maxY3.add(j);number3++;}}}break;}case 4:{ //更新预测棋盘4最大值及其坐标maxValue4=0;number4=0;for(int i=0;i<size;i++){for(int j=0;j<size;j++){if(preBoard4[i][j]>maxValue4){maxX4.clear();maxY4.clear();maxX4.add(i);maxY4.add(j);number4=1;}else if(preBoard4[i][j]==maxValue4){maxX4.add(i);maxY4.add(j);number4++;}}}break;}case 5:{ //更新预测棋盘5最大值及其坐标maxValue5=0;number5=0;for(int i=0;i<size;i++){for(int j=0;j<size;j++){if(preBoard5[i][j]>maxValue5){maxX5.clear();maxY5.clear();maxX5.add(i);maxY5.add(j);number5=1;}else if(preBoard5[i][j]==maxValue5){maxX5.add(i);maxY5.add(j);number5++;}}}break;}case 6:{ //更新预测棋盘6最大值及其坐标maxValue6=0;number6=0;for(int i=0;i<size;i++){for(int j=0;j<size;j++){if(preBoard6[i][j]>maxValue6){maxX6.clear();maxY6.clear();maxX6.add(i);maxY6.add(j);number6=1;}else if(preBoard6[i][j]==maxValue6){maxX6.add(i);maxY6.add(j);number6++;}}}break;}case 7:{ //更新预测棋盘7最大值及其坐标maxValue7=0;number7=0;for(int i=0;i<size;i++){for(int j=0;j<size;j++){if(preBoard7[i][j]>maxValue7){maxX7.clear();maxY7.clear();maxX7.add(i);maxY7.add(j);number7=1;}else if(preBoard7[i][j]==maxValue7){maxX7.add(i);maxY7.add(j);number7++;}}}break;}}}AI主要代码public void refreshMax(int n){switch(n){maxValue1=0;number1=0;for(int i=0;i<size;i++){for(int j=0;j<size;j++){if(preBoard1[i][j]>maxValue1){maxValue1=preBoard1[i][j];maxX1.clear();maxY1.clear();maxX1.add(i);maxY1.add(j);number1=1;}else if(preBoard1[i][j]==maxValue1){maxX1.add(i);maxY1.add(j);number1++;}}}break;}maxValue2=0;number2=0;for(int i=0;i<size;i++){for(int j=0;j<size;j++){if(preBoard2[i][j]>maxValue2){maxValue2=preBoard2[i][j];maxX2.clear();maxY2.clear();maxX2.add(i);maxY2.add(j);number2=1;}else if(preBoard2[i][j]==maxValue2){maxX2.add(i);maxY2.add(j);number2++;}}}break;}maxValue3=0;number3=0;for(int i=0;i<size;i++){for(int j=0;j<size;j++){if(preBoard3[i][j]>maxValue3){maxValue3=preBoard3[i][j];maxX3.clear();maxY3.clear();maxX3.add(i);maxY3.add(j);number3=1;}else if(preBoard3[i][j]==maxValue3){maxX3.add(i);maxY3.add(j);number3++;}}}break;}maxValue4=0;number4=0;for(int i=0;i<size;i++){for(int j=0;j<size;j++){if(preBoard4[i][j]>maxValue4){maxValue4=preBoard4[i][j];maxX4.clear();maxY4.clear();maxX4.add(i);maxY4.add(j);number4=1;}else if(preBoard4[i][j]==maxValue4){maxX4.add(i);maxY4.add(j);number4++;}}}break;}maxValue5=0;number5=0;for(int i=0;i<size;i++){for(int j=0;j<size;j++){if(preBoard5[i][j]>maxValue5){maxValue5=preBoard5[i][j];maxX5.clear();maxY5.clear();maxX5.add(i);maxY5.add(j);number5=1;}else if(preBoard5[i][j]==maxValue5){maxX5.add(i);maxY5.add(j);number5++;}}}break;}maxValue6=0;number6=0;for(int i=0;i<size;i++){for(int j=0;j<size;j++){if(preBoard6[i][j]>maxValue6){maxValue6=preBoard6[i][j];maxX6.clear();maxY6.clear();maxX6.add(i);maxY6.add(j);number6=1;}else if(preBoard6[i][j]==maxValue6){maxX6.add(i);maxY6.add(j);number6++;}}}break;}maxValue7=0;number7=0;for(int i=0;i<size;i++){for(int j=0;j<size;j++){if(preBoard7[i][j]>maxValue7){maxValue7=preBoard7[i][j];maxX7.clear();maxY7.clear();maxX7.add(i);maxY7.add(j);number7=1;}else if(preBoard7[i][j]==maxValue7){maxX7.add(i);maxY7.add(j);number7++;}}}break;}}}五、感想通过这个试验,我对估价函数,极大极小搜索方法,α-β减枝技术有了更全面的认识,对它们的运用也更加熟练。

五子棋程序实习报告

五子棋程序实习报告

五子棋程序实习报告一、实习背景及目的近期,我通过五子棋程序的实习,深入了解了五子棋的规则和算法,并成功编写了一个五子棋程序。

本次实习的目的是为了提高我的编程能力和逻辑思维能力,同时了解人工智能在棋类游戏中的应用。

二、五子棋规则及算法分析五子棋是一种两人对弈的棋类游戏,游戏的目标是在棋盘上形成连续的五个棋子。

棋盘通常为15×15的网格,每个玩家轮流在空格中放置自己的棋子。

五子棋的算法主要包括两种:一种是基于搜索的算法,如极大极小值搜索和启发式搜索;另一种是基于机器学习的算法,如蒙特卡洛树搜索和深度学习。

三、程序设计及实现在本次实习中,我选择了基于极大极小值搜索的五子棋算法,并使用Python语言进行程序设计。

程序的主要功能包括棋盘的显示、玩家的输入和计算机的智能下棋。

首先,我使用类来表示棋盘,每个棋盘对象包含一个15×15的二维数组,用于存储棋子的位置。

同时,我还定义了一个常量类,用于存储棋子的颜色和空格的表示。

接下来,我实现了一个玩家输入的类,玩家可以通过该类来选择下棋的位置。

为了简化输入过程,我使用了一个简单的文本界面,玩家只需输入坐标即可。

最后,我实现了一个计算机下棋的类,该类使用了极大极小值搜索算法。

具体实现过程如下:1. 将棋盘划分为多个可能的获胜区域,例如横线、竖线和斜线。

2. 对于每个获胜区域,计算计算机和玩家在该区域获胜的概率。

3. 使用极大极小值搜索算法,选择最优的落子位置。

四、实习心得通过本次五子棋程序的实习,我对五子棋的规则和算法有了更深入的了解,同时也提高了我的编程能力和逻辑思维能力。

在程序设计过程中,我遇到了很多问题,如棋盘的表示、搜索算法的实现等,通过查阅资料和不断调试,我最终成功解决了这些问题。

此外,通过本次实习,我也了解到了人工智能在棋类游戏中的应用。

目前,深度学习等算法在棋类游戏中取得了显著的成果,例如AlphaGo在围棋领域的突破。

未来,我相信人工智能将在更多棋类游戏中发挥重要作用。

五子棋人机博弈实验报告

五子棋人机博弈实验报告

五子棋人机博弈实验报告目录一(课程设计目的............................................. 2 二(课程设计要求............................................. 2 三(课程设计内容............................................. 2 四(课程设计思想............................................. 2 五(系统实现 (2)设计平台 (2)数据结构设计 (3)程序流程图设计 (3)主要算法设计 (4)程序调试及运行结果.............................. 4 六(课程设计总结............................................. 5 七(参考资料................................................... 6 八(附录:五子棋博弈算法源代码 (7)1一( 课程设计目的通过上学期学习的《人工智能》学科,运用推理技术、搜索方法和决策规划和博弈树设计五子棋人机博弈系统,以此进一步深化对理论知识技术的了解,培养学生编程能力以及实践水平。

二(课程设计要求通过本次课程设计要求学生掌握以下内容:1.深入了解博弈树和alpha-beta剪枝算法。

2.设计出适合五子棋算法的启发式函数。

3.熟练掌握启发式的搜索方法。

三(课程设计内容本系统实现的是五子棋博弈算法,运用java语言实现了图形用户界面,方便用户使用。

算法采用了博弈算法和启发式函数进行搜索,人机对弈可自动判断输赢,结束后可重新开局。

四(课程设计思想本系统实现的是五子棋博弈算法,为了方便用户的使用,采用的是java图形用户界面技术。

为了记录棋盘的每一个下棋点,定义数组array[19][19]。

java五子棋小游戏实验报告(附源代码)

java五子棋小游戏实验报告(附源代码)

手机五子棋游戏的设计与实现专业:姓名:班级:学号:指导教师:J2ME(Java 2 Micro Edition)是近年来随着各种不同设备,尤其是移动通信设备的飞速发展而诞生的一项开发技术。

它因其“write once,run anywhere”的Java特性而提高了开发的效率。

随着手机性能的不断提高,手机休闲娱乐应用将成为PC休闲娱乐应用之后又一重要业务增长点。

棋类游戏规则单一,比较适合在手机等便携终端推广。

由于具有跨平台、易于移植、占用空间小的优势,J2ME成为移动应用开发平台的主流,并提供了很多用以支持移动应用软件的开发的API。

现将该技术用于这次的手机游戏开发,可以实现游戏的快速开发,不但便于查看游戏运行过程中内存的占用量和程序的每一部分代码消耗了多少处理器时间,而且可以不断地优化代码,使代码具有高度的复用性、可扩展性、可维护性。

游戏的开发以J2ME为平台,利用Java技术,结合J2ME的MIDP技术,并对于程序设计思想,重要类、方法等展开讨论。

在对弈部分,分析设计走棋算法,选择合适的方式组织成代码,实现基本的人工智能。

过程中使用了J2ME中的CLDC/MIDP软件体系,主要运用了MID Profile的特定类的支持,来完成游戏的开发。

关键词:J2ME;CLDC;MIDPJ2ME is a kind of fast developing technology implemented on various devices especially mobile communication equipments. It improves the efficiency of the development process because of its "write once, run anywhere" nature. The development trend of the entertainment market based on the cell phone is very obvious because the handset performance enhances unceasingly. The entertainment market based on the cell phone will to be the new important business growth point follow the PC entertainment market. As the rules of a single chess game, it is more suitable for mobile phones and other portable terminal extension.J2ME has been the preferred platform for development because of its platform independent and compatibility, and provides a lot of APIs to support the development of mobile application software. The technology for mobile game development, can achieve the rapid development of the game. It is not only easy to observe the memory consumption and processor consumed time during the operation of the game, but also can optimize the code, so that the code has a high degree of reusability, scalability, maintainability.The game has designed by J2ME, the Java technology and the MIDP technology. I studied the procedure thought, the important class and the method. In the playing chess part, I have analyzed the algorithm, choosed the appropriate way to organize the code and realized the basic artificial intelligence. On the other hand,I learned software system of CLDC/MIDP and the specific class of the MID Profile to complete the game development.Key words: J2ME;CLDC;MIDP目录1 概述 (5)1.1 课题研究背景 (5)1.2 课题研究意义 (5)2 开发技术背景 (6)2.1 JAVA语言概述 (6)2.2 J2ME简介 (6)2.3 移动信息设备简表 (6)3 系统分析及总体设计 (7)3.1 可行性分析 (7)3.2 需求分析 (8)3.3 系统概要设计 (8)4 系统详细设计 (9)4.1 界面设计 (9)4.1.1 图形的低级绘制 (10)4.1.2 用户按键设计 (10)4.2 走棋算法 (11)4.3 胜负判断 (11)5 系统测试 (11)5.1 测试方案 (11)5.2 测试结果 (12)6总结 (13)基于J2ME的手机五子棋游戏的设计与实现1 概述1.1 课题研究背景五子棋是当前非常流行的一种棋。

安卓欢乐五子棋人机大战报告

安卓欢乐五子棋人机大战报告

实验报告
( 2015 / 2016学年第2学期)
课程名称
实验名称安卓五子棋人机大战
实验时间2016 年 4 月13 日指导单位
指导教师
学生姓名学号
学院(系) 专业
一、实验目的
1.在棋盘上任意落下一颗子,计算机调用AI算法,能判断出最佳的落子位置并落子。

2.程序能判断出输赢,结束游戏,停止落子。

二、实验环境(实验设备)
Eclipse ADT
三、AI难点解析
1.赢法数组:记录五子棋所有的赢法,三维数组
2.每一种赢法的统计数组,一维数组
3.如何判断胜负
4.计算机落子规则
四、实验结果
开局前:
比赛一游戏结束:比赛二游戏结束:
11。

五子棋实验报告——李寒雪

五子棋实验报告——李寒雪

电子科技大学数学科学学院2018-2019-2学期实验报告(实验)课程名称程序设计基础综合实验学生姓名:李寒雪学号:2015060101029 报告评分:指导教师:胡科实验地点:基础实验大楼227电子科技大学教务处制表实验报告1一、项目名称:主界面与棋盘设计二、实验学时:6 (3~4周)三、算法描述:c语言字符界面,菜单选项有:0.人人对弈1.人机对弈2.退出游戏3.游戏说明四、核心代码:int main(){int temp;while(1){std::cout << "0.人人对弈\n1.人机对弈\n2.退出游戏\n3.游戏说明\n";std::cin >> temp;if (temp == 0){PVP();}else if (temp == 1){PVC();}else if(temp == 2){break;}else if(temp == 3){std::cout << "五子棋游戏:率先连成五颗方为赢家\n";}elsestd::cout << "无此选项";}}五、实验结果(含运行界面截图):1、运行程序进入菜单选项界面2、选择0.人人对弈或者1.人机对弈进入对弈的字符棋盘界面,通过选择行列号来下子3、选择3.游戏说明展示游戏规则4、选择2.退出游戏,成功退出程序六、总结及体会:若用户在使用中出现其他选项应给与一定的提示信息。

实验报告2一、项目名称:移位与胜负判定二、实验学时:6 (4~5周)三、算法描述:在价值判定类中的成员函数isWin实现,对给定的参数当前落子坐标和棋盘对象进行判定,每次落子判定一次,每次判定需要遍历8个方向,由函数PVP和PVC调用,返回布尔量是否赢。

四、核心代码:bool Evaluator::isWin(int x, int y, ChessBoard::State state){for (int direction = Evaluator::Direction::Up; direction <= Evaluator::Direction::LeftDown; direction++){int sum = 0;int x_ = x;int y_ = y;while (true){next(x_, y_, (Evaluator::Direction)direction);if (!chessBoardRef.isBound(x_, y_) && chessBoardRef.getBoardState(x_, y_) == state) sum++; else break;}x_ = x;y_ = y;while (true){next(x_, y_, (Evaluator::Direction)(direction + 4));if (!chessBoardRef.isBound(x_, y_) && chessBoardRef.getBoardState(x_, y_) == state) sum++; else break;}sum++;if (sum == 5) return true;}return false;}五、实验结果(含运行界面截图):1、以人人对弈为例,最后一颗白方落子(5,5),连成五颗判定为赢,游戏结束,提示白方获胜。

【报告】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并且对其添加单击事件以及鼠标事件,可以实现文本的剪贴、复制粘贴等功能。

python实现五子棋人机对战游戏

python实现五子棋人机对战游戏

python实现五⼦棋⼈机对战游戏本⽂代码基于 python3.6 和 pygame1.9.4。

五⼦棋⽐起我之前写的⼏款游戏来说,难度提⾼了不少。

如果是⼈与⼈对战,那么,电脑只需要判断是否赢了就可以。

如果是⼈机对战,那你还得让电脑知道怎么下。

我们先从简单的问题来看。

开端画棋盘⾸先肯定是要画出棋盘来,⽤ pygame 画出⼀个 19 × 19 或 15 × 15 的棋盘并不是什么难事,这在之前的⽂章中已经多次⽤到,就不赘述了。

画棋⼦需要说⼀下的是画棋⼦,因为没找到什么合适的棋⼦图⽚,所以只要⾃⼰来画棋⼦。

我们⽤ pygame.draw.circle 画出来的圆形是这样的:锯齿状⼗分明显,pygame.draw 中有画抗锯齿直线的函数 aaline,但是并没有 aacircle 这样的函数来画⼀个抗锯齿的圆。

这⾥就需要⽤到 pygame.gfxdraw 啦。

pygame.gfxdraw ⽬前还仅是实验版本,这意味着这个 API 可能会在以后的 pygame 版本中发⽣变化或消失。

要绘制抗锯齿和填充形状,请⾸先使⽤函数的aa *版本,然后使⽤填充版本。

例如:col = (255, 0, 0)surf.fill((255, 255, 255))pygame.gfxdraw.aacircle(surf, x, y, 30, col)pygame.gfxdraw.filled_circle(surf, x, y, 30, col)我们⽤这个⽅法在棋盘上画⼀个棋⼦试试看。

可以看到效果已明显改善。

落⼦落⼦需要判断⿏标事件,当⿏标左键点击,获取⿏标点击的位置,然后根据棋盘的位置,计算出棋⼦落在棋盘的位置。

while True:for event in pygame.event.get():if event.type == QUIT:sys.exit()elif event.type == MOUSEBUTTONDOWN:pressed_array = pygame.mouse.get_pressed()if pressed_array[0]: # ⿏标左键点击mouse_pos = pygame.mouse.get_pos()click_point = _get_clickpoint(mouse_pos)当⼀⼦落下,如何判定是否胜利?可以肯定的是,当某⼀⼦落下的时候,如果出现了 5 连,那么落下的这颗⼦必定在这条 5 连线上。

五子棋代码(人机对战)

五子棋代码(人机对战)

import java.applet.*;import java.awt.*;import java.awt.event.*;import java.applet.Applet;import java.awt.Color;public class wuziqi extends Applet implements ActionListener,MouseListener,MouseMotionListener,ItemListe ner{int color_Qizi=0;//旗子的颜色标识0:白子1:黑子int intGame_Start=0;//游戏开始标志0未开始1游戏中int intGame_Body[][]=new int[16][16]; //设置棋盘棋子状态0 无子1 白子2 黑子Button b1=new Button("游戏开始");Button b2=new Button("重置游戏");Label lblWin=new Label(" ");Checkbox ckbHB[]=new Checkbox[2];CheckboxGroup ckgHB=new CheckboxGroup();public void init(){setLayout(null);addMouseListener(this);add(b1);b1.setBounds(330,50,80,30);b1.addActionListener(this);add(b2);b2.setBounds(330,90,80,30);b2.addActionListener(this);ckbHB[0]=new Checkbox("白子先",ckgHB,false);ckbHB[0].setBounds(320,20,60,30);ckbHB[1]=new Checkbox("黑子先",ckgHB,false);ckbHB[1].setBounds(380,20,60,30);add(ckbHB[0]);add(ckbHB[1]);ckbHB[0].addItemListener(this);ckbHB[1].addItemListener(this);add(lblWin);lblWin.setBounds(330,130,80,30);Game_start_csh();}public void itemStateChanged(ItemEvent e){if (ckbHB[0].getState()) //选择黑子先还是白子先{color_Qizi=0;}else{color_Qizi=1;}}public void actionPerformed(ActionEvent e){Graphics g=getGraphics();if (e.getSource()==b1){Game_start();}else{Game_re();}}public void mousePressed(MouseEvent e){}public void mouseClicked(MouseEvent e){Graphics g=getGraphics();int x1,y1;x1=e.getX();y1=e.getY();if (e.getX()<20 || e.getX()>300 || e.getY()<20 || e.getY()>300) {return;}if (x1%20>10){x1+=20;}if(y1%20>10){y1+=20;}x1=x1/20*20;y1=y1/20*20;set_Qizi(x1,y1);}public void mouseEntered(MouseEvent e){} public void mouseExited(MouseEvent e){} public void mouseReleased(MouseEvent e){} public void mouseDragged(MouseEvent e){} public void mouseMoved(MouseEvent e){}public void paint(Graphics g){draw_qipan(g);}。

五子棋C++实验报告

五子棋C++实验报告

五子棋C++实验报告五子棋 C++实验报告一、实验目的本次实验的目的是使用 C++语言实现五子棋游戏,通过编写代码来模拟五子棋的游戏规则和逻辑,加深对 C++程序设计语言的理解和应用能力,同时提高解决实际问题的编程思维和技巧。

二、实验环境本次实验使用的开发环境为 Visual Studio 2019,操作系统为Windows 10。

三、实验原理1、棋盘设计采用二维数组来表示棋盘,数组的每个元素表示棋盘上的一个交叉点的状态(空、黑棋、白棋)。

2、落子判断在玩家落子时,需要判断落子位置是否合法(在棋盘范围内且该位置为空)。

3、胜负判断检查横向、纵向、正斜向和反斜向是否有连续的同色棋子达到五子相连,以确定胜负。

四、实验步骤1、棋盘类的设计定义一个`ChessBoard`类,包含棋盘的大小、棋盘状态数组以及相关的操作方法,如初始化棋盘、获取棋盘状态、判断落子位置是否合法等。

2、玩家类的设计设计`Player`类,代表游戏中的玩家,包含玩家的颜色(黑或白)和落子方法。

3、游戏流程控制在主函数中实现游戏的主要流程,包括初始化棋盘、玩家轮流落子、判断胜负等。

4、界面显示使用简单的控制台输出显示棋盘和游戏的相关信息。

五、代码实现以下是关键部分的代码示例:```cppinclude <iostream>using namespace std;//棋盘类class ChessBoard {private:int boardSize;int boardState;public:ChessBoard(int size) {boardSize = size;boardState = new int boardSize;for (int i = 0; i < boardSize; i++){boardStatei = new intboardSize;for (int j = 0; j < boardSize; j++){boardStateij = 0; // 0 表示空位}}}~ChessBoard(){for (int i = 0; i < boardSize; i++){delete boardStatei;}delete boardState;}bool isLegalMove(int x, int y) {if (x < 0 || x >= boardSize || y < 0 || y >=boardSize || boardStatexy!= 0) {return false;}return true;}void makeMove(int x, int y, int player) {boardStatexy = player;}void printBoard(){for (int i = 0; i < boardSize; i++){for (int j = 0; j < boardSize; j++){if (boardStateij == 0) {cout <<"";} else if (boardStateij == 1) {cout <<" X ";} else {cout <<" O ";}}cout << endl;}}bool checkWin(int player) {//横向检查for (int i = 0; i < boardSize; i++){for (int j = 0; j < boardSize 4; j++){if (boardStateij == player && boardStateij + 1 == player &&boardStateij + 2 == player && boardStateij + 3 == player &&boardStateij + 4 == player) {return true;}}}//纵向检查for (int i = 0; i < boardSize 4; i++){for (int j = 0; j < boardSize; j++){if (boardStateij == player && boardStatei + 1j == player &&boardStatei + 2j == player && boardStatei + 3j == player &&boardStatei + 4j == player) {return true;}}}//正斜向检查for (int i = 0; i < boardSize 4; i++){for (int j = 0; j < boardSize 4; j++){if (boardStateij == player && boardStatei + 1j + 1 == player && boardStatei + 2j + 2 == player && boardStatei + 3j + 3 ==player && boardStatei + 4j + 4 == player) {return true;}}}//反斜向检查for (int i = 4; i < boardSize; i++){for (int j = 0; j < boardSize 4; j++){if (boardStateij == player && boardStatei 1j + 1 == player &&boardStatei 2j + 2 == player && boardStatei 3j + 3 == player &&boardStatei 4j + 4 == player) {return true;}}}return false;}};//玩家类class Player {private:int color; // 1 表示黑棋,2 表示白棋public:Player(int c) {color = c;}void makeMove(ChessBoard& board) {int x, y;cout <<"请" <<(color == 1? "黑棋" :"白棋")<<"玩家输入落子位置(x y):";cin >> x >> y;while (!boardisLegalMove(x, y)){cout <<"非法落子,请重新输入: ";cin >> x >> y;}boardmakeMove(x, y, color);}};int main(){ChessBoard board(15);// 15x15 的棋盘Player blackPlayer(1);Player whitePlayer(2);int currentPlayer = 1;while (true) {boardprintBoard();if (currentPlayer == 1) {blackPlayermakeMove(board);if (boardcheckWin(1)){cout <<"黑棋胜利!"<< endl; break;}currentPlayer = 2;} else {whitePlayermakeMove(board);if (boardcheckWin(2)){cout <<"白棋胜利!"<< endl;break;}currentPlayer = 1;}}return 0;}```六、实验结果与分析经过多次测试,程序能够正确地实现五子棋的游戏规则,玩家可以顺利进行游戏。

五子棋之人机对弈智能报告

五子棋之人机对弈智能报告

《人工智能课程设计》课题名称:五子棋之人机对弈五子棋之人机对弈摘要:项目完成了一个人机对弈的五子棋游戏。

游戏采用按钮做棋子,棋子图标来填充按钮。

首先,继承java的JFrame类创建了一个窗口,并在窗口中添加了一系列菜单选项和按钮,同时并为菜单、按钮组件添加事件动作和监听器,并设置按钮组件的坐标位置。

窗体上方为菜单选项,分别有新游戏、悔棋、认输、退出、帮助、关于菜单;下方为12x12的按钮棋盘。

玩家下子后,电脑会自动计算棋盘上的最优下棋坐标,然后在此坐标对应的按钮上填充棋子图标。

在下子过程中,用一个坐标数组来保存每个棋子坐标,用于悔棋时做出相应动作。

最终赢家由电脑计算,玩家和电脑谁先五子连珠谁就先获胜。

开发工具语言:eclipse工具+ java语言游戏背景:五子棋游戏不但容易上手,而且它区别于别的游戏,它不但能使人娱乐,而且能使人的头脑变得更加聪明。

而五子棋对战有两种模式:一.人机对战;二.双人对战。

这些给人无限乐趣的用途正是人工智能的杰作。

正因为这样它鼓励着人们对它不断研究,这在很大程度上促进了人工智能的发展,反过来人工智能的理论和技术上的突破能够使五子棋程序更完美、更受欢迎!同时,五子棋游戏程序的开发也使得五子棋这个游戏得到了广泛的推广,让世界各地的人们知道五子棋,随时地玩上五子棋,这已经不再是梦想了。

五子棋游戏程序使得越来越多的人喜欢上了五子棋,热爱下五子棋,它是具有很好的带动性的。

随着互联网络的不断普及,越来越多的人可以在网络上就能够与他人下五子棋了。

课题研究的现状:随着五子棋事业的发展,五子棋在国际国内的交流和比赛越来越多,随之也带动了越来越多的五子棋爱好者。

目前,五子棋在我国的很多大、中城市发展很快,尤其是首都北京,曾多次举办了五子棋的各种比赛,中央电视台体育频道也长期播放着五子棋的讲座,还有,一些大型企业和单位也曾举办过五子棋的比赛。

这些活动表明,五子棋在我国有着广泛的群众基础,是一项人民群众喜闻乐见的体育运动。

五子棋实验报告

五子棋实验报告

五子棋实验报告一、实验目的和要求一、能够用编程语言实现一个简单的五子棋程序二、在实际系统中利用、实现人工智能的相关算法3、进一步加深对人工智能算法的明白得二、五子棋的大体常识与原理一、五子棋的起源五子棋,是一种两人对弈的纯策略型棋类游戏,亦称“串珠”、“连五子”;是中国民间超级熟知的一个古老棋种。

相传,它起源于四千连年前的尧帝时期,比围棋的历史还要悠长。

亦有传奇,五子棋最初流行于少数民族地域,以后渐渐演变成围棋并在炎黄子孙后代中遍及开来。

五子棋进展于日本,流行于欧美。

容易上手,老少皆宜,而且趣味横生,引人入胜;不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。

传统五子棋的棋具与围棋相同,棋子分为黑白两色,棋盘为19X19,棋子放置于棋盘线交叉点上。

两人对局,各执一色,连番下一子,先将横、竖或斜线的5个或5个以上同色棋子连成不中断的一排者为胜。

因为传统五子棋在落子后不能移动或拿掉,因此也能够用纸和笔来进行游戏。

二、五子棋的大体常识与任何一种竞技棋一样,五子棋的每一局棋也分为三个时期:开局,中局和残局。

五子棋的开始时期称为开局,或称布局。

其开局时期是十分短暂的,大约在七着与十几着之间。

在这一时期的争夺中,两边的布局,应付将对以后的输赢起着极为关键的作用。

在开局时期取得的形势好坏,主动与被动,先手与后手的好坏程度,往往直接阻碍中局的战斗。

因此踊跃处置好开局和开局向中局的过渡十分重要。

五子棋是从一至五,慢慢布子,进展连系,同时运用限制和反限制的聪慧,在连子的进程中为自己的棋子争得相对的主动权和优势,慢慢扩展优势,或从劣势转化为优势,击溃对方的防线,最后连五取胜或抓禁手取胜或迫使对方投子认负。

3、五子棋竞赛的相关规定(1) 职业连珠规那么a. 黑方先下子,白后下,从天元开始彼此顺序落子。

b. 最先在棋盘横向、竖向、斜向形成持续的相同色五个棋子的一方为胜。

c. 黑棋禁手判负,白棋无禁手。

黑棋禁手包括“三三”(包括“四三三”)、“四四”(包括“四四三”)、“长连”。

“Java程序设计”——“五子棋”综合实验报告

“Java程序设计”——“五子棋”综合实验报告

“Java程序设计”综合实验报告一、前言1、项目背景通过五子棋这个课程设计。

可以让我们更加熟悉Java程序设计这门课程,加强对Eclipse这个软件的使用,加深对Java语言的掌握,提高编程水平。

同时培养能力,为将来的工作打下坚实的基础。

2、目标和意义目标:锻炼我们的能力,提高组中每一个人对Java语言的认识,培养编程兴趣。

让每一个人都能参与进来,提高团队合作意识。

意义:通过编写综合类的程序,运用已经学过的知识,和自主学习一些新的知识,提高了学习能力,掌握了一些自主学习的方法。

3、开发分工及进度安排二、功能分析1、主要模块本项目主要分为3个大的模块,分别为整体布局;界面绘制;与对战的算法。

由于游戏规则的设置,这里的游戏模式分为人机对战和人人对战。

黑白双方依次落子,由黑子先下,当任意一方在棋盘上形成横向,竖向,斜向连续五个相同颜色的棋子的一方获胜。

主要功能①实现在2种模式下五子棋的游戏。

②实现通过鼠标的点击位置放置棋子,达到下棋的目的。

③实现游戏玩家对游戏模式的自主选择。

④实现对在每种游戏模式下的黑子先手下棋的规定,先达到5子即为胜利。

三、关键功能的设计与实现1、数据结构与算法数据结构:项目中主要数据结构为二维数组。

用于存储棋盘上棋子的信息,和保存棋型表。

主要算法:(一)iswin()函数:用来判断输赢,通过鼠标事件所得到的点或者电脑下的点的坐标,来扫描该点八个方向的相邻的相同棋子数,上下,左右,斜左上下,斜右上下为四组,任意一组等于5即为胜利,由于本程序没有考虑禁手原则,只考虑了民间规则,所以大于5也为胜利。

public int iswin1(int x, int y, int heqi) {int k, s1, s2, s3, s4, s5, s6, s7, s8;s1 = 0;s2 = 0;s3 = 0;s4 = 0;s5 = 0;s6 = 0;s7 = 0;s8 = 0;if (heqi == 256)return -1;for (k = 1; k < 5; k++) {if (y + k < 16 && qipanqizi[x][y + k] == qipanqizi[x][y])s1++;elsebreak;}for (k = 1; k < 5; k++) {if (y - k > -1 && qipanqizi[x][y - k] == qipanqizi[x][y])s2++;elsebreak;}for (k = 1; k < 5; k++) {if (x + k < 16 && y + k < 16&& qipanqizi[x + k][y + k] == qipanqizi[x][y]) s3++;elsebreak;}for (k = 1; k < 5; k++) {if (x - k > -1 && y - k > -1&& qipanqizi[x - k][y - k] == qipanqizi[x][y]) s4++;elsebreak;}for (k = 1; k < 5; k++) {if (x + k < 16 && qipanqizi[x + k][y] ==qipanqizi[x][y])s5++;elsebreak;}for (k = 1; k < 5; k++) {if (x - k > -1 && qipanqizi[x - k][y] ==qipanqizi[x][y])s6++;elsebreak;}for (k = 1; k < 5; k++) {if (x - k > -1 && y + k < 16&& qipanqizi[x - k][y + k] == qipanqizi[x][y]) s7++;elsebreak;}for (k = 1; k < 5; k++) {if (x + k < 16 && y - k > -1&& qipanqizi[x + k][y - k] == qipanqizi[x][y]) s8++;elsebreak;}if (s1 + s2 >= 4 || s3 + s4 >= 4 || s5 + s6 >= 4 || s7 + s8 >= 4) {return 1;} elsereturn 0;}(二)人机对战通过对整个棋盘上每一个点的扫描,获得了电脑和玩家的棋型表,表中数据为该点的权值。

C语言课程设计五子棋源代码_+设计报告

C语言课程设计五子棋源代码_+设计报告

C语言程序设计综合实验设计报告题目:班级;人数:小组成员:时间:目录1 课程设计报告1.1课题描述1.2需求分析1.3概要设计2源程序代码3详细设计1.课题设计报告1.1课题分析:游戏介绍:在一个18*18的方格中下棋,两个玩家,根据键盘上的上、下、左、右键及W、S、A、D来控制棋的走向,空格键及回车键表示确定棋子的落下位置,两个玩家为交替下棋,如果于其中任何一家下的五个棋子能够练成一线那么为胜者,游戏结束。

1 、五子棋是两个人之间进行的竞技活动,开始是由P1先下,把棋落在方框内,然后P2下,如此下棋直到一方在棋盘的横,竖,斜将同色的五个棋子连成一条线,则此方获胜。

游戏由玩家决定继续或结束。

1.2需求分析(1)在游戏开始时出现一个欢迎的界面同时介绍了游戏的规则;(2)画出棋盘的大小;(3)画棋子并确定棋子的大小;(4)判断键盘输入哪个键执行操作;(5)玩家P1先落棋;(6)玩家轮流下棋;(7)判断赢家。

(8)由玩家决定是否继续新游戏。

1.3 概要设计(1)功能模块2. 主流程图五子棋游戏初始化模块下棋操作模块 判断胜负模块 帮助模块 开始 欢迎界面帮助信息画出18*18棋盘遇到的一个问题:图形一闪而过解决方法因为Win-TC 的图形驱动程序EGAVGA.BGI 文件安装路径为c:\\Win-TC\\projects int gdriver=DETECT, gmode;initgraph(&gdriver, &gmode, "c:\\tc")改为initgraph(&gdriver, &gmode, "c:\\Win-TC\\projects")2程序代码#include <bios.h>#include "stdio.h"#include "graphics.h"/*定义1号玩家的操作键键码*/ 定义数组a[X] [Y ]设置初始点设置为(240,170),调用p1move函数,调用p2move函数Enter SpaceESC 用WIN函数判断胜负 游戏结束#define W 0x1177/*上移--'W'*/#define S 0x1f73/*下移--'S'*/#define A 0x1e61/*左移--'A'*/#define D 0x2064/*右移--'D'*/#define SP 0x3920/*落子--空格键*//*定义2号玩家的操作键键码*/#define UP 0x4800/*上移--方向键up*/#define DOWN 0x5000/*下移--方向键down*/#define LEFT 0x4b00/*左移--方向键left*/#define RIGHT 0x4d00/*右移--方向键right*/#define ENTER 0x1c0d/*落子--回车键Enter*/#define ESC 0x011b#define X (getx()-140)/20 /*将棋盘上光标所在点的横坐标X转化为0-18的数*/ #define Y (gety()-70)/20 /*将棋盘上光标所在点的横坐标Y转化为0-18的数*/int k,w=DETECT,gmode,j,i;int a[20][20];void p1move(); /*定义函数*/void p2move();void win();p1win();p2win();yellow();white();black();heqi();welcome();help();csz();qipang();p1turn();p2turn();p1del();p1turn()/*画左上角的白棋*/{setcolor(7);setfillstyle(1,7);circle(60,110,9);floodfill(60,110,7);}p1del() /*将左上角白棋檫去*/ {setfillstyle(1,14);floodfill(60,110,14);}p2turn() /*画右上角的黑棋*/ {setcolor(0);setfillstyle(1,0);circle(578,115,9);floodfill(578,115,0);}p2del() /*画右上角的黑棋*/ {setfillstyle(1,14);floodfill(578,115,14);}white() /*在当前位置画白棋*/ {setcolor(7);setfillstyle(1,7);circle(getx(),gety(),9); floodfill(getx(),gety(),7); }black() /*在当前位置画黑棋*/ {setcolor(0);setfillstyle(1,0);circle(getx(),gety(),9); floodfill(getx(),gety(),0); }yellow() /*补棋盘的颜色*/ {setcolor(6);setfillstyle(1,6);circle(getx(),gety(),9);floodfill(getx(),gety(),6);setcolor(15);line(getx()-9,gety(),getx()+9,gety());line(getx(),gety()+9,getx(),gety()-9);}qipang() /*画棋盘*/{ setfillstyle(1,6);bar(120,50,520,450);setfillstyle(1,14);bar(540,50,620,150);bar(20,50,100,150);for(k=0;k<19;k++){moveto(140+20*k,70);linerel(0,360);moveto(140,70+20*k);linerel(360,0);}moveto(240,170);setcolor(5);settextstyle(3,0,4);outtextxy(50,60,"P1");outtextxy(560,60,"P2");}welcome() /*欢迎界面*/{ initgraph(&w ,&gmode,"c:\\Win-TC\\projects") ; clearviewport();setcolor(4);settextstyle(0,0,6);outtextxy(180,180,"Welcome");settextstyle(0,0,2);outtextxy(280,440,"press any key to begin");delay(1000) ; /*delay(1000000000) ; delay(1000000000) ; */ }help() /*帮助界面*/{initgraph(&w ,&gmode,"c:\\Win-TC\\projects");clearviewport();setcolor(4);settextstyle(0,0,2);outtextxy(80,100,"P1 move; 'W S A D' ");outtextxy(80,120," set : space ");outtextxy(80,180,"P2 move: up down left right ");outtextxy(80,200," set: Enter");outtextxy(80,280,"Whoever is first to gather five ");/*same color pieces in a line without any different color piece among them,then he win */ outtextxy(80,300,"same color pieces in a line without");outtextxy(80,320,"any different color piece among ");outtextxy(80,340,"them, then he win.");outtextxy(80,360,"When you want to quit the game,");outtextxy(80,380,"press Esc.");outtextxy(220,440,"press any key to continue");while(bioskey(1)==0);}p1win() /*玩家1获胜界面*/{initgraph(&w ,&gmode,"c:\\Win-TC\\projects") ;clearviewport();setcolor(4);settextstyle(0,0,6);outtextxy(180,180,"P1 WIN");settextstyle(0,0,2);outtextxy(280,440,"press any key to begin");while(bioskey(1)==0);main();}p2win() /*玩家2获胜界面*/{clearviewport();setcolor(4);settextstyle(0,0,6);outtextxy(180,180,"P2 WIN");settextstyle(0,0,2);outtextxy(280,440,"press any key to begin");while(bioskey(0)!=0) main();}heqi() /*和棋界面*/{clearviewport();setcolor(4);settextstyle(0,0,6);outtextxy(180,180,"tie");settextstyle(0,0,2);outtextxy(280,440,"press any key to begin");while(bioskey(0)!=0) main();}csz() /*将所在位置的A[X][Y]赋初值6*/{for(i=0;i<19;i++)for(j=0;j<19;j++){a[i][j]=6;}}void win() /*判断输赢*/{int sum1,sum2,sum3,sum4,sum=0,n,i,j;for(i=X-4,j=Y-4,n=0;i<=X,j<=Y;i++,j++,n-=2){sum1=a[i][Y]+a[i+1][Y]+a[i+2][Y]+a[i+3][Y]+a[i+4][Y];sum2=a[i][j]+a[i+1][j+1]+a[i+2][j+2]+a[i+3][j+3]+a[i+4][j+4];sum3=a[X][j]+a[X][j+1]+a[X][j+2]+a[X][j+3]+a[X][j+4];sum4=a[i][j+8+n]+a[i+1][j+7+n]+a[i+2][j+6+n]+a[i+3][j+5+n]+a[i+4][j+4+n]; if(sum1==5||sum2==5||sum3==5||sum4==5)p2win();if (sum1==0||sum2==0||sum3==0||sum4==0)p1win(); }for(i=0;i<18;i++)for(j=0;j<18;j++)sum=sum+a[i][j];if(sum<181)heqi();}void p1move() /*玩家1的移动*/{switch(bioskey(0)){case ESC: {closegraph(); exit(0);}/*如果按键为ESC就退出游戏*/case SP:/*落子*/if(a[X][Y]==6) {p1del();p2turn();a[X][Y]=0;white();win(); p2move();}else p1move();case A: /*向左移*/if(a[X][Y]==0){if(getx()==140) moveto(520,gety());moverel(-20,0);white();}else if(a[X][Y]==1){if(getx()==140) moveto(520,gety());black();moverel(-20,0);white();} else{ yellow();if(getx()==140) moveto(520,gety());moverel(-20,0);white();} p1move();case D: /*向右移*/if(a[X][Y]==0) {if(getx()==500) moveto(120,gety());moverel(20,0);white();}else if(a[X][Y]==1) {if(getx()==500) moveto(120,gety());black();moverel(20,0);white();}else { yellow();if(getx()==500) moveto(120,gety());moverel(20,0);white();}p1move();case W: /*向上移*/if(a[X][Y]==0) {if(gety()==70) moveto(getx(),450);moverel(0,-20);white();}else if(a[X][Y]==1) {if(gety()==70) moveto(getx(),450);black();moverel(0,-20);white();}else { yellow();if(gety()==70) moveto(getx(),450);moverel(0,-20);white();}p1move();case S: /*向下移*/if(a[X][Y]==0) {if(gety()==430) moveto(getx(),50);moverel(0,20);white();}else if(a[X][Y]==1) {if(gety()==430) moveto(getx(),50);black();moverel(0,20);white();}else { yellow();if(gety()==430) moveto(getx(),50);moverel(0,20);white(); } p1move();default: p1move();}}void p2move() /*玩家2的移动*/{switch(bioskey(0)) /*如果按键为ESC就退出游戏*/{case ESC: {closegraph(); exit(0);}case ENTER: /*落子*/if(a[X][Y]==6) {p2del();p1turn();a[X][Y]=1;black();win();p1move();}else p2move();case LEFT: /*向左移*/if(a[X][Y]==1) {if(getx()==140) moveto(520,gety());moverel(-20,0);black();}else if(a[X][Y]==0) {if(getx()==140) moveto(520,gety());if(getx()==140) moveto(500,gety());white();moverel(-20,0);black();}else { yellow();if(getx()==140) moveto(520,gety());moverel(-20,0);black();} p2move();case RIGHT: /*向右移*/if(a[X][Y]==1) {if(getx()==500) moveto(120,gety());moverel(20,0);black();}else if(a[X][Y]==0) {if(getx()==500) moveto(120,gety());white();moverel(20,0);black();}else { yellow();if(getx()==500) moveto(120,gety());moverel(20,0);black();}p2move();case UP: /*向上移*/if(a[X][Y]==1) {if(gety()==70) moveto(getx(),450);moverel(0,-20);black();}else if(a[X][Y]==0) {if(gety()==70) moveto(getx(),450);white();moverel(0,-20);black();}else { yellow();if(gety()==70) moveto(getx(),450);moverel(0,-20);black();}p2move();case DOWN: /*向下移*/if(a[X][Y]==1) {if(gety()==430) moveto(getx(),50);moverel(0,20);black();}else if(a[X][Y]==0) {if(gety()==430) moveto(getx(),50);white();moverel(0,20);black();}else {if(gety()==430) moveto(getx(),50); yellow();moverel(0,20);black();}p2move();default: p2move();}}main() /*主函数*/{ welcome(); /*调用欢迎界面*/help(); /*调用帮助界面*/initgraph(&w ,&gmode,"c:\\Win-TC\\projects") ; /*清屏*/clearviewport();csz();qipang(); /*调用棋盘*/p1move(); /*调用玩家1的移动*/p2move();getch();}3详细设计1部分:以下是我负责的模块的函数,由于个人水平问题,我只负责画图部分。

Java五子棋游戏源代码(人机对战)

Java五子棋游戏源代码(人机对战)

//Java编程:五子棋游戏源代码import java.awt.*;import java.awt.event.*;import java.applet.*;import javax.swing.*;import java.io.PrintStream;import javax.swing.JComponent;import javax.swing.JPanel;/**main方法创建了ChessFrame类的一个实例对象(cf),*并启动屏幕显示显示该实例对象。

**/public class FiveChessAppletDemo {public static void main(String args[]){ChessFrame cf = new ChessFrame();cf.show();}}/**类ChessFrame主要功能是创建五子棋游戏主窗体和菜单**/class ChessFrame extends JFrame implements ActionListener { private String[] strsize={"20x15","30x20","40x30"};private String[] strmode={"人机对弈","人人对弈"};public static boolean iscomputer=true,checkcomputer=true; private int width,height;private ChessModel cm;private MainPanel mp;//构造五子棋游戏的主窗体public ChessFrame() {this.setTitle("五子棋游戏");cm=new ChessModel(1);mp=new MainPanel(cm);Container con=this.getContentPane();con.add(mp,"Center");this.setResizable(false);this.addWindowListener(new ChessWindowEvent());MapSize(20,15);JMenuBar mbar = new JMenuBar();this.setJMenuBar(mbar);JMenu gameMenu = new JMenu("游戏");mbar.add(makeMenu(gameMenu, new Object[] {"开局", "棋盘","模式", null, "退出"}, this));JMenu lookMenu =new JMenu("视图");mbar.add(makeMenu(lookMenu,new Object[] {"Metal","Motif","Windows"},this));JMenu helpMenu = new JMenu("帮助");mbar.add(makeMenu(helpMenu, new Object[] {"关于"}, this));}//构造五子棋游戏的主菜单public JMenu makeMenu(Object parent, Object items[], Object target){ JMenu m = null;if(parent instanceof JMenu)m = (JMenu)parent;else if(parent instanceof String)m = new JMenu((String)parent);elsereturn null;for(int i = 0; i < items.length; i++)if(items[i] == null)m.addSeparator();else if(items[i] == "棋盘"){JMenu jm = new JMenu("棋盘");ButtonGroup group=new ButtonGroup();JRadioButtonMenuItem rmenu;for (int j=0;j<strsize.length;j++){rmenu=makeRadioButtonMenuItem(strsize[j],target);if (j==0)rmenu.setSelected(true);jm.add(rmenu);group.add(rmenu);}m.add(jm);}else if(items[i] == "模式"){JMenu jm = new JMenu("模式");ButtonGroup group=new ButtonGroup();JRadioButtonMenuItem rmenu;for (int h=0;h<strmode.length;h++){rmenu=makeRadioButtonMenuItem(strmode[h],target);if(h==0)rmenu.setSelected(true);jm.add(rmenu);group.add(rmenu);}m.add(jm);}elsem.add(makeMenuItem(items[i], target));return m;}//构造五子棋游戏的菜单项public JMenuItem makeMenuItem(Object item, Object target){ JMenuItem r = null;if(item instanceof String)r = new JMenuItem((String)item);else if(item instanceof JMenuItem)r = (JMenuItem)item;elsereturn null;if(target instanceof ActionListener)r.addActionListener((ActionListener)target);return r;}//构造五子棋游戏的单选按钮式菜单项public JRadioButtonMenuItem makeRadioButtonMenuItem( Object item, Object target){JRadioButtonMenuItem r = null;if(item instanceof String)r = new JRadioButtonMenuItem((String)item);else if(item instanceof JRadioButtonMenuItem)r = (JRadioButtonMenuItem)item;elsereturn null;if(target instanceof ActionListener)r.addActionListener((ActionListener)target);return r;}public void MapSize(int w,int h){setSize(w * 20+50 , h * 20+100 );if(this.checkcomputer)this.iscomputer=true;elsethis.iscomputer=false;mp.setModel(cm);mp.repaint();}public boolean getiscomputer(){return this.iscomputer;}public void restart(){int modeChess = cm.getModeChess();if(modeChess <= 3 && modeChess >= 1){cm = new ChessModel(modeChess);MapSize(cm.getWidth(),cm.getHeight());}else{System.out.println("\u81EA\u5B9A\u4E49");}}public void actionPerformed(ActionEvent e){String arg=e.getActionCommand();try{if (arg.equals("Windows"))UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");else if(arg.equals("Motif"))UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");elseUIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel" ); SwingUtilities.updateComponentTreeUI(this);}catch(Exception ee){}if(arg.equals("20x15")){this.width=20;this.height=15;cm=new ChessModel(1);MapSize(this.width,this.height);SwingUtilities.updateComponentTreeUI(this);}if(arg.equals("30x20")){this.width=30;this.height=20;cm=new ChessModel(2);MapSize(this.width,this.height);SwingUtilities.updateComponentTreeUI(this);}if(arg.equals("40x30")){this.width=40;this.height=30;cm=new ChessModel(3);MapSize(this.width,this.height);SwingUtilities.updateComponentTreeUI(this);}if(arg.equals("人机对弈")){this.checkcomputer=true;this.iscomputer=true;cm=new ChessModel(cm.getModeChess());MapSize(cm.getWidth(),cm.getHeight());SwingUtilities.updateComponentTreeUI(this);}if(arg.equals("人人对弈")){this.checkcomputer=false;this.iscomputer=false;cm=new ChessModel(cm.getModeChess());MapSize(cm.getWidth(),cm.getHeight());SwingUtilities.updateComponentTreeUI(this);}if(arg.equals("开局")){restart();}if(arg.equals("关于"))JOptionPane.showMessageDialog(this, "五子棋游戏测试版本", "关于", 0);if(arg.equals("退出"))System.exit(0);}}/**类ChessModel实现了整个五子棋程序算法的核心*/class ChessModel {//棋盘的宽度、高度、棋盘的模式(如20×15)private int width,height,modeChess;//棋盘方格的横向、纵向坐标private int x=0,y=0;//棋盘方格的横向、纵向坐标所对应的棋子颜色,//数组arrMapShow只有3个值:1,2,3,-5,//其中1代表该棋盘方格上下的棋子为黑子,//2代表该棋盘方格上下的棋子为白子,//3代表为该棋盘方格上没有棋子,//-5代表该棋盘方格不能够下棋子private int[][] arrMapShow;//交换棋手的标识,棋盘方格上是否有棋子的标识符private boolean isOdd,isExist;public ChessModel() {}//该构造方法根据不同的棋盘模式(modeChess)来构建对应大小的棋盘public ChessModel(int modeChess){this.isOdd=true;if(modeChess == 1){PanelInit(20, 15, modeChess);}if(modeChess == 2){PanelInit(30, 20, modeChess);}if(modeChess == 3){PanelInit(40, 30, modeChess);}}//按照棋盘模式构建棋盘大小private void PanelInit(int width, int height, int modeChess){this.width = width;this.height = height;this.modeChess = modeChess;arrMapShow = new int[width+1][height+1];for(int i = 0; i <= width; i++){for(int j = 0; j <= height; j++){arrMapShow[i][j] = -5;}}}//获取是否交换棋手的标识符public boolean getisOdd(){return this.isOdd;}//设置交换棋手的标识符public void setisOdd(boolean isodd){if(isodd)this.isOdd=true;elsethis.isOdd=false;}//获取某棋盘方格是否有棋子的标识值public boolean getisExist(){return this.isExist;}//获取棋盘宽度public int getWidth(){return this.width;}//获取棋盘高度public int getHeight(){return this.height;}//获取棋盘模式public int getModeChess(){return this.modeChess;}//获取棋盘方格上棋子的信息public int[][] getarrMapShow(){return arrMapShow;}//判断下子的横向、纵向坐标是否越界private boolean badxy(int x, int y){if(x >= width+20 || x < 0)return true;return y >= height+20 || y < 0;}//计算棋盘上某一方格上八个方向棋子的最大值,//这八个方向分别是:左、右、上、下、左上、左下、右上、右下public boolean chessExist(int i,int j){if(this.arrMapShow[i][j]==1 || this.arrMapShow[i][j]==2)return true;return false;}//判断该坐标位置是否可下棋子public void readyplay(int x,int y){if(badxy(x,y))return;if (chessExist(x,y))return;this.arrMapShow[x][y]=3;}//在该坐标位置下棋子public void play(int x,int y){if(badxy(x,y))return;if(chessExist(x,y)){this.isExist=true;return;}elsethis.isExist=false;if(getisOdd()){setisOdd(false);this.arrMapShow[x][y]=1;}else{setisOdd(true);this.arrMapShow[x][y]=2;}}//计算机走棋/**说明:用穷举法判断每一个坐标点的四个方向的的最大棋子数,*最后得出棋子数最大值的坐标,下子**/public void computerDo(int width,int height){int max_black,max_white,max_temp,max=0;setisOdd(true);System.out.println("计算机走棋...");for(int i = 0; i <= width; i++){for(int j = 0; j <= height; j++){if(!chessExist(i,j)){//算法判断是否下子max_white=checkMax(i,j,2);//判断白子的最大值max_black=checkMax(i,j,1);//判断黑子的最大值max_temp=Math.max(max_white,max_black);if(max_temp>max){max=max_temp;this.x=i;this.y=j;}}}}setX(this.x);setY(this.y);this.arrMapShow[this.x][this.y]=2;}//记录电脑下子后的横向坐标public void setX(int x){this.x=x;}//记录电脑下子后的纵向坐标public void setY(int y){this.y=y;}//获取电脑下子的横向坐标public int getX(){return this.x;}//获取电脑下子的纵向坐标public int getY(){return this.y;}//计算棋盘上某一方格上八个方向棋子的最大值,//这八个方向分别是:左、右、上、下、左上、左下、右上、右下public int checkMax(int x, int y,int black_or_white){int num=0,max_num,max_temp=0;int x_temp=x,y_temp=y;int x_temp1=x_temp,y_temp1=y_temp;//judge rightfor(int i=1;i<5;i++){x_temp1+=1;if(x_temp1>this.width)break;if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++;elsebreak;}//judge leftx_temp1=x_temp;for(int i=1;i<5;i++){x_temp1-=1;if(x_temp1<0)break;if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++;elsebreak;}if(num<5)max_temp=num;//judge upx_temp1=x_temp;y_temp1=y_temp;num=0;for(int i=1;i<5;i++){y_temp1-=1;if(y_temp1<0)break;if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++;elsebreak;}//judge downy_temp1=y_temp;for(int i=1;i<5;i++){y_temp1+=1;if(y_temp1>this.height)break;if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++;elsebreak;}if(num>max_temp&&num<5)max_temp=num;//judge left_upx_temp1=x_temp;y_temp1=y_temp;num=0;for(int i=1;i<5;i++){x_temp1-=1;y_temp1-=1;if(y_temp1<0 || x_temp1<0)break;if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++;elsebreak;}//judge right_downx_temp1=x_temp;y_temp1=y_temp;for(int i=1;i<5;i++){x_temp1+=1;y_temp1+=1;if(y_temp1>this.height || x_temp1>this.width)break;if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++;elsebreak;}if(num>max_temp&&num<5)max_temp=num;//judge right_upx_temp1=x_temp;y_temp1=y_temp;num=0;for(int i=1;i<5;i++){x_temp1+=1;y_temp1-=1;if(y_temp1<0 || x_temp1>this.width)break;if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++;elsebreak;}//judge left_downx_temp1=x_temp;y_temp1=y_temp;for(int i=1;i<5;i++){x_temp1-=1;y_temp1+=1;if(y_temp1>this.height || x_temp1<0)break;if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++;elsebreak;}if(num>max_temp&&num<5)max_temp=num;max_num=max_temp;return max_num;}//判断胜负public boolean judgeSuccess(int x,int y,boolean isodd){ int num=1;int arrvalue;int x_temp=x,y_temp=y;if(isodd)arrvalue=2;elsearrvalue=1;int x_temp1=x_temp,y_temp1=y_temp;//判断右边for(int i=1;i<6;i++){x_temp1+=1;if(x_temp1>this.width)break;if(this.arrMapShow[x_temp1][y_temp1]==arrvalue)num++;elsebreak;}//判断左边x_temp1=x_temp;for(int i=1;i<6;i++){if(x_temp1<0)break;if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++;elsebreak;}if(num==5)return true;//判断上方x_temp1=x_temp;y_temp1=y_temp;num=1;for(int i=1;i<6;i++){y_temp1-=1;if(y_temp1<0)break;if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++;elsebreak;}//判断下方y_temp1=y_temp;for(int i=1;i<6;i++){y_temp1+=1;if(y_temp1>this.height)break;if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++;elsebreak;}if(num==5)return true;//判断左上x_temp1=x_temp;y_temp1=y_temp;num=1;for(int i=1;i<6;i++){x_temp1-=1;if(y_temp1<0 || x_temp1<0)break;if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++;elsebreak;}//判断右下x_temp1=x_temp;y_temp1=y_temp;for(int i=1;i<6;i++){x_temp1+=1;y_temp1+=1;if(y_temp1>this.height || x_temp1>this.width) break;if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++;elsebreak;}if(num==5)return true;//判断右上x_temp1=x_temp;y_temp1=y_temp;num=1;for(int i=1;i<6;i++){x_temp1+=1;y_temp1-=1;if(y_temp1<0 || x_temp1>this.width)break;if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++;elsebreak;}//判断左下x_temp1=x_temp;y_temp1=y_temp;for(int i=1;i<6;i++){x_temp1-=1;y_temp1+=1;if(y_temp1>this.height || x_temp1<0)break;if(this.arrMapShow[x_temp1][y_temp1]==arrvalue)num++;elsebreak;}if(num==5)return true;return false;}//赢棋后的提示public void showSuccess(JPanel jp){JOptionPane.showMessageDialog(jp,"你赢了,好厉害!","win",RMATION_MESSAGE);}//输棋后的提示public void showDefeat(JPanel jp){JOptionPane.showMessageDialog(jp,"你输了,请重新开始!","lost",RMATION_MESSAGE);}}/**类MainPanel主要完成如下功能:*1、构建一个面板,在该面板上画上棋盘;*2、处理在该棋盘上的鼠标事件(如鼠标左键点击、鼠标右键点击、鼠标拖动等)**/class MainPanel extends JPanelimplements MouseListener,MouseMotionListener{private int width,height;//棋盘的宽度和高度private ChessModel cm;//根据棋盘模式设定面板的大小MainPanel(ChessModel mm){cm=mm;width=cm.getWidth();height=cm.getHeight();addMouseListener(this);}//根据棋盘模式设定棋盘的宽度和高度public void setModel(ChessModel mm){cm = mm;width = cm.getWidth();height = cm.getHeight();}//根据坐标计算出棋盘方格棋子的信息(如白子还是黑子),//然后调用draw方法在棋盘上画出相应的棋子public void paintComponent(Graphics g){super.paintComponent(g);for(int j = 0; j <= height; j++){for(int i = 0; i <= width; i++){int v = cm.getarrMapShow()[i][j];draw(g, i, j, v);}}}//根据提供的棋子信息(颜色、坐标)画棋子public void draw(Graphics g, int i, int j, int v){int x = 20 * i+20;int y = 20 * j+20;//画棋盘if(i!=width && j!=height){g.setColor(Color.white);g.drawRect(x,y,20,20);}//画黑色棋子if(v == 1 ){g.setColor(Color.gray);g.drawOval(x-8,y-8,16,16);g.setColor(Color.black);g.fillOval(x-8,y-8,16,16);}//画白色棋子if(v == 2 ){g.setColor(Color.gray);g.drawOval(x-8,y-8,16,16);g.setColor(Color.white);g.fillOval(x-8,y-8,16,16);}if(v ==3){g.setColor(Color.cyan);g.drawOval(x-8,y-8,16,16);}}//响应鼠标的点击事件,根据鼠标的点击来下棋,//根据下棋判断胜负等public void mousePressed(MouseEvent evt){int x = (evt.getX()-10) / 20;int y = (evt.getY()-10) / 20;System.out.println(x+" "+y);if (evt.getModifiers()==MouseEvent.BUTTON1_MASK){cm.play(x,y);System.out.println(cm.getisOdd()+" "+cm.getarrMapShow()[x][y]);repaint();if(cm.judgeSuccess(x,y,cm.getisOdd())){cm.showSuccess(this);evt.consume();ChessFrame.iscomputer=false;}//判断是否为人机对弈if(ChessFrame.iscomputer&&!cm.getisExist()){puterDo(cm.getWidth(),cm.getHeight());repaint();if(cm.judgeSuccess(cm.getX(),cm.getY(),cm.getisOdd())){cm.showDefeat(this);evt.consume();}}}}public void mouseClicked(MouseEvent evt){}public void mouseReleased(MouseEvent evt){}public void mouseEntered(MouseEvent mouseevt){}public void mouseExited(MouseEvent mouseevent){}public void mouseDragged(MouseEvent evt){}//响应鼠标的拖动事件public void mouseMoved(MouseEvent moveevt){int x = (moveevt.getX()-10) / 20;int y = (moveevt.getY()-10) / 20;cm.readyplay(x,y);repaint();}}class ChessWindowEvent extends WindowAdapter{ public void windowClosing(WindowEvent e){ System.exit(0);}ChessWindowEvent(){}}。

五子棋游戏实践报告

五子棋游戏实践报告

计算机实习报告姓名:班级:学号:小班序号:指导老师:题目:五子棋游戏平台:MFC基于对话框程序邮箱:五子棋游戏实验报告一.功能说明1.1总体功能说明五子棋是一种两人对弈的纯策略型棋类游戏,起源于中国古代的传统黑白棋种之一。

本次实验,我设计的是人机对弈游戏,棋盘规格为14*14,棋子放置于方格内,当某一方有五个棋子连成一条直线时,即为获胜者。

游戏者在完成一局后可以在界面上选择重新开始进行下一次游戏。

1.2用户界面该界面可以为游戏界面,可直接点击开始进行五子棋游戏,游戏者开始可以点击任意方格放置第一枚棋子,计算机也会随之放置棋子的,游戏会随着游戏者和计算机交替下棋而进行的。

游戏结束后,可以选择重新开始进行下一轮游戏,也可以点击结束离开游戏界面。

1.3使用方法通过在某一点点击鼠标选择你想要放置棋子的位置,来达到五子连珠的效果。

一局结束后,游戏者可以选择重新开始进行下一次游戏。

二.程序设计说明2.1 总体设计框架工程项目的主要框架式基于基于对话框的MFC平台,当工程创建成功之后,基类CDialog和派生类类CAboutDlg,CMyDlg已经创建成功。

从整个程序上来看可以分成以下几个主要的板块。

一,游戏机界面的设计:通过创建了按钮并设置属性来完成按钮所实现的功能。

二,实现加载位图和相应鼠标点击来设计游戏画面:通过CBitmap函数来加载bmp图片素材,当鼠标指向棋盘内显示手拿黑白棋子的位图,游戏者通过点击鼠标左键来放置棋子。

三,找出所有五子连珠的结果,并用数组标记出来。

四,计算计算机放置棋子的位置:通过评定计算机和游戏者的赢得可能性谁比较大,来选定计算机是防守还是进攻;然后计算计算机的最佳落子点,即权值最大点。

五,显示游戏界面:每当放置一个棋子,如果双方都没有赢,就显示当前页面。

如果任意一方获胜,则停止游戏,成一条线的棋子显示为红色,弹出对话框显示游戏结束。

程序执行流程:2.2 关键算法描述算法1:设置鼠标左键单击落下棋子。

C语言五子棋源代码_设计报告1

C语言五子棋源代码_设计报告1

C语言五子棋源代码_设计报告1C语言五子棋源代码_设计报告1设计报告一、概述本项目是一个基于C语言的五子棋游戏,实现了双人对战的功能。

通过控制台界面显示棋盘和棋子,并进行相应的逻辑判断,以确定游戏的胜负。

二、设计思路1.棋盘的显示使用二维数组来表示棋盘,通过循环遍历数组并打印相应的字符来显示棋盘。

2.棋子的放置根据玩家的输入即坐标位置,在对应的数组下标位置放置相应的字符表示棋子。

3.游戏逻辑设计了胜利的条件判断函数,通过检查棋盘中的连续五个相同的字符来判断是否已经获胜。

4.玩家输入的处理使用循环来等待玩家输入,输入合法的坐标后进行相应的处理,包括棋盘上棋子的放置、胜利判断以及游戏结束的处理。

5.游戏结束的判断游戏结束时,根据胜利的条件判断结果进行相应的处理,可以继续游戏或退出游戏。

三、关键函数说明1. void displayBoard(char board[ROW][COL])该函数用于显示棋盘,根据棋盘数组的值打印相应的字符来显示棋盘。

2. int isWin(char board[ROW][COL], int x, int y)该函数用于判断当前位置的棋子是否连成五子线,如果是胜利则返回1,否则返回0。

3. void playerMove(char board[ROW][COL], int player)该函数用于玩家输入坐标,并将相应的棋子放置在棋盘上,同时进行胜利判断。

4. void playGame该函数用于游戏的整体流程,循环进行玩家的输入和处理,直到出现胜利或平局。

四、总结通过本项目的设计和实现,我进一步熟悉了C语言的编程技巧和逻辑思维,学会了如何通过编写函数来组织代码和实现功能。

同时,我也了解了五子棋游戏的规则和胜利判断的逻辑。

通过不断调试和优化代码,我成功地实现了一个简单但完整的五子棋游戏,提升了自己的编程能力和解决问题的能力。

这个项目的完成使我对C语言的应用有了更加深入的理解,也锻炼了我的团队合作和解决问题的能力。

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

1.五子棋对战说明2.实验报告3.源代码五子棋作品特点:C语言程序五子棋作品功能:五子棋人机对战,人人对战。

目录:1 五子棋介绍。

2五子棋棋型介绍。

3人人对战的实现。

4电脑下子的实现。

5棋型价值的计算。

6胜利及棋型的判断。

7补充说明1五子棋介绍。

五子棋是一种两人对弈的纯策略型棋类游戏。

只要任意一方在棋盘上且同一个回合上连为五子为胜。

还有禁手规则,在本程序中不作讨论。

2五子棋棋型介绍。

本程序中的棋型均为本人自定义。

本程序总共设计35种棋型。

●表示玩家的棋子,◎表示电脑的棋子。

以下称电脑方为己方,玩家方为对方。

从一空点向某一方向判断该方向的棋型。

某一方向指1-8方向从右顺时针开始数。

(1)空棋型。

从一空点向一方向看连续2个为空的棋型。

空棋型共1种。

如图,从左端的空点向右看会发现有连续2个空点。

(2)活棋型。

2端无挡的棋型为活棋型。

活棋型共8种:己方4种,对方4种。

左图为己活3 。

从左端的空点向右看会发现己方有连续的3个子,且右端无挡。

故该点的1方向为己活3。

左图为对活2(3)冲棋型。

1端无挡的棋型为冲棋型。

冲棋型共9种:己方4种,对方4种,边界1种。

左图为边界冲棋型。

空点的右端为边界。

或左图为己冲2。

从左端的空点向右看会发现己方有连续的2个子,且右端有挡(此处有挡表示有对方的子或为边界)。

故该点的1方向为己冲2。

左图为对冲4。

(4)空活棋型。

从一空点向一方向看有1个空点,继续看有己方或对方的活棋型。

空活棋型共8种:己方4种,对方4种。

左图为己空活2。

从左端的空点向右看有1个空点,继续看会发现己方有连续的2个子,且右端无挡。

故该点的1方向为己空活2。

左图为对空活1。

(5)空冲棋型。

从一空点向一方向看有1个空点,继续看有己方或对方或边界冲棋型。

空冲棋型共9种:己方4种,对方4种,边界1种。

左图为边界空冲棋型。

空点的右端为空点再右看为边界。

或左图为己空冲2。

从左端的空点向右看有1个空点,继续看会发现己方有连续的2个子,且右端有挡。

故该点的1方向为己空冲2。

3人人对战的实现。

双方玩家轮流下子,直到一方形成五连即判为胜方。

下子时输入棋盘上显示的对应坐标。

如果某方需要悔棋,则输入15 15 即可。

悔棋只能悔一步。

在人机对战中亦可悔棋。

4电脑下子的实现。

人机对战中电脑下子是通过AI(int *p,int *q)这个函数实现的。

用p 、q返回下子的坐标。

先历遍棋盘上所有点,如发现一个空点则调用函数value(int p,int q)计算该空点的价值。

每个点又由8个方向的棋型组成。

调用函数qixing(int n,int p,int q)判断空点p q在n方向上的棋型号。

对每种棋型进行赋值,然后对各个方向的棋型进行分析。

最后计算出该空点的价值。

如此找到棋盘上价值最大的空点,则电脑在该处下子。

5 棋型价值的计算。

棋型价值的计算是通过函数value(int p,int q)实现的。

先调用函数qixing(int n,int p,int q) 判断空点p q在n 方向上的棋型号。

n为1-8方向从右顺时针开始数。

对8个方向的棋型进行分析后给出该点的价值。

各种棋型的价值存在数组a[2][4][4]中。

本程序将两相反方向的棋型进行合在一起进行分析。

本程序分为六类进行讨论。

①空棋型and其他。

②边界冲棋型and其他。

③边界空冲棋型and其他。

④己活己活己活己冲对活对活对活对冲。

⑤己活对活己活对冲己冲对活己冲对冲。

⑥其他棋型。

⑦6 胜利及棋型的判断。

胜利及棋型的判断都调用了函数yiwei(int n,int *i,int *j)。

在n方向上对坐标i j 移位。

n为1-8方向从右顺时针开始数。

胜利的判断:每下一次子从该点向1方向移位,移位后判断新点是否与下的子相同。

如相同则继续移位判断,否则转向判断即n+=4;如转向后仍然没五连,则换下一个方向判断即n-=3;直到出现五连则胜利,如果8个方向判断完都没有五连则返回0,表示还未胜利。

棋型的判断:棋型的判断主要运用switch语句。

在某一方向移位后判断该点的状态。

最后得出该方向上的棋型号。

7补充说明1.在WIN7环境下用VC++运行棋盘之间有空隙,影响美观。

建议在XP操作系统下运行。

2.程序经过多次修改。

各次修改如下:V1.1 修改了胜负判断函数win的算法。

V1.2 加上了人人对战的功能,并加上了开始界面。

V1.3 增加了一些注释,并对棋型值数组做了更改。

V1.4 修正了2个BUG,进一步对棋型值数组做了更改。

V1.5 修改了画棋盘draw的算法,改变了主函数main,增加函数start,并增加了赢棋之后是否继续的功能,还完善了各棋型的赋值,进一步对棋型值数组做了更改。

实验报告2014 –2015 学年第一学期任课老师:结果:人人对战总结以及心得体会经过本次试验,我c语言的应用了,以前只是编写一些小小的程序,现在可以利用简单的c程序可以做出稍微大型一点的程序,像五子棋这种游戏想想我们玩的时候感觉很奇妙,但是经过我的深思熟虑我也可以在计算机用简单的c语言给搞定了,我们有时感觉一个小小的游戏玩的时候感觉很简单,但是在用代码实现的时候却发现考虑的东西很多,不然那个游戏的bug就会很多,得经过好多实例的检验。

只有这样我们才能让程序按照我们的意愿去实现它的功能!源码:#include "windows.h" #include "stdio.h"#include "conio.h"#define up 'w'#define left 'a'#define down 's'#define right 'd'#define lz 'p'#define cls 'm'# define SPA 0# define MAN 1# define COM 2 /* 空位置设为0 ,玩家下的位置设为1 ,电脑下的位置设为2 */struct stu //定义位置记录结构体{int x;int y;}weizhi;int player=0;int Q[15][15]={0}; //定义数组以记录落子情况void gotoxy(int x, int y) ;//建立坐标函数void drawqipan(); //绘制棋盘及数据初始化void jilu(); //人机记录落子情况int cluozi(int x,int y); //由电脑落子时调用void luozi(); //人机玩家落子int checkWin(); //检查游戏是否有输赢void Keypress(char n); //人机光标位置移动void Keypress1(char n); //人人光标位置移动void yiwei(int n,int *i,int *j); /* 在n方向上对坐标i j 移位n为1-8方向从右顺时针开始数*/int qixing(int n,int p,int q) ; /* 返回空点p q在n方向上的棋型号n为1-8方向从右顺时针开始数*/int value(int p,int q); /* 计算空点p q的价值以k返回*/void AI(int *p,int *q);/* 电脑下子*p *q返回下子坐标*/void luozi1(); //人人玩家落子void jilu1(); //人人记录落子情况void gotoxy(int x, int y) //建立坐标函数{COORD c;c.X=2*x;c.Y=y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c); //修改当前光标的位置}void drawqipan() //绘制棋盘及数据初始化{int i,j;system("cls"); //清除屏幕for(i=0;i<15;i++){for(j=0;j<15;j++){Q[i][j]=0;printf("十");}printf("\n");}weizhi.x=6;weizhi.y=6; //程序数据初始化gotoxy(6,6);}void jilu() //记录落子情况{Q[weizhi.y][weizhi.x]=player+1;if(player==1) player=0; //玩家变换else player=1;}void jilu1() //记录落子情况{Q[weizhi.x][weizhi.y]=player+1;if(player==1) player=0; //玩家变换else player=1;}int cluozi(int x,int y) //由电脑落子时调用{weizhi.x=x;weizhi.y=y;gotoxy(weizhi.x,weizhi.y);jilu();printf("○");gotoxy(weizhi.x,weizhi.y);}void luozi() //玩家落子{if(Q[weizhi.y][weizhi.x]==0) //判断当前位置是否已经落子{gotoxy(weizhi.x,weizhi.y);jilu();printf("●");gotoxy(weizhi.x,weizhi.y);}}void luozi1() //玩家落子{if(Q[weizhi.x][weizhi.y]==0) //判断当前位置是否已经落子{if(player){jilu1();printf("●");}else{jilu1();printf("○");}gotoxy(weizhi.x,weizhi.y);}}int checkWin() //检查游戏是否有输赢{int p;int r,c,rr,cc,count=0;p=player==0?2:1;for(c=0;c<15;c++){for(r=0;r<15;r++){if(Q[r][c]!=p)continue;//检查列rr=r;cc=c;while(--cc>=0 &&Q[rr][cc]==p)count++; cc=c;while(++cc<15 &&Q[rr][cc]==p)count++; cc=c;if(count+1>=5)return p;//检查行count=0;while(--rr>=0 &&Q[rr][cc]==p)count++; rr=r;while(++rr<15 &&Q[rr][cc]==p)count++; rr=r;if(count+1>=5)return p;//检查反斜边count=0;cc--;rr--;while((cc>=0||rr>=0)&&Q[rr][cc]==p){count++;cc--;rr--;} rr=r;cc=c;cc++;rr++;while((cc<15||rr<15)&&Q[rr][cc]==p){count++;cc++;rr++;} rr=r;cc=c;if(count+1>=5)return p;count=0;//检查正斜边count=0;cc++;rr--;while((cc<15||rr>=0)&&Q[rr][cc]==p){count++;cc++;rr--;} rr=r;cc=c;cc--;rr++;while((cc>=0||rr<15)&&Q[rr][cc]==p){count++;cc--;rr++;} rr=r;cc=c;if(count+1>=5)return p;count=0;}}return 0;}void Keypress(char n) //光标位置移动{switch(n){case up:weizhi.y--;gotoxy(weizhi.x,weizhi.y);break;//向上移动光标case left:weizhi.x--;gotoxy(weizhi.x,weizhi.y);break;//向左移动光标case right: weizhi.x++;gotoxy(weizhi.x,weizhi.y);break;//向右移动光标case down: weizhi.y++;gotoxy(weizhi.x,weizhi.y);break;//向下移动光标case lz:luozi();break;//开始落子操作case cls:drawqipan();break;//重新开始}}void Keypress1(char n) //光标位置移动{switch(n){case up:if(weizhi.y<=0)weizhi.y=14;else weizhi.y--;gotoxy(weizhi.x,weizhi.y);break;//向上移动光标case left:if(weizhi.x<=0)weizhi.x=14;else weizhi.x--;gotoxy(weizhi.x,weizhi.y);break;//向左移动光标case right:if(weizhi.x>=14)weizhi.x=0;elseweizhi.x++;gotoxy(weizhi.x,weizhi.y);break;//向右移动光标case down:if(weizhi.y>=14)weizhi.y=0;else weizhi.y++;gotoxy(weizhi.x,weizhi.y);break;//向下移动光标case lz:luozi1();break;//开始落子操作case cls:drawqipan();break;//重新开始}}void yiwei(int n,int *i,int *j) /* 在n方向上对坐标i j 移位n为1-8方向从右顺时针开始数*/{switch(n){case 1:*i+=1;break;case 2:*i+=1;*j+=1;break;case 3:*j+=1;break;case 4:*i-=1;*j+=1;break;case 5:*i-=1;break;case 6:*i-=1;*j-=1;break;case 7:*j-=1;break;case 8:*i+=1;*j-=1;break;}}int qixing(int n,int p,int q) /* 返回空点p q在n方向上的棋型号n为1-8方向从右顺时针开始数*/{int k,m=0; /* 棋型号注解: 己活000-003 己冲010-013 对活100-103 对冲110-113 己空活020-023 己空冲030-033 对空活120-123 对空冲130-133 空-1 边界冲-2 边界空冲-3*/yiwei(n,&p,&q);if(p<0||p>14||q<0||q>14) k=-2; /* 边界冲棋型*/switch(Q[q][p]){case COM:{m++;yiwei(n,&p,&q);if(p<0||p>14||q<0||q>14){k=m+9;return k;}while(Q[q][p]==COM){m++;yiwei(n,&p,&q);if(p<0||p>14||q<0||q>14){k=m+9;return k;}}if(Q[q][p]==0) k=m-1; /* 己方活棋型*/else k=m+9; /* 己方冲棋型*/}break;case MAN:{m++;yiwei(n,&p,&q);if(p<0||p>14||q<0||q>14){k=m+109;return k;}while(Q[q][p]==MAN){m++;yiwei(n,&p,&q);if(p<0||p>14||q<0||q>14){k=m+109;return k;}}if(Q[q][p]==SPA) k=m+99; /* 对方活棋型*/else k=m+109; /* 对方冲棋型*/}break;case SPA:{yiwei(n,&p,&q);if(p<0||p>14||q<0||q>14){k=-3; /* 边界空冲棋型*/return k;}switch(Q[q][p]){case COM:{m++;yiwei(n,&p,&q);if(p<0||p>14||q<0||q>14){k=m+29;return k;}while(Q[q][p]==COM){m++;yiwei(n,&p,&q);if(p<0||p>14||q<0||q>14){k=m+29;return k;}}if(Q[q][p]==SPA) k=m+19; /* 己方空活棋型*/else k=m+29; /* 己方空冲棋型*/}break;case MAN:{m++;yiwei(n,&p,&q);if(p<0||p>14||q<0||q>14){k=m+129;return k;}while(Q[q][p]==MAN){m++;yiwei(n,&p,&q);if(p<0||p>14||q<0||q>14){k=m+129;return k;}}if(Q[q][p]==SPA) k=m+119; /* 对方空活棋型*/else k=m+129; /* 对方空冲棋型*/}break;case SPA:k=-1;break;/* 空棋型*/}}break;}return k;}int value(int p,int q) /* 计算空点p q的价值以k返回*/{int n=1,k=0,k1,k2,K1,K2,X1,Y1,Z1,X2,Y2,Z2,temp;int a[2][4][4]= {40,400,3000,10000,6,10,600,10000,20,120,200,0,6,10,500,0,30,300,2500,500 0,2,8,300,8000,26,160,0,0,4,20,300,0};/* 数组a中储存己方和对方共32种棋型的值己方0对方1 活0冲1空活2空冲3 子数0-3(0表示1个子,3表示4个子)*/while(n!=5){k1=qixing(n,p,q);n+=4; /* k1,k2为2个反方向的棋型编号*/k2=qixing(n,p,q);n-=3;if(k1>k2){temp=k1; /* 使编号小的为k1,大的为k2 */k1=k2;k2=temp;}K1=k1;K2=k2; /* K1 K2储存k1 k2的编号*/Z1=k1%10;Z2=k2%10;k1/=10;k2/=10;Y1=k1%10;Y2=k2%10;k1/=10;k2/=10;X1=k1%10;X2=k2%10;/* X Y Z分别表示己方0对方1 活0冲1空活2空冲3 子数0-3(0表示1个子,3表示4个子)*/if(K1==-1){if(K2<0){k+=0;continue;}else k+=a[X2][Y2][Z2]+5;continue;}; /* 空棋型and其他*/if(K1==-2){if(K2<0){k+=0;continue;}else k+=a[X2][Y2][Z2]/2;continue;}; /* 边界冲棋型and其他*/ if(K1==-3){if(K2<0){k+=0;continue;}else k+=a[X2][Y2][Z2]/3;continue;}; /* 边界空冲棋型and其他*/if(((K1>-1&&K1<4)&&((K2>-1&&K2<4)||(K2>9&&K2<14)))||((K1>99&&K1 <104)&&((K2>99&&K2<104)||(K2>109&&K2<114)))){/* 己活己活己活己冲对活对活对活对冲的棋型赋值*/if(Z1+Z2>=2){k+=a[X2][Y2][3];continue;}else{k+=a[X2][Y2][Z1+Z2+1];continue;}}if(((K1>9&&K1<14)&&(K2>9&&K2<14))||((K1>109&&K1<114)&&(K2>109 &&K2<114))){/* 己冲己冲对冲对冲的棋型赋值*/if(Z1+Z2>=2){k+=10000;continue;}else{k+=0;continue;}}if(((K1>-1&&K1<4)&&((K2>99&&K2<104)||(K2>109&&K2<114)))||((K1>9 &&K1<14)&&((K2>99&&K2<104)||(K2>109&&K2<114)))){/* 己活对活己活对冲己冲对活己冲对冲的棋型赋值*/if(Z1==3||Z2==3){k+=10000;continue;}else{k+=a[X2][Y2][Z2]+a[X1][Y1][Z1]/4;continue;}}else{k+=a[X1][Y1][Z1]+a[X2][Y2][Z2]; /* 其他棋型的赋值*/continue;}}return k;}void AI() /* 电脑下子*p *q返回下子坐标*/{int i,j,k,max=0,I,J; /* I J为下点坐标*/for(j=0; j<15; j++){for(i=0; i<15; i++){if(Q[j][i]==0) /* 历遍棋盘,遇到空点则计算价值,取最大价值点下子。

相关文档
最新文档