• 全国 [切换]
  • 二维码
    富博农业

    手机WAP版

    手机也能找商机,信息同步6大终端平台!

    微信小程序

    微信公众号

    当前位置: 首页 » 行业新闻 » 热点新闻 » 正文

    编写生命游戏

    放大字体  缩小字体 发布日期:2020-02-11 15:58:30   浏览次数:1176  发布人:1886****  IP:117.173.23.***  评论:0
    导读

    书名:代码本色:用编程模拟自然系统 作者:Daniel Shiffman 译者:周晗彬 ISBN:978-7-115-36947-5 第7章目录7.7 编写生命游戏1、用二维数组表示细胞状态现在,我们需要将之前的Wolfram CA扩展到二维空间。前面我们用一维数组存放细胞的状态,在生命游戏中,我们需要用二维数组表示细胞状态。int [][] board = new int[columns][ro

    书名:代码本色:用编程模拟自然系统
    作者:Daniel Shiffman
    译者:周晗彬
    ISBN:978-7-115-36947-5
    第7章目录

    7.7 编写生命游戏

    1、用二维数组表示细胞状态

    • 现在,我们需要将之前的Wolfram CA扩展到二维空间。前面我们用一维数组存放细胞的状态,在生命游戏中,我们需要用二维数组表示细胞状态。

    int [][] board = new int[columns][rows];

    • 首先,我们用随机的状态值(0或1)初始化board数组中的每个细胞。

    for (int x = 0; x < columns; x++) { for (int y = 0; y < rows; y++) { current[x][y] = int(random(2)); 用0或1初始化每个细胞 } }

    2、计算下一次迭代

    • 为了计算下一次迭代,就像以前一样,我们需要一个新的二维数组。并在遍历过程中将新状态写入这个数组。

    int[][] next = new int[columns][rows]; for (int x = 0; x < columns; x++) { for (int y = 0; y < rows; y++) { next[x][y] = _________?; 为每个细胞设置新状态 } }

    3、如何引用邻居细胞

    • 在研究新状态的计算方法之前,我们要先搞清楚如何引用邻居细胞。
    • 在一维CA中,引用邻居细胞很简单:如果细胞的下标是i,那么邻居的下标就是i-1和i+1。
    • 在二维CA中,每个细胞都有两个下标:列下标x和行下标y。如图7-27所示,细胞的邻居分别为:(x-1,y-1)、(x,y-1)、(x+1,y-2)、(x-1,y)、(x+1,y)、(x-1,y+1)、(x,y+1)和(x+1,y+1)。







    4、邻居数变量

    • 在生命游戏中,所有规则都只涉及“活着”的邻居细胞的数量。因此,我们可以引入一个邻居计数器变量,每次发现一个“活着”的邻居,就递增这个变量,最后就能得到“活着”的邻居的总数。

    int neighbors = 0; if (board[x-1][y-1] == 1) neighbors++; 最顶行的邻居 if (board[x ][y-1] == 1) neighbors++; if (board[x+1][y-1] == 1) neighbors++; if (board[x-1][y] == 1) neighbors++; 中间的邻居(不包括自身) if (board[x+1][y] == 1) neighbors++; if (board[x-1][y+1] == 1) neighbors++; 最底行的邻居 if (board[x ][y+1] == 1) neighbors++; if (board[x+1][y+1] == 1) neighbors++;

    • 如同Wolfram CA,上面的实现方式在教学方面非常有用,它让我们看到了每一个计算步骤(每次找到一个状态为1的邻居,就递增计数器)。但是,“如果细胞状态等于1,则让计数器加1”和“计数器加上细胞状态”这两种描述是等价的,只是后者比前者更巧妙。毕竟,如果细胞只有0和1两个状态,所有邻居细胞状态的和就等于“活着”的邻居的总数。由于邻居处在一个3 × 3的网格内,我们可以把这一步放到另一个循环中。

    for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { neighbors += board[x+i][y+j]; 将所有邻居的状态相加 } }

    • 上面的代码中有一个错误,在生命游戏中,细胞并不是自己的邻居。因此我们应该加一个条件判断语句:如果i和j同时等于0,则跳过当前邻居;但还有另一种方案,就是在结束循环时再减去自身的状态。

    neighbors -= board[x][y]; 减去自身的状态,我们不想把自身也包括在内

    5、确定新状态

    • 最后,一旦知道“活着”邻居的总数,我们下一步要做的就是确定细胞的新状态,也就是实现生命游戏的规则:新生、死亡或者静止。

    if ((board[x][y] == 1) && (neighbors < 2)) { 如果细胞活着,但活着的邻居少于两个,它就因孤next[x][y] = 0; } else if ((board[x][y] == 1) && (neighbors > 3)) { 如果细胞活着,但活着的邻居多于3个,它就next[x][y] = 0; } else if ((board[x][y] == 0) && (neighbors == 3)) { 如果细胞的状态为死亡,但它有3个活着的next[x][y] = 1; } else { 其他情况下,细胞的状态保持不变 next[x][y] = board[x][y]; }

    6、显示

    下一代状态计算完成后,我们就可以用之前的方法绘制生命游戏——黑色方块代表“活着”,白色方块代表“死亡”。

    for ( int i = 0; i < columns;i++) { for ( int j = 0; j < rows;j++) {   如果状态=1,就绘制黑色方块 if ((board[i][j] == 1)) fill(0); else fill(255); 如果状态为0,就绘制白色方块 stroke(0); rect(i*w, j*w, w, w); } }

    7、结果






    不推荐电脑端访问(用户少)
    请微信扫一扫,查看完整信息(记得微信收藏)
     
    (文/匿名(若涉版权问题请联系我们核实发布者) / 非法信息举报 / 删稿)
    打赏
    免责声明
    • 
    本文为昵称为 1886**** 发布的作品,本文仅代表发布者个人观点,本站未对其内容进行核实,请读者仅做参考,如若文中涉及有违公德、触犯法律的内容,一经发现,立即删除,发布者需自行承担相应责任。涉及到版权或其他问题,请及时联系我们154208694@qq.com删除,我们积极做(权利人与发布者之间的调停者)中立处理。郑重说明:不 违规举报 视为放弃权利,本站不承担任何责任!
    有个别老鼠屎以营利为目的遇到侵权情况但不联系本站或自己发布违规信息然后直接向本站索取高额赔偿等情况,本站一概以诈骗报警处理,曾经有1例诈骗分子已经绳之以法,本站本着公平公正的原则,若遇 违规举报 我们100%在3个工作日内处理!
    0 条相关评论
     

    福博农产品采购网 (c)2008-现在 foubo.com All Rights Reserved.