Java & Python 康威生命游戏 - 命令行版(2020年7月23日)
制作背景
高二的时候看霍金的《大设计》最后几页的时候看到里面提到了康威生命游戏,介绍了它的规则,感觉很有意思,但是在草稿纸上一点一点画,推演,实在是太麻烦了,于是我便想是否可以通过编程的方式实现康威生命游戏?我当时高二,感觉自己很难做出来。到了大一下学期,自学了python和java,学校的课程里也学习了C语言,自己也经常写一些有意思的小程序,可以说是有一定的编程基础了,于是就又会想起了一年多前的康威生命游戏。
其实在 2020年2月24号,大一上学期结束的寒假里,我已经把一维版的康威宇宙做出了来了,但是那终究是一维的,没有二维的丰富,开发难度肯定没有二维的高。所以这次我打算真正的试一试二维的,原版的、正经的康威宇宙。
在 2020年4月11日的时候,生命游戏的作者 约翰·何顿·康威 已经因为新冠肺炎去世了。感觉突然挺遗憾的。之前了解这个人完全是因为生命游戏,但是其实他是一个数学家。他还有其他很多更大的贡献和发现,不只是生命游戏。
2020年7月23日,我把用python实现了,随后一天我又做了一份Java版本的。
相关介绍
百度介绍:
https://baike.baidu.com/item/%E5%BA%B7%E5%A8%81%E7%94%9F%E5%91%BD%E6%B8%B8%E6%88%8F
知乎介绍:
https://zhuanlan.zhihu.com/p/45026142
效果截图
源代码
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
| import java.util.Random;
public class GameOfLife { private static final int CELLS_WIDTH = 85; private static final int CELLS_HEIGHT = 45; private static final String LIVE_CELL = "█"; private static final String DEATH_CELL = " "; private static final int R = 1; private static final int LIVE_NUM_MIN = 2; private static final int LIVE_NUM_MAX = 3; private static final int BIRTH_NUM_MIN = 3; private static final int BIRTH_NUM_MAX = 3;
public static void main(String[] args) { byte[][] cells = newCells(CELLS_WIDTH, CELLS_HEIGHT); System.out.println(str(cells));
randPoint(cells); System.out.println(str(cells));
while (true) { cells = iterative(cells); System.out.println(str(cells)); } }
private static byte[][] newCells(int width, int height){ byte[][] cellsArray = new byte[height][width]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { cellsArray[i][j] = 0; } } return cellsArray; }
private static void randPoint(byte[][] cellsArray){ for (int i = 0; i < cellsArray.length; i++) { for (int j = 0; j < cellsArray[i].length; j++) { int rd = Math.random()>0.5 ? 1 : 0; if(rd == 1) { cellsArray[i][j] = 1; } } } }
private static byte[][] iterative(byte[][] cellsArray){ byte[][] afterCells = newCells(cellsArray[0].length, cellsArray.length);
for (int i = 0; i < cellsArray.length; i++) { for (int j = 0; j < cellsArray[i].length; j++) { int neighborNum = 0; int top = Math.max(i - R, 0); int button = Math.min(cellsArray.length-1, i + R); int left = Math.max(j - R, 0); int right = Math.min(j + R, cellsArray[i].length-1); for( int y = top; y <= button; y++){ for (int x = left; x <= right; x++){ if(cellsArray[y][x] == 1){ if(j != x || i != y){ neighborNum++; } } } } if(cellsArray[i][j] == 1){ if(LIVE_NUM_MIN <= neighborNum && neighborNum <= LIVE_NUM_MAX){ afterCells[i][j] = 1; } }else if(cellsArray[i][j] == 0){ if(BIRTH_NUM_MIN <= neighborNum && neighborNum <= BIRTH_NUM_MAX){ afterCells[i][j] = 1; } } } } return afterCells; }
private static String str(byte[][] cellsArray){ StringBuilder cellsString = new StringBuilder(); for (byte[] bytes : cellsArray) { for (byte aByte : bytes) { if (aByte == 0) { cellsString.append(DEATH_CELL); } else { cellsString.append(LIVE_CELL); } } cellsString.append("/n"); } return cellsString.toString(); }
private static void putGlider(byte[][] cellsArray, int x, int y){ cellsArray[y][x+2] = 1; cellsArray[y+1][x] = 1; cellsArray[y+1][x+2] = 1; cellsArray[y+2][x+1] = 1; cellsArray[y+2][x+2] = 1; } }
|
python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
| """ 生命游戏-命令行版 设计作者:康威 代码作者:littlefean 代码时间:2020年7月23日 """ from random import randint import numpy as np
def newCells(width, height): """ 生成一个空的全是0的二维数组并返回 :param width: 宽度 :param height: 高度 :return: 二元数组 """ cellsArray = np.zeros([height, width], dtype=int) return cellsArray
def randPoint(cellsArray): """ 将二维数组随机化,该函数直接改参数的状态 :param cellsArray:二维数组 :return: """ for i in range(len(cellsArray)): for j in range(len(cellsArray[i])): cellsArray[i][j] = randint(0, 1)
def iterative(cellsArray): """ 传入二维数组并使其按照生命游戏规则迭代一次,迭代完成后返回一个新的迭代后的二维数组 :param cellsArray:迭代前的二维数组 :return:迭代后的二维数组 """ afterCells = newCells(len(cellsArray[0]), len(cellsArray)) for y in range(len(cellsArray)): for x in range(len(cellsArray[y])): neighborNum = 0 for y_border in range(max(y - R, 0), min(y + R, len(cellsArray) - 1) + 1): for x_border in range(max(x - R, 0), min(x + R, len(cellsArray[y]) - 1) + 1): if cellsArray[y_border][x_border] == 1: if x != x_border or y != y_border: neighborNum += 1 if cellsArray[y][x] == 1: if neighborNum in range(LIVE_NUM_MIN, LIVE_NUM_MAX + 1): afterCells[y][x] = 1 elif cellsArray[y][x] == 0: if neighborNum in range(BIRTH_NUM_MIN, BIRTH_NUM_MAX + 1): afterCells[y][x] = 1 return afterCells
def string(cellsArray): """ 返回cellsArray的字符串表示形式 :param cellsArray: 二维数组 :return: cellsArray的字符串表示形式 """ cellsString = "" for y in range(len(cellsArray)): for x in range(len(cellsArray[y])): if cellsArray[y][x] == 0: cellsString += DEATH_CELL else: cellsString += LIVE_CELL cellsString += "/n" return cellsString
def putGlider(cellsArray, x, y): """ 传入二维数组和两个位置参数,在二维数组的特定位置上做修改,并返回修改后的二维数组 此函数是在二维数组的xy下标位置上放了一个向右下飞行的 滑翔机 xy对应滑翔机的左上角顶点 □□■ ■□■ □■■ :param cellsArray:修改前(还未放置滑翔机)的数组 :param x:滑翔机的左上角顶点在数组里的x位置 :param y:滑翔机的左上角顶点在数组里的y位置 :return:修改后(放置了一个滑翔机)的二维数组 """ cellsArray[y][x + 2] = 1 cellsArray[y + 1][x] = 1 cellsArray[y + 1][x + 2] = 1 cellsArray[y + 2][x + 1] = 1 cellsArray[y + 2][x + 2] = 1 return cellsArray
if __name__ == '__main__': """ """ CELLS_WIDTH = 85 CELLS_HEIGHT = 45 LIVE_CELL = "█" DEATH_CELL = " " R = 1 LIVE_NUM_MIN = 2 LIVE_NUM_MAX = 3 BIRTH_NUM_MIN = 3 BIRTH_NUM_MAX = 3
cells = newCells(85, 45) print(string(cells)) randPoint(cells) putGlider(cells, 0, 0) print(string(cells)) step = 0 while True: if step % 24 == 0: putGlider(cells, randint(0, 5), randint(0, 5)) cells = iterative(cells) print(string(cells)) step += 1
|
回顾反思
- 直接给调用者暴露了数组,但是调用者并不知道是用
[y][x]
的方式还是[x][y]
的方式,你这个没有说明,会导致一些不方便
- 如果能把cellsArray封装成一个类那就好了,因为它已经很像类了。
不知道怎么结尾了,康威生命游戏的评价里有一句话说的不错,就以它结尾吧:“ 孤独和拥挤都不适合生命的繁衍和发展 ”。
Author:
Littlefean
License:
Copyright (c) 2019 CC-BY-NC-4.0 LICENSE
Slogan:
仅个人观点,buddy up!