参考链接: 康威的人生游戏(Python实现)

从功能和技术的角度来看,Conway的“生活游戏”都非常有趣。

这可以解释为什么它经常用于代码撤退 。 代码撤退是一种有趣的学习方法。

几乎每次与新对一起工作都会为您带来新见解,这真是令人惊讶。

在我参加的最后一次代码务虚会上,我的一对建议我们对单元格使用Flyweight模式 :

flyweight是一个共享对象,可以同时在多个上下文中使用。 在每个上下文中,flyweight都充当一个独立的对象-与未共享的对象实例是无法区分的。

当《 设计模式》一书(包含上面的引文)问世时,我记得有很多啊哈。 看到我以前使用过的所有这些模式,并最终为其命名,真是太酷了,这样我可以与同龄人更有效地讨论它们!

但是,当我阅读有关飞重的信息时,我并没有感到惊讶。 书中的示例在文本编辑器中共享字符对象,当时似乎有些牵强。 但是,此示例与“生命游戏”网格中的单元格并无不同,因此我很高兴地沿用了他们俩的想法,探索了该模式在这种情况下的适用性。

代码撤退结束后,我进一步考虑了该模式。 (这通常是代码撤退真正开始起作用的地方。)

实际上,我们一直在使用潜在的重量级:布尔值。 布尔值是只有两个实例的类,可以轻松共享这些实例。 在Java中,它们不是: new Boolean(true) != new Boolean(true) 。 但是, Boolean类确实为可用于共享的实例提供了两个常量TRUE和FALSE 。

那让我开始考虑将Enum用作飞行重量。 大多数时候,我使用枚举对相关但互斥的常量进行分组,例如一周中的几天。 但是,Java中的Enum可以定义方法:

public enum Cell {

ALIVE(true), DEAD(false);

private final boolean alive;

private Cell(boolean alive) {

this.alive = alive;

}

public boolean isAlive() {

return alive;

}

public Cell evolve(int numLiveNeighbors) {

boolean aliveInNextGeneration = alive

? 2 <= numLiveNeighbors && numLiveNeighbors <= 3

: numLiveNeighbors == 3;

return aliveInNextGeneration ? ALIVE : DEAD;

}

}

代码撤退的有趣部分之一是,在某些会话中,您将对工作方式有所限制。 这样的约束迫使您更具创造力,并思考超出通常使用的技术范围。

在这种情况下有趣的一个约束是不使用任何条件,例如if或switch语句或三元运算符。 该约束背后的想法是迫使您用多态替换条件语句 ,使您的程序更加面向对象。

我看到的保留当前Cell枚举而不使用条件的唯一方法是引入映射:

public enum Cell {

ALIVE(true), DEAD(false);

private final boolean alive;

private static final Map<Boolean, Map<Integer, Cell>>

NEXT = new HashMap<>();

static {

Map<Integer, Cell> dead = new HashMap<>();

dead.put(0, DEAD);

dead.put(1, DEAD);

dead.put(2, DEAD);

dead.put(3, ALIVE);

dead.put(4, DEAD);

dead.put(5, DEAD);

dead.put(6, DEAD);

dead.put(7, DEAD);

dead.put(8, DEAD);

dead.put(9, DEAD);

NEXT.put(false, dead);

Map<Integer, Cell> alive = new HashMap<>();

alive.put(0, DEAD);

alive.put(1, DEAD);

alive.put(2, ALIVE);

alive.put(3, ALIVE);

alive.put(4, DEAD);

alive.put(5, DEAD);

alive.put(6, DEAD);

alive.put(7, DEAD);

alive.put(8, DEAD);

alive.put(9, DEAD);

NEXT.put(true, alive);

}

private Cell(boolean alive) {

this.alive = alive;

}

public boolean isAlive() {

return alive;

}

public Cell evolve(int numLiveNeighbors) {

return NEXT.get(alive).get(numLiveNeighbors);

}

}

这种方法可行,但不是很优雅,并且随着可能性的增加而失效。 显然,我们需要更好的选择。

摆脱条件的唯一方法是摆脱单元格的布尔状态。 这意味着我们需要为两个实例使用不同的类,以便类型隐式体现状态。 反过来,这意味着我们需要一个工厂来向客户端隐藏这些类:

public interface Cell {

boolean isAlive();

Cell evolve(int numLiveNeighbors);

}

public class CellFactory {

private static final Map<Boolean, Cell> CELLS

= new HashMap<>();

static {

CELLS.put(false, new DeadCell());

CELLS.put(true, new AliveCell());

}

public static Cell dead() {

return cell(false);

}

public static Cell alive() {

return cell(true);

}

static Cell cell(boolean alive) {

return CELLS.get(alive);

}

}

class DeadCell implements Cell {

@Override

public boolean isAlive() {

return false;

}

@Override

public Cell evolve(int numLiveNeighbors) {

return CellFactory.cell(numLiveNeighbors == 3);

}

}

class AliveCell implements Cell {

@Override

public boolean isAlive() {

return true;

}

@Override

public Cell evolve(int numLiveNeighbors) {

return CellFactory.cell(numLiveNeighbors == 2

|| numLiveNeighbors == 3);

}

}

的确,当您查看Flyweight模式时,您会看到建议的结构包含一个flyweight工厂,该工厂创建实现普通flyweight接口的具体flyweight类的实例。

感谢代码撤退和我的合作伙伴,我现在知道为什么。

