- 浏览: 23049 次
- 性别:
- 来自: 杭州
五子棋总结
五子棋对我来说是第一个有关于算法的项目,也是第一个自己开始独立完成的项目。五子棋分为人人和人机两种版本。
但是在做之前都先要画棋盘,这个因为有前面画图板的经验,所以还相对于较容易实现,只要画直线就好,值得注意到是,我们可以先定义一个接口,将所以需要用到是数据都放在接口中,便于修改,而不需要在界面中进行修改:
只要主界面接这个接口就可以了。主界面中根据这些变量来画棋盘。在画棋子时,用鼠标监听器来监听点击的坐标。但是要计算好点击的是哪一个范围内就算哪一个点上落子。具体代码实现如下:
在鼠标监听器中,注意也要实现棋盘的重绘。
人人版显然相对较容易实现,只要实现判断落下棋子后是否有连成5个就可以了,相对来说只要遍历相对于这步棋的周围5步,看是否有连成5个即可以得到。
至于人机版,就需要有一个算法来计算当前游戏者落子后对于另一方比较有利的地方。因此可以考虑将整个棋盘可以下子的地方附上权值,每下一步并根据算法来更改棋盘上未落子的地方的权值,由此得到权值最大的地方就是最有利的下子地方,从而下子。这个算法便显的至关重要了,不仅要考虑下子后将周围的棋子的权值变大,还要考虑断三,活三等各种情况。因此分为进攻和防守两个算法。具体实行如下:
五子棋对我来说是第一个有关于算法的项目,也是第一个自己开始独立完成的项目。五子棋分为人人和人机两种版本。
但是在做之前都先要画棋盘,这个因为有前面画图板的经验,所以还相对于较容易实现,只要画直线就好,值得注意到是,我们可以先定义一个接口,将所以需要用到是数据都放在接口中,便于修改,而不需要在界面中进行修改:
public interface config { public static final int X0=50,Y0=50;//定义初始点位置 public static final int ROWS=13,COLUMNS=13;//定义横线和竖线的条数 public static final int SIZE=50;//定义棋盘单元格的大小 public static final int CHESS_SIZE=40;//定义棋子大小 public static final int[][] CHESS=new int[13][13];//定义一个数组来标记棋子 }
只要主界面接这个接口就可以了。主界面中根据这些变量来画棋盘。在画棋子时,用鼠标监听器来监听点击的坐标。但是要计算好点击的是哪一个范围内就算哪一个点上落子。具体代码实现如下:
在鼠标监听器中,注意也要实现棋盘的重绘。
public void mouseReleased(MouseEvent e) { // 画棋子 // 得到所点击处的坐标 int x1 = e.getX(); int y1 = e.getY(); // 计算所应摆放棋子的位置的单元格 int j = (x1 - X0) / SIZE; int i = (y1 - Y0) / SIZE; rules ru = new rules(); // 判断是否可以摆棋子 if (count == 1) { for (int k = 0; k < CHESS.length; k++) { for (int h = 0; h < CHESS[k].length; h++) { if (CHESS[k][h] == -1) { count2++; } } } } else { for (int k = 0; k < CHESS.length; k++) { for (int h = 0; h < CHESS.length; h++) { if (CHESS[k][h] == 1) { count1++; } } } } if (a || b == 1) { b++; // 判断此处是否可以摆放棋子 if (CHESS[i][j] == 0) { // 得到单元格的左上角坐标 int x2 = X0 + j * SIZE; int y2 = Y0 + i * SIZE; // 得到单元格的中心点坐标 int x3 = x2 + SIZE / 2; int y3 = y2 + SIZE / 2; a = ru.check(i, j, count); if (a) { if (count == 1) { g.setColor(Color.black); CHESS[i][j] = 1; count = -1; } else { g.setColor(Color.white); CHESS[i][j] = -1; count = 1; } // 绘制棋子 g.fillOval(x3 - CHESS_SIZE / 2, y3 - CHESS_SIZE / 2, CHESS_SIZE, CHESS_SIZE); javax.swing.SwingUtilities.updateComponentTreeUI(UI); } } } else { for (int k = 0; k < CHESS.length; k++) { for (int h = 0; h < CHESS.length; h++) { if (CHESS[k][h] == 1) { count1++; a = overt.chesstraver(k, h, count); } } } if (a) { if (CHESS[i][j] == 0) { // 得到单元格的左上角坐标 int x2 = X0 + j * SIZE; int y2 = Y0 + i * SIZE; // 得到单元格的中心点坐标 int x3 = x2 + SIZE / 2; int y3 = y2 + SIZE / 2; a = ru.check(i, j, count); if (a) { if (count == 1) { g.setColor(Color.black); CHESS[i][j] = 1; count = -1; } else { g.setColor(Color.white); CHESS[i][j] = -1; count = 1; } // 绘制棋子 g.fillOval(x3 - CHESS_SIZE / 2, y3 - CHESS_SIZE / 2, CHESS_SIZE, CHESS_SIZE); javax.swing.SwingUtilities.updateComponentTreeUI(UI); } } } } }
人人版显然相对较容易实现,只要实现判断落下棋子后是否有连成5个就可以了,相对来说只要遍历相对于这步棋的周围5步,看是否有连成5个即可以得到。
至于人机版,就需要有一个算法来计算当前游戏者落子后对于另一方比较有利的地方。因此可以考虑将整个棋盘可以下子的地方附上权值,每下一步并根据算法来更改棋盘上未落子的地方的权值,由此得到权值最大的地方就是最有利的下子地方,从而下子。这个算法便显的至关重要了,不仅要考虑下子后将周围的棋子的权值变大,还要考虑断三,活三等各种情况。因此分为进攻和防守两个算法。具体实行如下:
// 横向判断是否有5个棋子 public int checkROW(int x, int y, int color) { // 定义一个计数器 int count = 0; int i = y + 1; // 往右走 for (; i < CHESS.length; i++) { if ((CHESS[x][i] == CHESS[x][y]) && (CHESS[x][i] == color)) { count++; } else { break;// 只要有一颗棋子不同就退出循环 } } if (i < CHESS.length && count == 2) if ((CHESS[x][i] == CHESS[x][y]) && (CHESS[x][i] == color)) // 断3的处理方法 if ((CHESS[x][i - 1] != 1) && (CHESS[x][i - 1] != 1)) { CHESS[x][i - 1] = 10000; } // 往左走 for (i = y; i >= 0; i--) { if ((CHESS[x][i] == CHESS[x][y]) && (CHESS[x][i] == color)) { count++; } else { break; } } if (i >= 0 && count == 2) if ((CHESS[x][i] == CHESS[x][y]) && (CHESS[x][i] == color)) // 断3的处理方法 if ((CHESS[x][i + 1] != 1) && (CHESS[x][i + 1] != 1)) { CHESS[x][i + 1] = 10000; } // 连3的处理方法 if (count == 3) { if ((CHESS[x][y - 1] != 1) && (CHESS[x][y - 1] != -1) && (CHESS[x][y + 3] != -color)) { CHESS[x][y - 1] = 2000; } if ((CHESS[x][y + 1] != 1) && (CHESS[x][y + 1] != -1) && (CHESS[x][y - 3] != -color)) { CHESS[x][y + 1] = 2000; } } if (count == 4) { if ((CHESS[x][y - 1] != 1) && (CHESS[x][y - 1] != -1)) { CHESS[x][y - 1] = 100000; } if ((CHESS[x][y + 1] != 1) && (CHESS[x][y + 1] != -1)) { CHESS[x][y + 1] = 100000; } } return count;// 返回所数的个数 } // 纵向判断是否有5颗棋子 public int checkCOLUMNS(int x, int y, int color) { // 定义一个计数器 int count = 0; int i = x + 1; // 向上 for (; i < CHESS.length; i++) { if ((CHESS[i][y] == CHESS[x][y]) && (CHESS[i][y] == color)) { count++; } else { break; } } if (i < CHESS.length && count == 2) if ((CHESS[i][y] == CHESS[x][y]) && (CHESS[i][y] == color)) // 断3的处理方法 if ((CHESS[i - 1][y] != 1) && (CHESS[i - 1][y] != 1)) { CHESS[i - 1][y] = 100000; } // 向下 for (i = x; i >= 0; i--) { if ((CHESS[i][y] == CHESS[x][y]) && (CHESS[i][y] == color)) count++; else { break; } } if (i >= 0 && count == 2) if ((CHESS[i][y] == CHESS[x][y]) && (CHESS[i][y] == color)) // 断3的处理方法 if ((CHESS[i + 1][y] != 1) && (CHESS[i + 1][y] != 1)) { CHESS[i + 1][y] = 100000; } // 连3的处理方法 if (count == 3) { if ((CHESS[x - 1][y] != 1) && (CHESS[x - 1][y] != -1) && (CHESS[x + 3][y] != -color)) { CHESS[x - 1][y] = 2000; } if ((CHESS[x + 1][y] != 1) && (CHESS[x + 1][y] != -1) && (CHESS[x - 3][y] != -color)) { CHESS[x + 1][y] = 2000; } } if (count == 4) { if ((CHESS[x + 1][y] != 1) && (CHESS[x + 1][y] != -1)) { CHESS[x + 1][y] = 100000; } if ((CHESS[x - 1][y] != 1) && (CHESS[x - 1][y] != -1)) { CHESS[x - 1][y] = 100000; } } return count; } // 右斜 public int checkrighttop(int x, int y, int color) { // 定义一个计数器 int count = 0; int i = x - 1, j = y + 1; // 斜向上 for (; j < CHESS.length && i > 0; i--, j++) { if ((CHESS[x][y] == CHESS[i][j]) && (CHESS[i][j] == color)) { count++; } else { break; } } if (i >= 0 && j < CHESS.length && count == 2) if ((CHESS[i][j] == CHESS[x][y]) && (CHESS[i][j] == color)) // 断3的处理方法 if ((CHESS[i + 1][y - 1] != 1) && (CHESS[i + 1][y - 1] != 1)) { CHESS[i + 1][y - 1] = 10000; } // 斜向下 for (i = x, j = y; i < CHESS.length && j > 0; i++, j--) if ((CHESS[x][y] == CHESS[i][j]) && (CHESS[i][j] == color)) { count++; } else { break; } if (i < CHESS.length && j > 0 && count == 2) if ((CHESS[i][j] == CHESS[x][y]) && (CHESS[i][j] == color)) // 断3的处理方法 if ((CHESS[i - 1][y + 1] != 1) && (CHESS[i - 1][y + 1] != 1)) { CHESS[i - 1][y + 1] = 10000; } if (count == 3) { if ((CHESS[x - 1][y + 1] != 1) && (CHESS[x - 1][y + 1] != -1) && (CHESS[x + 3][y - 3] != -color)) { CHESS[x - 1][y + 1] = 2000; } if ((CHESS[x + 1][y - 1] != 1) && (CHESS[x + 1][y - 1] != -1) && (CHESS[x - 3][y + 3] != -color)) { CHESS[x + 1][y - 1] = 2000; } } if (count == 4) { if ((CHESS[x - 1][y + 1] != 1) && (CHESS[x - 1][y + 1] != -1)) { CHESS[x - 1][y + 1] = 100000; } if ((CHESS[x + 1][y - 1] != 1) && (CHESS[x + 1][y - 1] != -1)) { CHESS[x + 1][y - 1] = 100000; } } return count; } // 左斜 public int checklefttop(int x, int y, int color) { // 定义一个计数器 int count = 0; int i = x, j = y; // 斜向上 for (; i >= 0 && j >= 0; i--, j--) { if ((CHESS[x][y] == CHESS[i][j]) && (CHESS[i][j] == color)) count++; else { break; } } if (i > 0 && j > 0 && count == 2) if ((CHESS[i][j] == CHESS[x][y]) && (CHESS[i][j] == color)) // 断3的处理方法 if ((CHESS[i + 1][y + 1] != 1) && (CHESS[i + 1][y + 1] != 1)) { CHESS[i + 1][y + 1] = 10000; } // 斜向下 for (i = x + 1, j = y + 1; i < CHESS.length && j < CHESS.length; i++, j++) { if ((CHESS[x][y] == CHESS[i][j]) && (CHESS[i][j] == color)) count++; else break; } if (i < CHESS.length && j < CHESS.length && count == 2) if ((CHESS[i][j] == CHESS[x][y]) && (CHESS[i][j] == color)) // 断3的处理方法 if ((CHESS[i - 1][y - 1] != 1) && (CHESS[i - 1][y - 1] != 1)) { CHESS[i - 1][y - 1] = 10000; } if (count == 3) { if ((CHESS[x + 1][y + 1] != 1) && (CHESS[x + 1][y + 1] != -1) && (CHESS[x -3 ][y - 3] != -color)) { CHESS[x + 1][y + 1] = 2000; } if ((CHESS[x - 1][y - 1] != 1) && (CHESS[x - 1][y - 1] != -1) && (CHESS[x + 3][y + 3] != -color)) { CHESS[x - 1][y - 1] = 2000; } } if (count == 4) { if ((CHESS[x + 1][y + 1] != 1) && (CHESS[x + 1][y + 1] != -1)) { CHESS[x + 1][y + 1] = 100000; } if ((CHESS[x - 1][y - 1] != 1) && (CHESS[x - 1][y - 1] != -1)) { CHESS[x - 1][y - 1] = 100000; } } return count; } } // 横向判断是否有5个棋子 public int checkROW(int x, int y, int color) { // 定义一个计数器 int count = 0; // 往右走 for (int i = y + 1; i < CHESS.length; i++) { if ((CHESS[x][i] == CHESS[x][y]) && (CHESS[x][i] == color)) { count++; } else break; // 只要有一颗棋子不同就退出循环 } // 往左走 for (int i = y; i >= 0; i--) { if ((CHESS[x][i] == CHESS[x][y]) && (CHESS[x][i] == color)) { count++; } else break; // 只要有一颗棋子不同就退出循环 } //攻击,下活3 if(count==2){ if ((CHESS[x][y - 1] != 1) && (CHESS[x][y - 1] != -1) && (CHESS[x ][y + 2] != -color)) { CHESS[x][y - 1] = 700; } if ((CHESS[x][y + 1] != 1) && (CHESS[x][y + 1] != -1) && (CHESS[x ][y - 2] != -color)) { CHESS[x][y + 1] = 700; } } //攻击,连4颗 if (count == 3) { if ((CHESS[x][y - 1] != 1) && (CHESS[x][y - 1] != -1)) { CHESS[x][y - 1] = 500; } if ((CHESS[x][y + 1] != 1) && (CHESS[x][y + 1] != -1)) { CHESS[x][y + 1] = 500; } } if (count == 4) { if ((CHESS[x][y - 1] != 1) && (CHESS[x][y - 1] != -1)) { CHESS[x][y - 1] = 5000; } if ((CHESS[x][y + 1] != 1) && (CHESS[x][y + 1] != -1)) { CHESS[x][y + 1] = 5000; } } return count;// 返回所数的个数 } // 纵向判断是否有5颗棋子 public int checkCOLUMNS(int x, int y, int color) { // 定义一个计数器 int count = 0; // 向上 for (int i = x + 1; i < CHESS.length; i++) { if ((CHESS[i][y] == CHESS[x][y]) && (CHESS[i][y] == color)) { count++; } else break; } for (int i = x; i >= 0; i--) { if ((CHESS[i][y] == CHESS[x][y]) && (CHESS[i][y] == color)) count++; else break; } if (count == 2) { if ((CHESS[x - 1][y] != 1) && (CHESS[x - 1][y] != -1) && (CHESS[x + 1][y] != -color)) { CHESS[x + 2][y] = 700; } if ((CHESS[x + 1][y] != 1) && (CHESS[x + 1][y] != -1) && (CHESS[x - 2][y] != -color)) { CHESS[x + 1][y] = 700; } } if (count == 3) { if ((CHESS[x - 1][y] != 1) && (CHESS[x - 1][y] != -1)) { CHESS[x - 1][y] = 800; } if ((CHESS[x + 1][y] != 1) && (CHESS[x + 1][y] != -1)) { CHESS[x + 1][y] = 800; } } if (count == 4) { if ((CHESS[x + 1][y] != 1) && (CHESS[x + 1][y] != -1)) { CHESS[x + 1][y] = 5000; } if ((CHESS[x - 1][y] != 1) && (CHESS[x - 1][y] != -1)) { CHESS[x - 1][y] = 5000; } } return count; } // 右斜 public int checkrighttop(int x, int y, int color) { // 定义一个计数器 int count = 0; //斜向上 for (int i = x - 1, j = y + 1; j < CHESS.length && i > 0; i--, j++) { if ((CHESS[x][y] == CHESS[i][j]) && (CHESS[i][j] == color)) { count++; } else { break; } } //斜向下 for (int i = x, j = y; i < CHESS.length && j > 0; i++, j--) if ((CHESS[x][y] == CHESS[i][j]) && (CHESS[i][j] == color)) { count++; } else { break; } if (count == 2) { if ((CHESS[x - 1][y + 1] != 1) && (CHESS[x - 1][y + 1] != -1) && (CHESS[x + 2][y-2] != -color)) { CHESS[x-1][y + 1] = 700; } if ((CHESS[x + 1][y - 1] != 1) && (CHESS[x + 1][y - 1] != -1) && (CHESS[x - 2][y + 2] != -color) ){ CHESS[x + 1][y - 1] = 700; } } if (count == 3) { if ((CHESS[x - 1][y + 1] != 1) && (CHESS[x - 1][y + 1] != -1)) { CHESS[x-1][y + 1] = 800; } if ((CHESS[x + 1][y - 1] != 1) && (CHESS[x + 1][y - 1] != -1)) { CHESS[x + 1][y - 1] = 800; } } if (count == 4) { if ((CHESS[x - 1][y + 1] != 1) && (CHESS[x - 1][y + 1] != -1)) { CHESS[x-1][y + 1] = 5000; } if ((CHESS[x + 1][y - 1] != 1) && (CHESS[x + 1][y - 1] != -1)) { CHESS[x + 1][y - 1] = 5000; } } return count; } // 左斜 public int checklefttop(int x, int y, int color) { // 定义一个计数器 int count = 0; // 斜向上 for (int i = x, j = y; i >= 0 && j >= 0; i--, j--) { if ((CHESS[x][y] == CHESS[i][j]) && (CHESS[i][j] == color)) count++; else break; } // 斜向下 for (int i = x + 1, j = y + 1; i < CHESS.length && j < CHESS.length; i++, j++) { if ((CHESS[x][y] == CHESS[i][j]) && (CHESS[i][j] == color)) count++; else break; } if (count == 2) { if ((CHESS[x + 1][y + 1] != 1) && (CHESS[x + 1][y + 1] != -1)&&(CHESS[x - 2][y - 2] != -color) ){ CHESS[x + 1][y + 1] = 700; } if ((CHESS[x - 1][y - 1] != 1) && (CHESS[x - 1][y - 1] != -1)&&(CHESS[x + 2][y + 2] != -color) ) { CHESS[x - 1][y - 1] = 700; } } if (count == 3) { if ((CHESS[x + 1][y + 1] != 1) && (CHESS[x + 1][y + 1] != -1)) { CHESS[x + 1][y + 1] = 800; } if ((CHESS[x - 1][y - 1] != 1) && (CHESS[x - 1][y - 1] != -1)) { CHESS[x - 1][y - 1] = 800; } } if (count == 4) { if ((CHESS[x + 1][y + 1] != 1) && (CHESS[x + 1][y + 1] != -1)) { CHESS[x + 1][y + 1] = 5000; } if ((CHESS[x - 1][y - 1] != 1) && (CHESS[x - 1][y - 1] != -1)) { CHESS[x - 1][y - 1] = 5000; } } return count; } }
相关推荐
五子棋社团工作计划总结总结.doc
【毕业设计】MATLAB实战应用案例小游戏(附MATLAB代码):围五子棋.zip
1引言1 1.1系统开发背景2 1.1系统开发的目的和意义3 1.2完成的主要工作4 2需求分析和总体设计4 2.1需求分析与设计思路5 2.1.1关键技术说明5 2.1.2...模块实现9 4系统运行结果10 5课程设计总结12 五子棋游戏的设计与实现...
网络五子棋设计报告 大家下载着看看吧 网络五子棋设计报告 网络五子棋设计报告
本文档是关于大学本科课程实训的一个项目,是用c语言写的一个关于五子棋的实训报告,并且可视化
北京邮电大学世纪学院实习报告,主要针对五子棋的设计过程做出分析,附有代码说明
五子棋程序源码 加 报告 五子棋程序源码 加 报告 五子棋程序源码 加 报告
python课程设计完整 五子棋
五子棋课程设计报告 五子棋课程设计报告 五子棋课程设计报告
Java五子棋设计报告.pdf
使用python写的基于两层博弈树的五子棋AI。加入了阿尔法贝塔剪枝。 python版本:3+,应该可以在命令行里直接跑。 电脑执黑,玩家执白。无禁手。 因为只有两层博弈树,请大家不要嫌他菜哈哈哈,仅供大家学习参考。 ...
使用C语言基于EGE图形库实现的五子棋小游戏,实验报告,C语言程序设计的结课作业,实现了人机对弈与人人对战功能。有相应的音乐
NULL 博文链接:https://javaprince.iteye.com/blog/798714
五子棋游戏是一个深受人们喜爱的游戏,通常是人机对弈,本程序设计为人与人对弈,一方执黑棋,一方执白棋,轮流走棋,每方都试图在游戏结束前让自己的棋子五子相连。按键盘上的方向键可以移动光标,回车键可以摆放...
Python编程与数据分析-结课报告-五子棋对弈的算法设计包含以下两部分文件: 1.【报告】分为五章进行展示,包括程序思路介绍、设计方案、源程序代码、程序运行,以及结语。 2.【代码】包括4个python代码文件,用于...
五子棋是起源于中国古代的传统黑白棋种之一。现代五子棋日文称之为“連珠”,英译为“Renju”,英文称之为“Gobang”或“FIR”(Five in a Row的缩写),亦有“连五子”、“五子连”、“串珠”、“五目”、“五目碰...
Java实现五子棋源码+实验报告
基于Python实现五子棋(三人对战) 大学生课程设计 基于python的课程设计 自己大二写的课程设计
五子棋游戏开发总结c语言版