博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python实现康威生命游戏
阅读量:3959 次
发布时间:2019-05-24

本文共 5398 字,大约阅读时间需要 17 分钟。

文章目录


前言

设计很有趣,我的方法是借助pygame进行外观的展示,最近一段时间的游戏项目都是使用pygame进行的,做起来比较顺利。算法代码的实现也比较简单,根据游戏规则我们需要的是多次的计算周围生命数和该生命的存亡判断,再刷新数组进行游戏外观展示。


一、游戏规则

  • 当周围仅有1个或没有存活细胞时, 原来的存活细胞进入死亡状态。(模拟生命数量稀少)
  • 当周围有2个或3个存活细胞时, 网格保持原样。
  • 当周围有4个及以上存活细胞时,原来的存活细胞亦进入死亡状态。(模拟生命数量过多)
  • 当周围有3个存活细胞时,空白网格变成存活细胞。(模拟繁殖)

二、设计流程

1、引入库

代码如下(示例):

import sysimport randomimport numpy as npimport pygame

2、设计思路

在这篇博客里面我们实现了下面第一个图的内容。

在这里插入图片描述
感兴趣的朋友也可以加下面的思路:
在这里插入图片描述

3、设计

窗口

首先我们借用了之前的pygame窗口的代码,实现窗口的调用。与之前有所不同的变化是,我们在展开窗口之前首先确定大小。

我们实现了游戏大小的自定义,窗口大小的自定义,可以与后面游戏设计增加统一性,增加美观性。
中间的部分代码是一些颜色的调出,和窗口的填充。
在这里插入图片描述

import sysimport randomimport numpy as npimport pygamepygame.init()#初始化init()及设置n=int(input("请输入阶数:"))size=width,height=50*n+2,50*n+2screen=pygame.display.set_mode(size)#窗口大小pygame.display.set_caption("康威生命游戏")#窗口名字icon=pygame.image.load("Icon.jpg")pygame.display.set_icon(icon)BLACK=pygame.Color("black")GAINSBORO=pygame.Color("gainsboro")MOCCASIN=pygame.Color("moccasin")WHITE=pygame.Color("white")screen.fill(MOCCASIN)fps=5fclock=pygame.time.Clock()#创建一个Clock对象用于操作时间while True:    for event in pygame.event.get():        if event.type == pygame.QUIT:  # 点击了退出            sys.exit()  # 退出    pygame.display.update()  # 对显示窗口进行更新,默认窗口全部重绘    fclock.tick(fps)  # 窗口刷新速度,每秒3次

初始生命矩阵

我们通过循环产生随机数来产生随机的初始生命。

random.randint(a,b):产生一个位于a-b之间的随机整数,包括a,b。

## 生成初始生命a=[]for i in range(0,n):    a.append([])    for j in range(0,n):        a[i].append(random.randint(0,1))

周围生命的检测

我们将生命周围八个位置的索引差值存放在一个列表中,通过循环检测有效位置上生命的个数,存放入列表中。

包含两个判断。

  1. 首先要判断位置的有效性
  2. 另一个是判断是否有生命
direction = [[-1, -1], [0, -1], [1, -1], [1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0]]    c = []    # 计算周围生命个数    for i in range(0, n):        c.append([])        for j in range(0, n):            count = 0   # 每一个方格            for o in direction:                ide = np.array([i, j]) + np.array(o)                # 保证判断的位置在范围内,针对边界方格                if 0 <= ide[0] < n and 0 <= ide[1] < n:                    if a[ide[0]][ide[1]] == 1:                        count += 1            c[i].append(count)

生命的变化

将每个位置上的生命根据计数列表进行更新,更新生命矩阵。

## 按照生命的发展规律进行新一轮的生面变化    for i in range(0, n):        for j in range(0, n):            if c[i][j] <= 1 or c[i][j] >= 4:#当生命稀少或者过多时生命死亡                a[i][j] = 0            elif c[i][j] == 3:#当生命的周围有三个生命时,生成新生命                a[i][j] = 1

生命的展示

画出生命的方格很简单,我们调用pygame的绘制图形代码:

pygame.draw.rect(screen, BLACK, (i*50, j*50, 50, 50)):这样展示出来的是一个填充的矩形,展示在:screen上,初始位置为:(i * 50, j * 50),大小为:(50, 50),颜色为:black,默认边框为0,即全部填充的矩形,当后面添加一个数字时,代表无填充,框线为数字大小的矩形,如:pygame.draw.rect(screen, GAINSBORO, (i*50, j*50, 50, 50),2)代表不填充,框线为2
通过画图重叠,我们实现每个生命之间的间隔的样式,增强渲染效果。

