GameofLife

GAME OF LIFE

1、问题介绍

这是个模拟生命演化的游戏,在一个广阔的生存空间里,设定生命群落存活和繁衍的规则,个体和群落依据既相互竞争又相互依存的法则进行进化。

假定:对于每一个单元,在它的 3 × 3 3\times3 3×3邻域内:少于2邻居,死;多于3邻居,死;正好3邻居,生。

2、python模拟

规则:

  • 用Python实现游戏规则
  • 在1000x1000共一百万个单元里模拟
  • 尽量短的代码
  • 尽量高效

思路一:

对每个单元的3x3邻域进行统计

import random as random
import timeit

# 产生一个百万0,1数组,0代表空(死),1代表生
Z = [[random.choice([0,1]) for x in range(1000)] for y in range(1000)]

# 计算八个邻居数目
def neighbours(Z):
    s = len(Z), len(Z[0])
    # 一个初始全为0的邻居数量矩阵
    N = [[0,]*(s[0]) for i in range(s[1])]
    for x in range(1, s[0]-1):
        for y in range(1, s[1]-1):
            N[x][y] = (Z[x-1][y-1] + Z[x][y-1] + Z[x+1][y-1] +
                       Z[x-1][y]               + Z[x+1][y]   +
                       Z[x-1][y+1] + Z[x][y+1] + Z[x+1][y+1])
    return N

# 根据周围邻居总数应用规则
def evolve(Z):
    s = len(Z), len(Z[0])
    N = neighbours(Z)
    for x in range(1, s[0]-1):
        for y in range(1, s[1]-1):
            if Z[x][y] == 1 and (N[x][y] < 2 or N[x][y] > 3): # 灭亡规则
                Z[x][y] = 0
            elif Z[x][y] == 0 and N[x][y] == 3:               # 繁衍规则
                Z[x][y] = 1
    return Z
 
print(timeit.timeit(lambda: evolve(Z), number=3))             # 对百万人口作三代进化,统计运算效率

思路二:

把1000x1000共一百万个单元当作一个整体进行运算

import timeit
import numpy as np

Znp = np.random.randint(2, size=(1000,1000))
#print(Znp)
def nextGeneration(Z):
    neighborCount = sum(np.roll(np.roll(Z, i, 0), j, 1) for i in (-1, 0, 1) for j in (-1, 0, 1) if (i != 0 or j != 0))
    #return (neighborCount == 3) | ((neighborCount == 1) & (neighborCount == 2)).astype("int8")
    return (neighborCount == 3) | ((neighborCount == 1) & (neighborCount == 2))

def np_solver(Z):  
    #Z = np.argwhere(nextGeneration(Z))#下一代
    Z = np.where(nextGeneration(Z),1,0)#下一代
    return Z # 把实现填进来
    
print(timeit.timeit(lambda: np_solver(Znp), number=3))

思路三:

只对有生命的单元进行运算

from collections import namedtuple, defaultdict
import random as random
import timeit

Cell = namedtuple('Cell', ['x', 'y'])
Z = [[random.choice([0,1]) for x in range(10)] for y in range(10)]

def getNeighbours(cell):
    for x in range(cell.x - 1, cell.x + 2):
        for y in range(cell.y - 1, cell.y + 2):
            if (x, y) != (cell.x, cell.y):
                yield Cell(x, y)


def getNeighbourCount(board):
    neighbour_counts = defaultdict(int)
    for cell in board:
        for neighbour in getNeighbours(cell):
            neighbour_counts[neighbour] += 1
    return neighbour_counts


def advanceBoard(board):
    new_board = set()
    for cell, count in getNeighbourCount(board).items():
        if count == 3 or (cell in board and count == 2):
            new_board.add(cell)
    return new_board


def generateBoard(desc):
    board = set()
    row , col = len(desc),len(desc[0])
    for i in range(row):
        for j in range(col):
            if desc[i][j] == 1:
                board.add(Cell(int(i), int(j)))
    return board

def evolve(Z):
    f = generateBoard(Z)
    f = advanceBoard(f)
    return f

print(timeit.timeit(lambda: evolve(Z), number=3))  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值