python实现元胞自动机

        这是刚学习写代码时完成的,因此很多地方编写的可能不太美观,但运行起来没有问题,先发出来,之后有精力了在修改美化。

该元胞自动机的功能:

1.初始化按一定概率在各个位置生成元胞。

2.迭代,每次迭代元胞八个方向若没有一个以上存活的元胞数量,则该元胞死亡;若一个空格子周围有三个及三个以上元胞存活,则该空格子出长出新元胞。

3.不断迭代,直到所有元胞存活状态不再改变(或所有元胞全部死亡)。

放几张运行时截图

 

 

 代码如下:

import os
from random import random
import numpy as np
import copy

#系统指定生命空间的大小,也即:6行;6列
width=6
hight=6

###辅助函数1 初始化生命空间
def init(life_prob):
    #(life_prob=0.2):
    life=[]
    for i in range(hight):
        life.append([])
        for j in range(width):
            
            if random()<=life_prob:
                life[i].append('*')
            else:
                life[i].append(" ")
    
        
    return np.array(life)
   
    
        
    """
    初始化游戏,以life_prob的概率生成活细胞
    输入:life_prob——生成活细胞的概率
    输出:width x height大小的细胞状态
    """   
    
        
    
###辅助函数2 打印细胞状态
def print_screen(screen):
    """ 
    screen 参数类型与init()函数返回值类型一致,表示当前
    细胞状态。由于屏幕打印时行距比字符宽度大很多,所以请在打印
    每个字符后面加空格,并在最后一个字符的后面打印'|'表示生命
    空间的边界(注意:表示生命空间边界的符号可以换成你们喜欢的符号,不局限
    于'|')
    """
    
    for i in screen:
        for j in i:
            print(j,end="   ")
        print('|\n')

###辅助函数3 计算相邻细胞中活细胞的数目
def get_near_by_cells_count(screen, i, j):
    """
    get_near_by_cells_count()的形参有:screen, i,j;
    其中screen与init()函数的返回值类型一致,表示当前细胞的状态;
    i和j均为int类型,表示生命空间各细胞,也即:n*n空间内的格子,所在的行号和列号
    函数返回值为int类型,表示位置(i,j)的细胞其相邻活细胞的数量
    """
    survival_numbers=[]
    '''四个角落'''
    if i==1 and j==1:
        if screen[0][1]=='*':
            survival_numbers.append(screen[0][1])
        if screen[1][1]=='*':
            survival_numbers.append(screen[1][1])
        if screen[1][0]=='*':
            survival_numbers.append(screen[1][0])
        nums=len(survival_numbers)
    elif i==1 and j==width:
        if screen[0][width-2]=='*':
            survival_numbers.append(screen[0][width-2])
        if screen[1][width-1]=='*':
            survival_numbers.append(screen[1][width-1])
        if screen[1][width-2]=='*':
            survival_numbers.append(screen[1][width-2])
        nums=len(survival_numbers)
    elif i==hight and j==1:
        if screen[i-1][1]=='*':
            survival_numbers.append(screen[i-1][1])
        if screen[i-2][0]=='*':
            survival_numbers.append(screen[i-2][0])
        if screen[i-2][1]=='*':
            survival_numbers.append(screen[i-2][1])
        nums=len(survival_numbers)
    elif i==hight and j==width:
        if screen[i-1][j-2]=='*':
            survival_numbers.append(screen[i-1][j-2])
        if screen[i-2][j-1]=='*':
            survival_numbers.append(screen[i-2][j-2])
        if screen[i-2][j-2]=='*':
            survival_numbers.append(screen[i-2][j-1])
        nums=len(survival_numbers)
        
# 边框

    elif (i==1 or i==hight) and 1<j<width:
        if i==1:
            a=screen[i][j-2:j+1]
            c=[screen[i-1][j-2],screen[i-1][j]]
        else:
            a=screen[i-2][j-2:j+1]
            c=[screen[i-1][j-2],screen[i-1][j]]
        c.extend(a)
        nums=c.count('*')
        
        
    elif 1<i<hight and (j==1 or j==width):
        if j==1:
            c=[screen[i][j-1],screen[i-2][j-1],screen[i-2][j],screen[i-1][j],screen[i][j]]
        else:
            c=[screen[i][j-1],screen[i-2][j-1],screen[i-2][j-2],screen[i-1][j-2],screen[i][j-2]]
