生命游戏Java实现
来源:互联网 发布:西瓜影音mac 编辑:程序博客网 时间:2024/05/17 21:44
关于生命游戏
之前在学校看到ThoughtWorks举办的线下结对编程的比赛一等奖是大疆无人机,冲着无人机就拉着实验室小伙伴马总一起报了个名。然后题目就是实现一个界面版的生命游戏,所以才了解了生命游戏。
关于生命游戏,可以参考维基百科。
下图是效果图:
规则
生命游戏中,对于任意细胞,规则如下:
每个细胞有两种状态-存活或死亡,每个细胞与以自身为中心的周围八格细胞产生互动。(如图,黑色为存活,白色为死亡)
当前细胞为存活状态时,当周围低于2个(不包含2个)存活细胞时, 该细胞变成死亡状态。(模拟生命数量稀少)
当前细胞为存活状态时,当周围有2个或3个存活细胞时, 该细胞保持原样。
当前细胞为存活状态时,当周围有3个以上的存活细胞时,该细胞变成死亡状态。(模拟生命数量过多)
当前细胞为死亡状态时,当周围有3个存活细胞时,该细胞变成存活状态。 (模拟繁殖)
可以把最初的细胞结构定义为种子,当所有在种子中的细胞同时被以上规则处理后, 可以得到第一代细胞图。按规则继续处理当前的细胞图,可以得到下一代的细胞图,周而复始。
根据上面的规则得出下面的代码:
/** * 上一个状态到下一个状态的转移 * 根据规则可以总结得出两条规则: * 1. 对于周围活着的细胞为3的情况,下一个状态该细胞总是为活 * 2. 对于周围活着的细胞为2的情况,下一个状态与上一状态相同 */ public void transform(){ int[][] nextMatrix=new int[height][width]; for (int y = 0; y < matrix.length; y++) { for (int x = 0; x < matrix[0].length; x++) { nextMatrix[y][x]=0; int nearNum= findLifedNum(y,x); //等于3,则下一状态总是活 if(nearNum==3){ nextMatrix[y][x]=1; } //等于2,则与上一状态一样 else if(nearNum==2){ nextMatrix[y][x]=matrix[y][x]; } } } matrix=nextMatrix; } /** * 统计每个细胞周围活着的个数 * @param x 横坐标 * @param y 纵坐标 * @return */ public int findLifedNum(int y, int x){ int num=0; //左边 if(x!=0){ num+=matrix[y][x-1]; } //左上角 if(x!=0&&y!=0){ num+=matrix[y-1][x-1]; } //上边 if(y!=0){ num+=matrix[y-1][x]; } //右上 if(x!=width-1&&y!=0){ num+=matrix[y-1][x+1]; } //右边 if(x!=width-1){ num+=matrix[y][x+1]; } //右下 if(x!=width-1&&y!=height-1){ num+=matrix[y+1][x+1]; } //下边 if(y!=height-1){ num+=matrix[y+1][x]; } //左下 if(x!=0&&y!=height-1){ num+=matrix[y+1][x-1]; } return num; }
实现
首先看我们做的效果,如下图:
关于初始状态的输入
初始状态是通过文件加载的方式来实现的,为了加载很多的情况,又写了一个工具类负责随机产生case,代码如下:
/** * 创建测试案例 */ private static void createCaseFile() { Random random = new Random(); int rows = 1 + random.nextInt(100); int cols = 1 + random.nextInt(100); int duration = 200; int num = 300; File file = new File(cols+"_"+rows+"_"+System.nanoTime() + ".txt"); PrintWriter writer = null; try { writer = new PrintWriter(new FileWriter(file)); StringBuilder sb = new StringBuilder(cols + " " + rows + " " + duration + " " + num); writer.write(sb.append("\n").toString()); //开始逐行初始化 for (int y = 0; y < rows; y++) { sb = new StringBuilder(); for (int x = 0; x < cols; x++) { if (random.nextInt(3) % 3 == 0) { sb.append("1 "); } else { sb.append("0 "); } } sb.deleteCharAt(sb.length()-1).append("\n"); writer.write(sb.toString()); } } catch (IOException e) { e.printStackTrace(); } finally { if (writer != null) { writer.close(); } } }
关于界面
使用的Swing编程,java的界面做出来确实不咋的。不过我们加入了暂停、继续功能,这个是通过控制一个变量来做的,每两帧动画之间通过线程睡眠实现的。核心代码如下:
private class GameControlTask implements Runnable { @Override public void run() { while (!stop) { cellMatrix.transform(); showMatrix(); try { TimeUnit.MILLISECONDS.sleep(duration); } catch (InterruptedException ex) { ex.printStackTrace(); } } } }
其中cellMatrix代表了一帧的状态,调用transform()将会进行下一次变换,showMatrix负责更新界面。
总结
最后,由于界面比较酷炫,可以支持暂停、继续功能,代码结构比较优美及注释比较完整,最后和我的小伙伴拿了个无人机,还是挺爽的。
关于代码,可以参考TxGameOfLife。
- 生命游戏Java实现
- React实现生命游戏
- 生命游戏(Java)
- 生命游戏 c语言实现
- 生命游戏 c语言实现
- GTK实现生命游戏小结
- 使用PySide实现生命游戏
- python 实现康威生命游戏
- 用C#实现的生命游戏
- 生命游戏 -- 使用WTL C++实现
- 康威生命游戏的简单实现
- python实现生命游戏(Game of Life)
- 生命游戏
- 生命游戏
- 生命游戏
- 生命游戏
- 生命游戏
- 生命游戏
- 最简单的非模块化的vue笔记
- 005_Tomcat环境配置与Tomcat项目部署
- laravel的request里的get和input区别
- centOS 安装tomcat
- 构造函数调用顺序
- 生命游戏Java实现
- springMVC与app对接
- Android开发你需要知道的注解(Annotation)
- React Native手势识别
- 隐藏入口文件
- 【学习摘记】马士兵bbs改良版_课时13-14_article.jsp:最上来讲的,却是最难的
- jQuery-ui插件datepicker的参数使用详解
- Ubuntu 16.04 开机运行程序或脚本
- EC20_R20使用GPS功能