使用VSCode开发少儿编程项目:生命游戏

康威生命游戏 - 少儿编程项目

下面是一个使用Python在VSCode中开发的康威生命游戏项目。这个项目通过简单的规则模拟细胞的演化过程,非常适合少儿理解细胞自动机和复杂系统的概念。

项目代码

创建一个名为game_of_life.py的新文件,然后复制以下代码:

# 康威生命游戏 - 少儿编程项目
# 规则:
# 1. 活细胞周围有2-3个活细胞时,继续存活
# 2. 死细胞周围恰好有3个活细胞时,复活
# 3. 其他情况下,细胞死亡或保持死亡

import numpy as np
import pygame
import sys
import time
import random

# 初始化pygame
pygame.init()

# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GRAY = (128, 128, 128)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 120, 255)

class GameOfLife:
    def __init__(self, width=800, height=600, cell_size=10):
        # 屏幕尺寸和细胞大小
        self.width = width
        self.height = height
        self.cell_size = cell_size
        
        # 计算网格尺寸
        self.cols = width // cell_size
        self.rows = height // cell_size
        
        # 创建屏幕
        self.screen = pygame.display.set_mode((width, height))
        pygame.display.set_caption("康威生命游戏 - 按空格键暂停/继续")
        
        # 初始化网格(随机状态)
        self.grid = np.zeros((self.rows, self.cols))
        self.initialize_random()
        
        # 游戏状态
        self.running = True
        self.paused = False
        self.generation = 0
        self.population = np.sum(self.grid)
        
        # 字体
        self.font = pygame.font.SysFont('simhei', 16)
        self.title_font = pygame.font.SysFont('simhei', 24)
        
        # 预定义图案
        self.patterns = {
            "滑翔机": self.create_glider,
            "脉冲星": self.create_pulsar,
            "高斯帕滑翔机枪": self.create_glider_gun,
            "方块": self.create_block,
            "飞船": self.create_spaceship
        }
    
    def initialize_random(self, density=0.2):
        """随机初始化网格"""
        self.grid = np.random.choice([0, 1], size=(self.rows, self.cols), p=[1-density, density])
    
    def create_glider(self, x, y):
        """创建滑翔机图案"""
        pattern = np.array([
            [0, 1, 0],
            [0, 0, 1],
            [1, 1, 1]
        ])
        self.place_pattern(x, y, pattern)
    
    def create_pulsar(self, x, y):
        """创建脉冲星图案"""
        pattern = np.zeros((15, 15))
        # 定义脉冲星的三个臂
        arms = [
            (2, 0), (3, 0), (4, 0),
            (0, 2), (0, 3), (0, 4),
            (5, 2), (5, 3), (5, 4),
            (2, 5), (3, 5), (4, 5)
        ]
        
        # 创建四个对称的部分
        for dx, dy in arms:
            pattern[dy, dx] = 1
            pattern[dy, 14-dx] = 1
            pattern[14-dy, dx] = 1
            pattern[14-dy, 14-dx] = 1
        
        self.place_pattern(x, y, pattern)
    
    def create_glider_gun(self, x, y):
        """创建高斯帕滑翔机枪图案(简化版)"""
        pattern = np.zeros((9, 36))
        
        # 高斯帕滑翔机枪的简化版本
        gun_coords = [
            (1, 5), (1, 6), (2, 5), (2, 6),
            (11, 5), (11, 6), (11, 7), (12, 4), (12, 8), (13, 3), (13, 9),
            (14, 3), (14, 9), (15, 6), (16, 4), (16, 8), (17, 5), (17, 6),
            (17, 7), (18, 6), (21, 3), (21, 4), (21, 5), (22, 3), (22, 4),
            (22, 5), (23, 2), (23, 6), (25, 1), (25, 2), (25, 6), (25, 7)
        ]
        
        for dy, dx in gun_coords:
            pattern[dy, dx] = 1
        
        self.place_pattern(x, y, pattern)
    
    def create_block(self, x, y):
        """创建方块图案"""
        pattern = np.array([
            [1, 1],
            [1, 1]
        ])
        self.place_pattern(x, y, pattern)
    
    def create_spaceship(self, x, y):
        """创建飞船图案"""
        pattern = np.array([
            [0, 1, 1, 1, 1],
            [1, 0, 0, 0, 1],
            [0, 0, 0, 0, 1],
            [1, 0, 0, 1, 0]
        ])
        self.place_pattern(x, y, pattern)
    
    def place_pattern(self, x, y, pattern):
        """在指定位置放置图案"""
        h, w = pattern.shape
        for i in range(h):
            for j in range(w):
                if 0 <= y+i < self.rows and 0 <= x+j < self.cols:
                    self.grid[y+i, x+j] = pattern[i, j]
    
    def count_neighbors(self, grid, x, y):
        """计算细胞周围的活细胞数量"""
        # 使用numpy的切片操作计算邻居数量
        # 考虑边界条件(使用模运算实现环形边界)
        total = np.sum(grid[(y-1)%self.rows:(y+2)%self.rows, (x-1)%self.cols:(x+2)%self.cols])
        # 减去中心细胞自身
        return total - grid[y, x]
    
    def update(self):
        """更新网格状态"""
        if self.paused:
            return
        
        # 创建邻居计数网格
        neighbors = np.zeros((self.rows, self.cols))
        for y in range(self.rows):
            for x in range(self.cols):
                neighbors[y, x] = self.count_neighbors(self.grid, x, y)
        
        # 应用生命游戏规则
        # 活细胞规则:2-3个邻居存活
        survive = (self.grid == 1) & ((neighbors == 2) | (neighbors == 3))
        # 死细胞规则:恰好3个邻居复活
        born = (self.grid == 0) & (neighbors == 3)
        
        # 更新网格
        self.grid = np.where(survive | born, 1, 0)
        
        # 更新统计信息
        self.generation += 1
        self.population = np.sum(self.grid)
    
    def draw(self):
        """绘制网格和界面"""
        # 清空屏幕
        self.screen.fill(BLACK)
        
        # 绘制网格线
        for x in range(0, self.width, self.cell_size):
            pygame.draw.line(self.screen, GRAY, (x, 0), (x, self.height), 1)
        for y in range(0, self.height, self.cell_size):
            pygame.draw.line(self.screen, GRAY, (0, y), (self.width, y), 1)
        
        # 绘制活细胞
        for y in range(self.rows):
            for x in range(self.cols):
                if self.grid[y, x] == 1:
                    rect = pygame.Rect(x*self.cell_size, y*self.cell_size, 
                                      self.cell_size, self.cell_size)
                    pygame.draw.rect(self.screen, GREEN, rect)
        
        # 绘制信息面板
        self.draw_info_panel()
        
        # 更新显示
        pygame.display.flip()
    
    def draw_info_panel(self):
        """绘制信息面板"""
        # 半透明背景
        info_bg = pygame.Surface((self.width, 60))
        info_bg.set_alpha(180)
        info_bg.fill(BLACK)
        self.screen.blit(info_bg, (0, 0))
        
        # 标题
        title = self.title_font.render("康威生命游戏", True, WHITE)
        self.screen.blit(title, (10, 10))
        
        # 统计信息
        stats = [
            f"代数: {self.generation}",
            f"种群: {int(self.population)}",
            f"状态: {'运行中' if not self.paused else '已暂停'}"
        ]
        
        for i, text in enumerate(stats):
            rendered = self.font.render(text, True, WHITE)
            self.screen.blit(rendered, (10, 40 + i*20))
        
        # 控制说明
        controls = [
            "空格键: 暂停/继续",
            "R键: 随机初始化",
            "C键: 清空网格",
            "1-5键: 放置预设图案",
            "鼠标点击: 切换细胞状态"
        ]
        
        for i, text in enumerate(controls):
            rendered = self.font.render(text, True, BLUE)
            self.screen.blit(rendered, (self.width - 200, 10 + i*20))
    
    def handle_events(self):
        """处理用户输入事件"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
            
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    self.paused = not self.paused
                elif event.key == pygame.K_r:
                    self.initialize_random()
                    self.generation = 0
                elif event.key == pygame.K_c:
                    self.grid = np.zeros((self.rows, self.cols))
                    self.generation = 0
                elif event.key in [pygame.K_1, pygame.K_2, pygame.K_3, pygame.K_4, pygame.K_5]:
                    # 放置预设图案
                    pattern_idx = event.key - pygame.K_1
                    pattern_names = list(self.patterns.keys())
                    if pattern_idx < len(pattern_names):
                        pattern_name = pattern_names[pattern_idx]
                        pattern_func = self.patterns[pattern_name]
                        # 清空网格并放置图案在中央
                        self.grid = np.zeros((self.rows, self.cols))
                        center_x = self.cols // 2
                        center_y = self.rows // 2
                        pattern_func(center_x, center_y)
                        self.generation = 0
                        print(f"已放置图案: {pattern_name}")
            
            elif event.type == pygame.MOUSEBUTTONDOWN:
                # 鼠标点击切换细胞状态
                if event.button == 1:  # 左键
                    x, y = pygame.mouse.get_pos()
                    grid_x = x // self.cell_size
                    grid_y = y // self.cell_size
                    if 0 <= grid_x < self.cols and 0 <= grid_y < self.rows:
                        self.grid[grid_y, grid_x] = 1 - self.grid[grid_y, grid_x]
    
    def run(self):
        """运行游戏主循环"""
        clock = pygame.time.Clock()
        
        print("康威生命游戏已启动!")
        print("规则说明:")
        print("1. 活细胞周围有2-3个活细胞时,继续存活")
        print("2. 死细胞周围恰好有3个活细胞时,复活")
        print("3. 其他情况下,细胞死亡或保持死亡")
        print("\n控制说明:")
        print("空格键: 暂停/继续")
        print("R键: 随机初始化")
        print("C键: 清空网格")
        print("1-5键: 放置预设图案")
        print("鼠标点击: 切换细胞状态")
        
        while self.running:
            self.handle_events()
            self.update()
            self.draw()
            clock.tick(10)  # 控制更新速度
        
        pygame.quit()
        sys.exit()

# 主程序
if __name__ == "__main__":
    # 创建并运行游戏
    game = GameOfLife(width=800, height=600, cell_size=10)
    game.run()

安装必要的库

在运行项目前,需要安装Pygame和NumPy库。在VSCode的终端中运行以下命令:

pip install pygame numpy

如何在VSCode中运行

  1. 打开VSCode
  2. 创建一个新文件,命名为game_of_life.py
  3. 将上面的代码复制到文件中
  4. 保存文件
  5. 点击右上角的"运行"按钮(三角形图标)或按F5键运行程序

项目扩展建议

对于想要进一步挑战的学生,可以考虑以下扩展功能:

  1. 更多预设图案:添加更多有趣的细胞图案,如蜜蜂巢、反应扩散系统等
  2. 图案库:创建一个图案库,允许用户保存和加载自定义图案
  3. 速度控制:添加滑块或按键来控制模拟速度
  4. 统计图表:显示种群数量随时间变化的图表
  5. 规则自定义:允许用户自定义生命游戏的规则(如S/B规则)
  6. 颜色主题:添加多种颜色主题选择
  7. 缩放功能:实现网格的缩放和平移功能

教学要点

  1. 细胞自动机概念:解释什么是细胞自动机及其在计算机科学中的应用
  2. 康威生命游戏规则:详细讲解三条基本规则及其背后的逻辑
  3. 复杂系统:讨论简单规则如何产生复杂行为
  4. 网格计算:介绍如何使用二维数组表示和操作网格
  5. 邻居计算:解释如何高效计算每个细胞的邻居状态
  6. 可视化编程:展示如何将数据可视化并与用户交互

简化版(无Pygame依赖)

如果不想安装Pygame,可以使用以下基于终端的简化版本:

# 康威生命游戏 - 终端版本
import numpy as np
import time
import os

class SimpleGameOfLife:
    def __init__(self, rows=20, cols=40):
        self.rows = rows
        self.cols = cols
        self.grid = np.zeros((rows, cols))
        self.initialize_random(0.2)
        self.generation = 0
    
    def initialize_random(self, density=0.2):
        """随机初始化网格"""
        self.grid = np.random.choice([0, 1], size=(self.rows, self.cols), p=[1-density, density])
    
    def count_neighbors(self, x, y):
        """计算细胞周围的活细胞数量"""
        total = 0
        for i in range(-1, 2):
            for j in range(-1, 2):
                if i == 0 and j == 0:
                    continue
                nx, ny = (x + j) % self.cols, (y + i) % self.rows
                total += self.grid[ny, nx]
        return total
    
    def update(self):
        """更新网格状态"""
        new_grid = np.copy(self.grid)
        
        for y in range(self.rows):
            for x in range(self.cols):
                neighbors = self.count_neighbors(x, y)
                
                # 应用生命游戏规则
                if self.grid[y, x] == 1:  # 活细胞
                    if neighbors < 2 or neighbors > 3:
                        new_grid[y, x] = 0  # 死亡
                else:  # 死细胞
                    if neighbors == 3:
                        new_grid[y, x] = 1  # 复活
        
        self.grid = new_grid
        self.generation += 1
    
    def display(self):
        """在终端显示网格"""
        os.system('cls' if os.name == 'nt' else 'clear')  # 清屏
        
        print(f"康威生命游戏 - 第 {self.generation} 代")
        print("=" * (self.cols + 2))
        
        for y in range(self.rows):
            line = "|"
            for x in range(self.cols):
                if self.grid[y, x] == 1:
                    line += "●"  # 活细胞
                else:
                    line += " "  # 死细胞
            line += "|"
            print(line)
        
        print("=" * (self.cols + 2))
        print("按 Ctrl+C 停止")
    
    def run(self, delay=0.5):
        """运行游戏"""
        try:
            while True:
                self.display()
                self.update()
                time.sleep(delay)
        except KeyboardInterrupt:
            print("\n游戏结束!")

# 运行简化版
if __name__ == "__main__":
    game = SimpleGameOfLife(rows=20, cols=40)
    game.run(delay=0.3)

这个项目结合了数学、计算机科学和生物学概念,通过简单的规则展示了复杂系统的演化,非常适合培养少儿的逻辑思维和编程能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值