for i in range(0, n):        for j in range(0, n):            if a[i][j]==1:                #先画一个满填充的方格,有生命方格                pygame.draw.rect(screen, BLACK, (i*50, j*50, 50, 50))                #再画一个不填充,框线为2的方格,套在上面的方格上面                pygame.draw.rect(screen, GAINSBORO, (i*50, j*50, 50, 50),2)            else:#无生命方格                pygame.draw.rect(screen, WHITE, (i*50, j*50, 50, 50))                pygame.draw.rect(screen, GAINSBORO, (i*50, j*50, 50, 50),2)

完整代码

"""# -*- coding: utf-8 -*-# @Time    : 2021/4/23 0023 17:14# @Author  : 源来很巧# @FileName: 康威生命游戏2.py# @Software: PyCharm# @Blog    :https://blog.csdn.net/qq_44793283"""import sysimport randomimport numpy as npimport pygamepygame.init()#初始化init()及设置n=int(input("请输入阶数:"))size=width,height=50*n+2,50*n+2screen=pygame.display.set_mode(size)#窗口大小pygame.display.set_caption("康威生命游戏")#窗口名字icon=pygame.image.load("Icon.jpg")pygame.display.set_icon(icon)BLACK=pygame.Color("black")GAINSBORO=pygame.Color("gainsboro")MOCCASIN=pygame.Color("moccasin")WHITE=pygame.Color("white")screen.fill(MOCCASIN)fps=1fclock=pygame.time.Clock()#创建一个Clock对象用于操作时间## 生成初始生命a=[]for i in range(0,n):    a.append([])    for j in range(0,n):        a[i].append(random.randint(0,1))## 八个方位的索引变化direction = [[-1, -1], [0, -1], [1, -1], [1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0]]while True:    for event in pygame.event.get():        if event.type == pygame.QUIT:  # 点击了退出            sys.exit()  # 退出    c = []    # 计算周围生命个数    for i in range(0, n):        c.append([])        for j in range(0, n):            count = 0   # 每一个方格            for o in direction:                ide = np.array([i, j]) + np.array(o)                # 保证判断的位置在范围内,针对边界方格                if 0 <= ide[0] < n and 0 <= ide[1] < n:                    if a[ide[0]][ide[1]] == 1:                        count += 1            c[i].append(count)    ## 按照生命的发展规律进行新一轮的生面变化    for i in range(0, n):        for j in range(0, n):            if c[i][j] <= 1 or c[i][j] >= 4:#当生命稀少或者过多时生命死亡                a[i][j] = 0            elif c[i][j] == 3:#当生命的周围有三个生命时,生成新生命                a[i][j] = 1    for i in range(0, n):        for j in range(0, n):            if a[i][j]==1:                #先画一个满填充的方格,有生命方格                pygame.draw.rect(screen, BLACK, (i*50, j*50, 50, 50))                #再画一个不填充,框线为2的方格,套在上面的方格上面                pygame.draw.rect(screen, GAINSBORO, (i*50, j*50, 50, 50),2)            else:#无生命方格                pygame.draw.rect(screen, WHITE, (i*50, j*50, 50, 50))                pygame.draw.rect(screen, GAINSBORO, (i*50, j*50, 50, 50),2)    print(np.array(a))    pygame.display.update()  # 对显示窗口进行更新,默认窗口全部重绘    fclock.tick(fps)  # 窗口刷新速度,每秒3次

总结

这个游戏的实际设计并不是很困难,我们需要将具体的思路理顺,哪一步首先进行,需要我们准备哪些存储的矩阵等等。唯一的弯路是周围生命个数的检测,我的方法是穷举法,将每个位置索引只差手动计算存储起来。在小的计算量下,这层循环计算并不会浪费很多时间,如果您对此有好的建议欢迎交流。也欢迎对后面的游戏结束进行交流,后续我可以补上结束游戏的方法。

你可能感兴趣的文章
五.CSS选择器
查看>>
六.CSS尺寸
查看>>
七.CSS分类 (Classification)
查看>>
八.CSS媒介类型
查看>>
九.CSS注意事项
查看>>
一.JavaScript 基础
查看>>
二.JavaScript 对象
查看>>
三.JavaScript 高级
查看>>
WEB-INF目录下的文件(比如JSP)之间如何访问
查看>>
1.ECMAScript简介
查看>>
2.ECMAScript 基础
查看>>
3.ECMAScript 运算符
查看>>
4.ECMAScript 语句
查看>>
5.ECMAScript 函数概述
查看>>
6.ECMAScript 对象
查看>>
7.ECMAScript 继承
查看>>
HTML DOM
查看>>
AJAX 基础
查看>>
JSON 基础
查看>>
J2EE监听器Listener接口大全[转]
查看>>