100行python代码实现细胞自动机(康威生命游戏)

这篇具有很好参考价值的文章主要介绍了100行python代码实现细胞自动机(康威生命游戏)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 英国数学家约翰·何顿·康威在1970年发明了细胞自动机,它属于一种仿真程序,通过设定一些基本的规则来模拟和显示的图像的自我进化,看起来颇似生命的出生和繁衍过程,故称为“生命游戏”。

完成效果

100行python代码实现细胞自动机(康威生命游戏)

用到的第三方库

pygame

基本规则

康威生命游戏在网格上进行,有填充的网格代表有生命,或理解成一个细胞,游戏规则只有四条:

1 当周围仅有1个或没有存活细胞时, 原来的存活细胞进入死亡状态。(细胞过于稀少)

2 当周围有2个或3个存活细胞时, 网格保持原样。

3 当周围有4个及以上存活细胞时,原来的存活细胞亦进入死亡状态。(细胞过于拥挤)

4 当周围有3个存活细胞时,空白网格变成存活细胞。(繁殖新细胞)

代码实现

首先定义两个常量,来代表一个细胞(网格)的生或空白的状态:

ALIVE = (124, 252, 0)  # 绿色
EMPTY = (0, 0, 0)      # 黑色

我这里取了个巧,直接用RGB颜色来表示细胞生存或者死亡这两种状态,因为在后面的pygame的展示中,ALIVE的细胞用绿色表示,EMPTY的区域用黑色表示。

下面几个变量是pygame里用到的参数,分别是屏幕的尺寸,x和y方向的网格数量,还有单个细胞的尺寸:

SCREEN_WIDHT = 600
SCREEN_HEIGHT = 600
X = 100   # X方向的网格数量
Y = 100   # Y方向的网格数量
CELL_WIDTH = SCREEN_WIDHT / X
CELL_HEIGHT = SCREEN_HEIGHT / Y

现在来定义一个细胞,也就是一个网格:

import pygame
from pygame.locals import *


class Cell:
    '''单个细胞'''
    def __init__(self, x, y):
        self.state = EMPTY
        self.rect = Rect(x * CELL_WIDTH, y * CELL_HEIGHT, 
                         CELL_WIDTH, CELL_HEIGHT)

    def draw(self, screen):
        pygame.draw.rect(screen, self.state, self.rect)

细胞的属性很简单,state代表当前状态,我们默认每个细胞初始都是死亡状态;rect属性是用pygame里的Rect对象构建的,表示一个矩形区域。最后有一个方法draw,能够将自身“画”到对应的screen上。

 接下来定义整个网格:

class Grid:
    def __init__(self, X, Y):
        self.X = X
        self.Y = Y
        self.rows = []
        for y in range(Y):
            self.rows.append([])
            for x in range(X):
                self.rows[y].append(Cell(x, y))

    def get_state(self, y, x):
        return self.rows[y % self.Y][x % self.X].state

    def set_state(self, y, x, state):
        self.rows[y % self.Y][x % self.X].state = state

    def draw(self, screen):
        for row in self.rows:
            for cell in row:
                cell.draw(screen)

网格对象的核心是他的rows属性,这是一个二维列表,列表中的每个位置都是一个细胞对象,可以通过坐标(x, y)定位到。另外定义了三个方法,get_state和set_state用来获取和改变某个坐标中的细胞的状态,这里要注意一下,因为细胞自动机会自发扩散进化,所以会出现超出列表长度的情况(就是超出屏幕导致报错),所以列表的下标没有简单的用x,y,而是做成了可以折返的效果。

以下两个模块级函数用于实现生命游戏的逻辑:

def count_neighbors(y, x, get_state):
    n_ = get_state(y - 1, x + 0)  # North
    ne = get_state(y - 1, x + 1)  # Northeast
    e_ = get_state(y + 0, x + 1)  # East
    se = get_state(y + 1, x + 1)  # Southeast
    s_ = get_state(y + 1, x + 0)  # South
    sw = get_state(y + 1, x - 1)  # Southwest
    w_ = get_state(y + 0, x - 1)  # West
    nw = get_state(y - 1, x - 1)  # Northwest
    neighbor_states = [n_, ne, e_, se, s_, sw, w_, nw]
    count = 0
    for state in neighbor_states:
        if state == ALIVE:
            count += 1
    return count

def next_state(state, neighbors):
    if state == ALIVE:
        if neighbors < 2:
            return EMPTY
        elif neighbors > 3:
            return EMPTY
    else:
        if neighbors == 3:
            return ALIVE
    return state

count_neighbors函数接收一个坐标和一个获取状态的函数,用来计算该坐标相邻的邻居坐标有多少个存活的细胞;next_state函数描述了生命游戏的核心规则,它接收细胞当前状态和周边邻居坐标中存活的细胞数量,输出下一个状态。有了这两个函数,就可以写单个细胞以及整个网格状态变化的逻辑了。

下面两个模块级函数是设置单个细胞和整个网格的新状态

def step_cell(y, x, get_state, set_state):
    state = get_state(y, x)
    neighbors = count_neighbors(y, x, get_state)
    new_state = next_state(state, neighbors)
    set_state(y, x, new_state)