翻译自: https://www.javacodegeeks.com/2014/04/conways-game-of-life-and-the-flyweight-pattern.html

[转载] 康威的人生游戏与轻量级模式相关推荐

  1. 【项目经理之修炼(7)】《基础篇》人生游戏中的神器——谦虚

    作者: 孙继滨 "一封邮件究竟能够起多大的作用呢??" 大家有时候可能会产生这样的疑问. 史记有过这样的记载: ---------------------------------- ...

  2. 2012中国移动社交游戏市场盈利模式探讨

    2012年中国移动社交游戏市场盈利模式探讨 来源:艾媒网 作者:庄周 2012-04-18 11:13:19 [ 5124阅读 0评论 ] 内容摘要:伴随着中国3G网络的迅速发展与普及,网络社交活动也 ...

  3. javascript开发HTML5游戏--斗地主(单机模式part3)

    最近学习使用了一款HTML5游戏引擎(青瓷引擎),并用它尝试做了一个斗地主的游戏,简单实现了单机对战和网络对战,代码可已放到github上,在此谈谈自己如何通过引擎来开发这款游戏的. 客户端代码 服务 ...

  4. javascript开发HTML5游戏--斗地主(单机模式part2)

    最近学习使用了一款HTML5游戏引擎(青瓷引擎),并用它尝试做了一个斗地主的游戏,简单实现了单机对战和网络对战,代码可已放到github上,在此谈谈自己如何通过引擎来开发这款游戏的. 客户端代码 服务 ...

  5. 游戏设计模式——黑板模式

    目录 黑板(Blackboard) 定义 好处 缺点 额外功能 一个游戏使用黑板模式的例子 其他使用黑板模式的例子 小结 黑板模式的C++简易实现 黑板模式的C#实现 参考 黑板(Blackboard ...

  6. Python之模拟职场人生游戏

    题目:模拟人生 要求:1.至少有两个角色 2.玩的过程中,有冲突 3.根据不同的交互,产生不同的行为. 4.一定要用到面向对象语法和思想 1.解题思路 创建一个类,赋予角色不同的方法,使用面向对象思想 ...

  7. 一年突破3亿游戏安装量 小米游戏双发行模式助力游戏开发者

    2020年,全球市场迎来了颠覆式的新格局,挑战与机遇并存.一方面,疫情导致大量消费者居家隔离,线上业务迎来了爆发式增长;另一方面,文化冲突.数据隐私.地缘关系等因素对海外业务都增加了更多不确定性.对于 ...

  8. 转载一个手机RPG游戏制作工具,仿造RPGXP写的

    转载一个手机RPG游戏制作工具,仿造RPGXP写的 有朋友问有没有脚本编辑功能,大家注意啦: 有脚本编辑功能,可视化界面编辑脚本,和RMXP一样 经过一年的开发,手机RPG游戏制作工具--MobieG ...

  9. java游戏杀怪物_我的人生游戏 java知识点关卡之java基本类型怪物攻略

    人生如游戏,掌握了方方面面的技能知识后方能解决一个个场景下的问题,一步步走上人生巅峰.<我的人生游戏>就是一款将人生中暗含的各种能力培养显性化的游戏,帮你完善技能,积累经验,增加人生战斗力 ...

最新文章

  1. 正则表达式学习神器!
  2. const 和 static 的作用
  3. Perl文件句柄引用
  4. java小数换成字符实现加法_第一、二次笔记总结
  5. static_cast、dynamic_cast、reinterpret_cast、和const_cast
  6. 移动端手势库设计与实践
  7. 25个个免费英文文献下载网站!
  8. CS61C 学习笔记 --实时更新
  9. mysql建立唯一索引升序_MySQL数据库SQL优化技巧六之唯一索引
  10. 关于python程序格式的描述_关于Python程序格式框架的描述,以下选项中错误的是...
  11. 解决手机浏览器无法显示本地html文件
  12. 梯度下降算法的细节补充(凸函数, 导数, 偏导数,梯度, 方向导数以及负梯度下降最快背后的泰勒身影)
  13. 阿里云ECS七天训练营-搭建FTP
  14. YOLOv5的项目实践 | 手势识别项目落地全过程(附源码)
  15. mysql left outer join_关于mysql中的left join和left outer join的区别
  16. 亲历骗子通过闲鱼、江苏猎宝网络科技股份有限公司进行诈骗!
  17. 计算机编程语言及C语言简介,编程语言基础:C语言
  18. 腾讯云https证书部署nginx
  19. [Ubuntu 16.04] [Memos] install samba
  20. CentOS7 搭建Janus服务

热门文章

  1. 【PAT甲】1051 Pop Sequence (25分)判断出栈顺序的合法性
  2. Office Word2019您正试图运行的函数包含有宏或需要宏语言
  3. 电大计算机专业毕业自我鉴定,电大毕业生计算机专业自我鉴定
  4. eclipse配置python开发环境_Eclipse中配置python开发环境详解
  5. JQueryDOM之修改节点
  6. RSA解密Matlab,RSA加密算法--matlab
  7. [leetcode] 413. 等差数列划分
  8. Codeforces Round #197 (Div. 2): D. Xenia and Bit Operations(线段树)
  9. bzoj 1675: [Usaco2005 Feb]Rigging the Bovine Election 竞选划区(暴力)
  10. [debug+Python] 复制字典不能直接用 ‘=’,要用dict_name.copy()