期末课程设计之java实现五子棋的人机和人人对战
来源:互联网 发布:我知女人心电影插曲 编辑:程序博客网 时间:2024/04/30 05:00
五子棋人机实现和人人实现(java)
一.这学期期末课程设计选题选的是《用java完成五子棋人机以及人人对战》。其中人人主要是java的网络编程,运用UDP,socket来传输数据,每当有一方下棋,那么就会发送下棋一方的位置信息,这部分主要是调试比较麻烦,需要用两台电脑(一台电脑也可以实现);人机的主要难点在于电脑怎么下棋,这有点类似于人工智能了(就像机器人怎么走路),其实这是程序最精华的部分,你的人机要够聪明。我这里写的人机比较简单,大概是入门偏上的等级,其中主要的思路是在别的博客上习得。下面贴出代码:主要看中级人机部分代码吧,这里说下大概思路,首先需要遍历棋盘上每个位置(这里我的棋盘大小是19*19),对于每一个位置都需要给他计分,具体计分方法是这样的,在当前位置向八个方向遍历,如:向上遍历有3个白棋,那么这个位置的分数很高,因为活四(百度搜索一下五子棋基本术语以及含义)就是必赢了,以此类推可以算出每个位置的分数,当然这个分数有两种,一种是相对于白棋,另一种是相对于黑棋,最后要比较这两种分数,最后找到棋盘上分数最高的点,电脑就下在这了。如果我的代码晦涩难懂,那么我强力推荐一篇csdn博客点击打开链接,写的非常好。
package Model;import View.ChooseLevel;/** * Created by Blossoming on 2016/12/6. */public class Computer { private int test=0; private int scores; private Coord coord=new Coord(); private int everyPlayerPointScore[][]=new int[19][19]; private int everyComputerPointScore[][]=new int[19][19]; /** * 计算下棋位置 * @param role 角色 chess[][]棋盘 */ public Coord computePos(int role,int chess[][],int level) { int x, y, posX, posY; //初级 if(level== ChooseLevel.PRIMARY_LEVEL) { while (true) { posX = (int) (Math.random() * 10 + Math.random() * 9); posY = (int) (Math.random() * 10 + Math.random() * 9); if (chess[posX][posY] == Chess.NO_CHESS) { coord.setX(posX); coord.setY(posY); return coord; } } } //中级 else if(level==ChooseLevel.MEDIUM_LEVEL) { countMaxLines_primary(chess, Chess.WHITE); return coord; } else if(level==ChooseLevel.SENIOR_LEVEL) { countMaxLines_medium(chess,Chess.WHITE); return coord; } return coord; } /**********************下面是中级人机*************************************/ /** * 找出分数最大的坐标 * @param chess 棋盘数组 * @param role 白棋还是黑棋 */ public void countMaxLines_medium(int chess[][],int role) { Coord playerCoord=new Coord(); Coord computerCoord=new Coord(); int x,y; for(x=0;x<19;x++) { for(y=0;y<19;y++) { if(chess[x][y]==Chess.NO_CHESS) { countEveryPos_medium(x, y, chess, role); everyPlayerPointScore[x][y] = scores; countEveryPos_medium(x, y, chess, Chess.BLACK); everyComputerPointScore[x][y] = scores; } else { everyPlayerPointScore[x][y]=0; everyComputerPointScore[x][y]=0; } } } if(findBestPos_medium(everyPlayerPointScore, playerCoord)>=findBestPos(everyComputerPointScore,computerCoord)) { coord=playerCoord; } else { coord=computerCoord; } } /** * 找到最大分数点的坐标 * @param a 数组 存储每个点的分数 * @param c 保存最大分数点的坐标 * @return */ public int findBestPos_medium(int a[][],Coord c) { int i,j,max=0; for(i=0;i<19;i++) { for(j=0;j<19;j++) { if(a[i][j]>max) { max=a[i][j]; c.setX(i); c.setY(j); } } } return max; } /** * 估分函数 * @param count 每一个方向上的相同颜色的总个数 * @param i 不同颜色的个数 */ public void mark_medium(int count,int i,int countTwo,int role) { if(count==1) { scores=scores+10; } //活二 else if(count==2&&i==0&&role==Chess.WHITE&&countTwo<=1) { scores=scores+200; //System.out.println("白子活二"+scores); } else if(count==2&&i==0&&role==Chess.BLACK&&countTwo<=1) { scores=scores+400; // System.out.println("黑子活二"+scores); } //冲二 else if(count==2&&i==1) { scores=scores+50; // System.out.println("冲二"+scores); } //双活二 else if(count==2&&i==0&&countTwo>1) { scores=scores+84000; System.out.println("双活二"+scores); } //活三(黑子和白子同时活三的时候选择黑子成) else if(count==3&&i==0&&role==Chess.WHITE) { scores=scores+85000; //System.out.println("白子活三"+scores); } else if(count==3&&i==0&&role==Chess.BLACK) { scores=scores+86000; //System.out.println("黑子活三"+scores); } //冲三 else if(count==3&&i==1&&role==Chess.WHITE) { scores=scores+300; System.out.println("白子冲三"+scores); } else if(count==3&&i==1&&role==Chess.BLACK) { scores=scores+1000; System.out.println("黑子冲三"+scores); } //白子活四 else if(count==4&&i==0&&role==Chess.WHITE) { scores=scores+90000; //System.out.println("活四"+scores); } //黑子活四 else if(count==4&&i==0&&role==Chess.BLACK) { scores=scores+91000; } //冲四 else if(count==4&&i==1) { scores=scores+87000; //System.out.println("冲四"+scores); } else if(count==5) { scores=scores+100000; } } public void basicScore(int x,int y) { if(x==0||y==0) { scores=scores+3; } else { scores=scores+5; } } /** * 计算每个坐标的分数 * @param x * @param y * @param chess * @param role */ public void countEveryPos_medium(int x,int y,int chess[][],int role) { scores=0; basicScore(x,y); //countTwo代表有一个坐标向八个方向数 两个连一起的个数 int matchRole,startX=x,startY=y, count=0,up=0,down=0,left=0,right=0, leftUp=0,leftDown=0,rightUp=0,rightDown=0,countTwo=0; if(role==Chess.BLACK) { matchRole=Chess.WHITE; } else { matchRole=Chess.BLACK; } //竖直方向上判断输赢 while (true) { //向上判断 y--; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; } else if((x >= 0 && x < 19 && y >= 0 && y < 19 &&chess[x][y]==matchRole)||y<0){ up++; break; } else { break; } } y = startY; while (true) { //向下判断 y = y + 1; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; } else if((x >= 0 && x < 19 && y >= 0 && y < 19 &&chess[x][y]==matchRole)||y>19){ down++; break; } else { break; } } //此处代表在上下方向有二连 或者 夹了一个空子两边各有一个棋子 并且两端没有其他子挡住 if(count==2&&(up+down==0)) { countTwo++; //System.out.println("出现二连"+countTwo); } mark_medium(count, up + down, countTwo,role); //水平方向判断输赢 x = startX; y = startY; count = 0; while (true) { //向左判断 x--; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; }else if((x >= 0 && x < 19 && y >= 0 && y < 19 &&chess[x][y]==matchRole)||x==0){ left++; break; } else { break; } } x = startX; while (true) { //向右判断 x++; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; }else if((x >= 0 && x < 19 && y >= 0 && y < 19 &&chess[x][y]==matchRole)||x>19){ right++; break; } else { break; } } if(count==2&&(left+right==0)) { countTwo++; //System.out.println("出现二连"+countTwo); } mark_medium(count, left + right, countTwo,role); //右倾斜方向判断输赢 x = startX; y = startY; count = 0; while (true) { //向左上判断 y--; x--; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; } else if((x >= 0 && x < 19 && y >= 0 && y < 19 &&chess[x][y]==matchRole)||x<0||y<0){ leftUp++; break; } else { break; } } x = startX; y = startY; while (true) { //向右下判断 x++; y++; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; } else if((x >= 0 && x < 19 && y >= 0 && y < 19 &&chess[x][y]==matchRole)||x>19||y>19){ rightDown++; break; } else { break; } } if(count==2&&(leftUp+rightDown==0)) { countTwo++; // System.out.println("出现二连"+countTwo); } mark_medium(count, leftUp + rightDown, countTwo,role); //左倾斜方向判断 x = startX; y = startY; count = 0; while (true) { //向左下判断 x--; y++; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; } else if((x >= 0 && x < 19 && y >= 0 && y < 19 &&chess[x][y]==matchRole)||x<0||y>19){ leftDown++; break; } else { break; } } x = startX; y = startY; while (true) { //向右上判断 x++; y--; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; }else if((x >= 0 && x < 19 && y >= 0 && y < 19 &&chess[x][y]==matchRole)||x>19||y<0){ rightUp++; break; } else { break; } } if(count==2&&(leftDown+rightUp==0)) { countTwo++; // System.out.println("出现二连"+countTwo); } mark_medium(count, leftDown + rightUp, countTwo,role); } /*********************下面是初级人机*************************************/ /** * 找出分数最大的坐标 * @param chess 棋盘数组 * @param role 白棋还是黑棋 */ public void countMaxLines_primary(int chess[][],int role) { Coord playerCoord=new Coord(); Coord computerCoord=new Coord(); int x,y; for(x=0;x<19;x++) { for(y=0;y<19;y++) { if(chess[x][y]==Chess.NO_CHESS) { countEveryPos_primary(x, y, chess, role); everyPlayerPointScore[x][y] = scores; countEveryPos_primary(x, y, chess, Chess.BLACK); everyComputerPointScore[x][y] = scores; } else { everyPlayerPointScore[x][y]=0; everyComputerPointScore[x][y]=0; } } } if(findBestPos(everyPlayerPointScore,playerCoord)>=findBestPos(everyComputerPointScore,computerCoord)) { coord=playerCoord; } else { coord=computerCoord; } } /** * 找到最大分数点的坐标 * @param a 数组 存储每个点的分数 * @param c 保存最大分数点的坐标 * @return */ public int findBestPos(int a[][],Coord c) { int i,j,max=0; for(i=0;i<19;i++) { for(j=0;j<19;j++) { if(a[i][j]>max) { max=a[i][j]; c.setX(i); c.setY(j); } } } return max; } /** * 估分函数 * @param count 每一个方向上的相同颜色的总个数 * @param i 不同颜色的个数 */ public void mark_primary(int count,int i) { if(count==1) { scores=scores+10; } //活二 else if(count==2&&i==0) { scores=scores+200; } //冲二 else if(count==2&&i==1) { scores=scores+50; } //活三 else if(count==3&&i==0) { scores=scores+85000; System.out.println("分数"+scores); } //冲三 else if(count==3&&i==1) { scores=scores+150; System.out.println("分数"+scores); } //活四 else if(count==4&&i==0) { scores=scores+90000; System.out.println("分数"+scores); } //冲四 else if(count==4&&i==1) { scores=scores+87000; System.out.println("分数"+scores); } else if(count==5) { scores=scores+100000; } } /** * 计算每个坐标的分数 * @param x * @param y * @param chess * @param role */ public void countEveryPos_primary(int x,int y,int chess[][],int role) { scores=0; int matchRole,startX=x,startY=y,count=0,up=0,down=0,left=0,right=0,leftUp=0,leftDown=0,rightUp=0,rightDown=0; if(role==Chess.BLACK) { matchRole=Chess.WHITE; } else { matchRole=Chess.BLACK; } //竖直方向上判断输赢 while (true) { //向上判断 y--; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; } else if(x >= 0 && x < 19 && y >= 0 && y < 19 &&chess[x][y]==matchRole){ up++; break; } else { break; } } y = startY; while (true) { //向下判断 y = y + 1; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; } else if(x >= 0 && x < 19 && y >= 0 && y < 19 &&chess[x][y]==matchRole){ down++; break; } else { break; } } mark_primary(count, up + down); //水平方向判断输赢 x = startX; y = startY; count = 0; while (true) { //向左判断 x--; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; }else if(x >= 0 && x < 19 && y >= 0 && y < 19 &&chess[x][y]==matchRole){ down++; break; } else { break; } } x = startX; while (true) { //向右判断 x++; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; }else if(x >= 0 && x < 19 && y >= 0 && y < 19 &&chess[x][y]==matchRole){ right++; break; } else { break; } } mark_primary(count, left + right); //右倾斜方向判断输赢 x = startX; y = startY; count = 0; while (true) { //向左上判断 y--; x--; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; } else if(x >= 0 && x < 19 && y >= 0 && y < 19 &&chess[x][y]==matchRole){ leftUp++; break; } else { break; } } x = startX; y = startY; while (true) { //向右下判断 x++; y++; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; } else if(x >= 0 && x < 19 && y >= 0 && y < 19 &&chess[x][y]==matchRole){ rightDown++; break; } else { break; } } mark_primary(count, leftUp + rightDown); //左倾斜方向判断 x = startX; y = startY; count = 0; while (true) { //向左下判断 x--; y++; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; } else if(x >= 0 && x < 19 && y >= 0 && y < 19 &&chess[x][y]==matchRole){ leftDown++; break; } else { break; } } x = startX; y = startY; while (true) { //向右上判断 x++; y--; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; }else if(x >= 0 && x < 19 && y >= 0 && y < 19 &&chess[x][y]==matchRole){ rightUp++; break; } else { break; } } mark_primary(count, leftDown +rightUp); }/* public void countEveryPos(int x,int y,int chess[][],int role) { scores=0; int startX=x,startY=y,count=0; //竖直方向上判断输赢 while (true) { //向上判断 y--; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; } else { break; } } y = startY; while (true) { //向下判断 y = y + 1; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; } else { break; } } mark(count); //水平方向判断输赢 x = startX; y = startY; count = 0; while (true) { //向左判断 x--; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; } else { break; } } x = startX; while (true) { //向右判断 x++; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; } else { break; } } mark(count); //右倾斜方向判断输赢 x = startX; y = startY; count = 0; while (true) { //向左上判断 y--; x--; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; } else { break; } } x = startX; y = startY; while (true) { //向右下判断 x++; y++; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; } else { break; } } mark(count); //左倾斜方向判断 x = startX; y = startY; count = 0; while (true) { //向左下判断 x--; y++; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; } else { break; } } x = startX; y = startY; while (true) { //向右上判断 x++; y--; if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) { count++; } else { break; } } mark(count); }*/}二.全部代码在百度网盘链接:http://pan.baidu.com/s/1kVG1xCN 密码:9szs 下面贴出运行的截图
1.开始界面
2.人机界面
3.人人界面
三.总结
每次写课程设计总有一种应付感,实现了基本的功能之后就不再去完善它,这个程序有较多的bug,比如人
机对战中下在边缘位置的时候会出现很蠢的bug,还有人人对战的时候,当中途一方退出另一方并不知道。
1 0
- 期末课程设计之java实现五子棋的人机和人人对战
- NodeJS+html5+css3 带人机对战和人人对战的 五子棋
- java swing实现的人机对战五子棋
- 五子棋人机对战的实现
- 基于qt的五子棋 人人对战 人机对战 程序与程序对战
- 五子棋JAVA源码__支持人机、人人对战(转)
- 五子棋AI图形界面人机对战(JAVA实现)
- AI智能人机对战五子棋(Java实现图形界面)
- java 五子棋之人机对战思路详解
- 五子棋人人对战实现
- 百行内实现五子棋人机对战
- 人机对战五子棋
- java五子棋人机对战算法分析
- 一款简易五子棋,实现人机,人人功能。
- 五子棋人机对战的心得
- 五子棋代码人人、人机对战写完了、还少人机电脑的智能下棋功能,欢迎大家一起讨论分享、完善功能
- 五子棋 人人对战
- 五子棋人机对战思想
- Android内存优化(使用SparseArray和ArrayMap代替HashMap)
- (二十六)进程间通信——pipe管道
- Web App 开发
- CSS2的选择器
- ios 开发 app id 冲突
- 期末课程设计之java实现五子棋的人机和人人对战
- JDBC+C3P0连接Oracle,SID无效
- MySQL常用脚本
- JS实现点击复选框变更DIV显示状态实例
- swift中UITextView的使用
- 让lua的gc替我们回收c的堆变量
- Til the Cows Come Home (Digkstra邻接矩阵裸模板)
- 枚举-生成元3.5Digit generator
- I2C