def simulate(grid):
    new_grid = Grid(grid.X, grid.Y)
    for y in range(grid.Y):
        for x in range(grid.X):
            step_cell(y, x, grid.get_state, new_grid.set_state)
    return new_grid

其中,step_cell用来设置下一次细胞的状态,simulate用来返回下一代的网格。

主体代码都已经写好,下面开始测试了:

if __name__ == "__main__":
    # pygame初始化的相关内容
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_WIDHT, SCREEN_HEIGHT))
    pygame.display.set_caption('Game Of Live')
    framerate = pygame.time.Clock()

    # 设定网格的一个初始状态
    grid = Grid(X, Y)
    grid.set_state(2, 4, ALIVE)
    grid.set_state(2, 2, ALIVE)
    grid.set_state(3, 3, ALIVE)
    grid.set_state(3, 4, ALIVE)
    grid.set_state(4, 4, ALIVE)

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()

        grid.draw(screen)      # 将网格画到屏幕上
        grid = simulate(grid)  # 获得下一代网格

        pygame.display.update()
        framerate.tick(10)     # 设置每秒10帧

以上实现生命游戏的代码应该是非常简洁清晰的,代码一共也就100行左右,而且只要学一些pygame这个库的最基础知识,就可以实现这个非常神奇的效果。文章来源地址https://www.toymoban.com/news/detail-400549.html

到了这里,关于100行python代码实现细胞自动机(康威生命游戏)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • AC 自动机学习笔记

    AC自动机( (Aho Corasick Atomaton) )有着一种 (KMP) 的思想,所以在学习之前建议先学一下 (KMP) 。同时还需要了解一下 (Trie) 树(建议去看一下 oi-wiki 上的字典树) 给定一个字符串 (S) 和 (n) 模式串,问有多少个模式串在 (S) 中出现过。 首先我们把 (n) 个模式串组成一

    2024年02月11日
    浏览(38)
  • 「学习笔记」AC 自动机

    点击查看目录 目录 「学习笔记」AC 自动机 算法 问题 思路 代码 例题 Keywords Search 玄武密码 单词 病毒 最短母串 文本生成器 背单词 密码 禁忌 前置:「学习笔记」字符串基础:Hash,KMP与Trie。 好像对例题的讲解越来越抽象了? 求 (n) 个单词在一个长度为 (m) 的文章里出现

    2024年02月02日
    浏览(39)
  • 数学建模-元胞自动机

    2024年02月14日
    浏览(39)
  • 数模笔记14-元胞自动机

    元胞自动机理论 元胞自动机(Cellular Automata,CA)是一种时空离散的局部动力学模型,是研究复杂系统的一种典型方法,特别适合用于空间复杂系统的时空动态模拟研究。 元胞自动机不是由严格定义的物理方程或函数确定,而是用一系列模型构造的 规则 构成。凡是满足这些

    2024年02月09日
    浏览(37)
  • 元胞自动机(数学建模)

    一.元胞自动机的概念       元胞自动机(cellular automata,CA) 是一种时间、空间、状态都离散,空间相互作用和时间因果关系为局部的网格动力学模型,具有模拟复杂系统时空演化过程的能力。     元胞自动机是用一系列模型构造的 规则 构成,只要满足规则就可以算作是元胞

    2024年02月08日
    浏览(37)
  • 【数学建模】元胞自动机

    元胞自动机(Cellular Automaton,简称CA) 元胞自动机(Cellular Automaton,简称CA)是一种离散空间和时间的计算模型。它由许多简单的计算单元(称为元胞)组成,每个元胞可以处于有限的状态之一。元胞自动机通过在空间上进行迭代更新的方式,根据元胞自身的状态和邻居元胞

    2024年02月15日
    浏览(32)
  • KMP算法 - 确定有限状态自动机

    子串匹配问题,拍脑袋一下子想出来的暴力解法大抵都是两重for循环,不断重复扫描主串,与子串进行匹配,重复换句话讲就是冗余,会有很高的时间复杂度 我先前博客大作业发的 模糊查找算法 就是如此,我那里是在计算一个匹配度的问题,通过相同定位到相同字母判定开

    2024年02月09日
    浏览(45)
  • 【NLP】有限自动机的KMP算法

    目录 一、说明 二、无策略直接匹配法 2.1  简单粗暴的无脑匹配: 2.2 跳过外循环的思路

    2024年02月08日
    浏览(38)
  • 不确定有穷自动机NFA的确定化

    从文件读入一个非确定有穷状态自动机(NFA),用子集法将其确定化,并输出一个确定化的有穷状态自动机(DFA)。 原理: 流程图如下: 具体代码实现: 这里为了实现图形可视化,使用了graphviz,下载完成Graphviz工具后,需将其添加至系统环境变量中,且需将其上移至Matl

    2024年02月07日
    浏览(36)
  • 正规文法、正规表达式、有限自动机及其之间的转换(笔记)

    The Equivalent Transforming among RG, RE and FA A Grammar G is a quadruple (四元组):G = (V N , V T , S, P ) Where, V N is a finite set of nonterminals. V T is a finite set of terminals. S is the start symbol, S ∈ in ∈ V N . P is a finite set of productions (产生式). Regular Grammar (RG) (正规文法): α∈V N and β ∈V T ∪V T V N Regular Exp

    2024年02月08日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包