''' 整体思路 植物生长分7个阶段,遵循以下规则 1> 每经过一回合就进入下一阶段 2> 部分阶段是敏感期(2,4,6)临近区域的植物'过壮'就死亡(我设计成15) 3> 死亡时,会留下遗骸,遗骸的生命力是负值,是hp的相反数(越大的植物死亡,腐化时间越长) 4> 遗骸每回合恢复1,恢复到0之前,种子无法在这里萌发 5> 后四个生育阶段,都会释放种子 分别释放 1231个 备注 1> 因为我的错误 规则2>并没有起到预期的作用 2> 246阶段死亡,hp = -hp,7阶段死亡就成了hp = -hp*4 这里纯粹是我个人的疏忽 个人认为的要点: 1> 棋盘的复制, 同回合的棋子不相互影响!!!!!!格子只受上回合棋盘的影响. 假定AB临近 A根据周边(包括B)变成的 新A ,'B 变 新B '的过程参考的应该是 旧A 而不是新A 2> 如果棋盘是 双层嵌套的list ,请注意"深浅拷贝" ''' from copy import deepcopy from random import sample,randint import pygame import os # 图形界面是pygame,只有这个模块需要安装 ''' aound_dict全局常量,只读不改,内容是 (0, 0), (-1, 0), (1, 1), (1, 0), (-1, 1), (0, -1), (-1, -1), (1, -1), (0, 1)} 是以(0,0)为中心的 3x3 区域的相对坐标 ''' around_dict = {(i,j) for i in range(-1,2) for j in range(-1,2) } # around_dict应当是列表,是我错写成集合了,但不影响结果 #-----------------导入结束----------------------- def ask(z): # z是坐标,二元元组 # 返回该坐标在上回合的值 # 超范围的默认为0 x,y = z if 0 <= x < x_max and 0 <= y < y_max: return max_copy[y][x] return 0 def probe(z): # 判断坐标是否越界 x,y = z return 0 <= x < x_max and 0 <= y < y_max def around(x,y): return sum(list(map(ask,around_dict))) # 返回 x,y 为中心的3x3区域的"总生命值" # 我当初写错了.... # 应当是 ''' def around(x,y): around_dict = [(x+i,y+j) for i,j in around_dict] return sum(list(map(ask,around_dict))) ''' def release_seed(x,y,n): # 以x,y为中心 释放n枚种子 l = [(x+i,y+j)for i,j in sample(k49,n)] l = filter(probe,l) # 过滤越界的种子 seeds.update(set(l)) # set成 集合 过滤重复元素 # 因为seed本身就是set, set(l)有些多余 def drow(): # 绘制界面的函数 screen.fill((255,255,255)) for x in range(x_max): for y in range(y_max): hp = max_list[y][x] pygame.draw.rect(screen, colors[hp], (x * 5, y * 5, 5, 5)) # colors是字典 key是hp,value是对应颜色的RGB值 pygame.display.update() #-----------------函数定义结束------------------- x_max = 180 y_max = 120 max_list = [[0 for i in range(x_max)]for j in range(y_max)] # max_list 是"棋盘",以双重列表的形式储存每一块的值,这里初始化棋盘 max_copy = [] # max_copy 是"棋盘的拷贝",此处相当于声明变量 seeds = {(90,60)} # 最开始的种子 k49 = [(i,j)for i in range(-3,4)for j in range(-3,4)] # 和aound_dict类似,但是这个是7x7范围的表,以0,0为中心,所以是-3到3 def run_one(): # 这是个每个回合都要执行的函数 global max_copy,max_list max_copy = deepcopy(max_list) #deepcopy是copy模块的内容,用来拷贝棋盘,不懂的请自行了解"深浅拷贝" #ss = 10 - len(seeds)//30 # ss是"发芽率" 因图形不好看废弃这个设定 # 这是是要根据种子数量,实现"动态发芽率",种子少,发芽率高 # 种子多,发芽率低,用来限制草地规模 for x,y in seeds: if max_list[y][x] : pass else: max_list[y][x] = 1 #if randint(1,10)<=ss else 0 # seeds 是所有"种子"的列表, 如果种子落到了有植物(>0)或是荒地(<0)的格子,则什么都不会发生 # 如果恰好为0,则发芽,hp更新成1 # '#if randint(1,10)<=ss else 0'是废弃的发芽率设定 seeds.clear() # 清空种子 for x in range(x_max): for y in range(y_max): # 两层for遍历所有方格 hp = max_list[y][x] # 读取hp # 4-7 1231 # 连续的if 不同的hp有不同的处理流程 if not hp: pass elif hp < 0: hp += 1 elif hp in {2,4,6}: if around(x,y) > 15 : hp = -hp*1 if hp-3 > 0: release_seed(x,y,hp-3) hp+=1 elif hp in {1,3,5}: hp += 1 if hp == 5: release_seed(x,y,2) elif hp == 7: release_seed(x,y,1) hp = -7*4 max_list[y][x] = hp #-----------------pygame时间---------------- pygame.init() screen = pygame.display.set_mode((900,600)) pygame.display.set_caption("begin") fps = 100 fclock = pygame.time.Clock() colors = {-7: (181, 181, 181), -6: (181, 181, 181), -5: (181, 181, 181), -4: (181, 181, 181), -3: (181, 181, 181),-2: (181, 181, 181), -1: (181, 181, 181), 0:(232, 232, 232),1: (154, 255, 154), 2: (154, 255, 154), 3: (154, 255, 154),4: (0, 255, 0), 5: (0, 255, 0), 6: (0, 255, 0), 7: (0, 255, 0) } colors.update( {i:(181, 181, 181)for i in range(-35,-7)} ) go = True # go = False # go是暂停用的....按空格暂停/继续 time = 0 num = 0 # time 是用来控制更新频率的 # 因为我的更改 现在time是虚设.... while True: for event in pygame.event.get(): if event.type == pygame.QUIT: os._exit(0) elif event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: go = not go if go: time += 100 if time >= 50: run_one() drow() num+=1 pygame.display.set_caption("第%d轮"%(num)) time = 0 else: time+=0 fclock.tick(fps)