# 中间     
        nums=c.count('*')
    elif 1<i<hight and 1<j<width:
        c=[screen[i][j],screen[i][j-1],screen[i][j-2],screen[i-1][j],screen[i-1][j-2],screen[i-2][j],screen[i-2][j-1],screen[i-2][j-2]]
        nums=c.count('*')
    return nums
     

###辅助函数4 更新细胞的状态
def update(screen):
    """
    该函数包含一个参数,screen,其类型与init()函数返回值类型一致,表示当前
    细胞状态。该函数根据传入生命空间screen内细胞的状态,利用更新原则对细胞
    状态进行更新,并返回更新后的细胞状态,返回值类型与screen类型一致
    
    """
    new_screen=copy.copy(screen)
    for i in range(hight):
        for j in range(width):
            if get_near_by_cells_count(screen, i+1, j+1)==3:
                new_screen[i][j]='*'
            elif get_near_by_cells_count(screen, i+1, j+1)==2:
                pass
            else:
                new_screen[i][j]=' '
                
    return new_screen
    


###辅助函数5,判断细胞状态是否没有变化

def is_state_same(screen, new_screen):
    """
    参数screen和new_screen分别表示更新前和更新后的细胞状态
    根据判断更新前后细胞的状态,如果更新前细胞(i,j)的状态与更新后细胞(i,j)
    的状态一致,则返回True;否则返回False
    
    """
    for i in range(hight):
        for j in range(width):
            if new_screen[i][j]==screen[i][j]:
                pass
            else:
                return False
    return True


###辅助函数6,循环更新细胞直至细胞生命状态不变,实现人机互动
def _main(screen, new_screen,cycle_index):   
    while not is_state_same(screen, new_screen):
        
        #实现人机互动,如果按q键则结束游戏;如果按其他键则继续游戏
        print('按下任意键继续,q键结束')
        _input_nums=input()
        print('\n')
        if _input_nums=='q':
            return 'game over'
        #打印每次更新后的细胞状态
        for i in new_screen:
            for j in i:
                print(j,end='   ')
            print('|\n')
        print('细胞更新前后生命状态不同')
        print('更新了',cycle_index,'次')
        #更新细胞
        screen=update(screen)
        new_screen=update(screen)
        #判断细胞更新前后生命状态是否相同 若相同游戏结束
        if is_state_same(screen, new_screen)==True:
            print('按下任意键继续,q键结束')
            _input_nums=input()
            print('\n')
            if _input_nums=='q':
                return 'game over'
            for i in new_screen:
                for j in i:
                    print(j,end='   ')
                print('|\n')
            print('细胞更新状态前后无变化')
            print('更新了',cycle_index+1,'次')
            return 'game over'
        cycle_index=cycle_index+1
     
    
#####以下为主程序,主要实现游戏实现与人机互动
def start():
    """
    (1)游戏开始后,用户输入活细胞的概率:life_prob的值,并调用辅助函数1 
    实现生命空间内细胞状态的随机生成
    (2)根据辅助函数1生成的细胞状态,调用辅助函数2,将当前细胞的状态进行打印
    (3)实现人机互动,如果按q键则结束游戏;如果按其他键则继续游戏
    (4)提示:如果要继续游戏,则需要对细胞生命状态进行更新,也即需要调用辅助函数3;
    并判断细胞生命状态更新前后差异,如果没有变化则终止游戏
    """

    ##以下代码实现了输入任意键游戏开始功能
    os.system("cls") # 用于清空窗口之前打印的内容
    print('==== 元胞自动机 ====')
    print('按下任意键开始游戏...')
    input()
    os.system("cls")
    ##请在以下部分实现主程序的上述功能
    # (1)游戏开始后,用户输入活细胞的概率:life_prob的值,并调用辅助函数1 
    #实现生命空间内细胞状态的随机生成
    life_prob=float(input('请输入细胞存活概率:'))
    screen=init(life_prob)
    #(2)根据辅助函数1生成的细胞状态,调用辅助函数2,将当前细胞的状态进行打印
    print_screen(screen)
    
    new_screen=update(screen)
    cycle_index=1
    _main(screen, new_screen, cycle_index)
   
   
        
    
   
   


###以下为主程序的测试代码
if __name__ == "__main__":
    
    # 以下为start()函数的测试代码
    start()

  • 26
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值