吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2582|回复: 4
收起左侧

[Python 转载] 【python】Game of Life 生命游戏——初学面向对象试水

[复制链接]
jjjzw 发表于 2021-4-20 19:34
本帖最后由 jjjzw 于 2021-4-20 19:42 编辑

python终于学到了面向对象这块,感觉有点难度
学了半天迷迷糊糊,决定动手写点什么来理解一下这些概念

生命游戏规则:每个细胞死或活的状态由它周围的八个细胞所决定。

规则

规则

之所以选这个游戏,是它有比较明显的对象类:细胞、规则等
用比较熟悉的pygame库来显示界面

细胞类:cell.py
[Python] 纯文本查看 复制代码
class Cell:
    def __init__(self, neighbour, is_live, position, charge):
        self.neighbour = neighbour
        self.is_live = is_live
        self.position = position
        self.charge = charge

    def change(self):
        if self.neighbour == 3:
            self.is_live = 1
        elif self.neighbour == 2:
            pass
        else:
            self.is_live = 0

    def convert(self):
        if self.is_live == 0:
            self.is_live = 1
        else:
            self.is_live = 0


规则类:rule.py
[Python] 纯文本查看 复制代码
from cell import Cell

cell_list = []


class Rule:
    def __init__(self, width, height, wow, state):
        self.width = width
        self.height = height
        self.wow = wow
        self.state = state

    def run(self):
        for i in range(0, self.width//self.wow):
            for j in range(0, self.height//self.wow):
                new_cell = Cell(0, 0, (i, j), 0)
                cell_list.append(new_cell)

    @staticmethod
    def get_neighbour():
        for cell in cell_list:
            cell.neighbour = 0
            x = cell.position[0] - 1
            y = cell.position[1] - 1
            for i in range(0, 3):
                for j in range(0, 3):
                    if (i, j) != (1, 1):
                        for cell2 in cell_list:
                            if cell2.position == (x + i, y + j):
                                if cell2.is_live == 1:
                                    cell.neighbour = cell.neighbour + 1


界面:main.py
[Python] 纯文本查看 复制代码
import pygame
import time
import random
from rule import *

global x, y, pos


class World:
    def __init__(self, width, height, wow, x1, y1):
        self.width = width
        self.height = height
        self.wow = wow
        self.x = x1
        self.y = y1

    def divide(self):
        global pos
        for i in range(0, self.width//self.wow):
            if i < x/self.wow < i + 1:
                self.x = i
        for j in range(0, self.height//self.wow):
            if j < y/self.wow < y + 1:
                self.y = j
        pos = self.x, self.y
        return pos


def draw(path, position):
    screen.blit(path, position)


def update():
    pygame.display.update()


def color(num):
    if num == 0:
        return black
    elif num == 1:
        return white


if __name__ == "__main__":
    pygame.init()
    World_width = 800
    World_height = 500
    Cell_size = 20
    rule = Rule(World_width, World_height, Cell_size, 0)
    world = World(World_width, World_height, Cell_size, 0, 0)
    # 创建铺满的细胞
    rule.run()
    size = rule.width, rule.height + 60
    screen = pygame.display.set_mode(size)
    pygame.display.set_caption("Game of Life")
    time_running = 0

    Black = pygame.color.Color("black")
    white = pygame.image.load("picture/white.png")
    white = pygame.transform.smoothscale(white, (rule.wow, rule.wow))
    black = pygame.image.load("picture/black.png")
    black = pygame.transform.smoothscale(black, (rule.wow, rule.wow))
    red = pygame.image.load("picture/red.png")
    red = pygame.transform.smoothscale(red, (rule.wow, rule.wow))
    green = pygame.image.load("picture/green.png")
    green = pygame.transform.smoothscale(green, (rule.wow, rule.wow))
    blue = pygame.image.load("picture/blue.png")
    blue = pygame.transform.smoothscale(blue, (World_width, 60))
    draw(blue, (0, World_height))
    txt_state_0 = pygame.font.Font("font/Arial.ttf", 20).render("Creating Mode(print R to run)", True, Black)
    txt_state_0_1 = pygame.font.Font("font/Arial.ttf", 20).render("Print Q to create randomly", True, Black)
    txt_state_1 = pygame.font.Font("font/Arial.ttf", 20).render("Running···(print SPACE to modify)", True, Black)

    while True:
        x, y = pygame.mouse.get_pos()
        for cell in cell_list:
            if cell.charge == 0:
                dest = (cell.position[0] * rule.wow, cell.position[1] * rule.wow)
                draw(color(cell.is_live), dest)
            cell.charge = 0
        if rule.state == 0:
            draw(blue, (0, World_height))
            draw(txt_state_0, ((World_width - txt_state_0.get_width())/2, World_height))
            draw(txt_state_0_1, ((World_width - txt_state_0_1.get_width())/2, World_height + 30))
        elif rule.state == 1:
            draw(blue, (0, World_height))
            draw(txt_state_1, ((World_width - txt_state_0.get_width())/2, World_height))
            txt_time = pygame.font.Font("font/Arial.ttf", 20).render("Time: " + str(time_running), True, Black)
            draw(txt_time, ((World_width - txt_time.get_width())/2, World_height + 30))
        update()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()
            if event.type == pygame.MOUSEBUTTONDOWN and rule.state == 0:
                # 获取坐标pos = (x, y)
                world.divide()
                for cell in cell_list:
                    if cell.position == pos:
                        cell.convert()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_r:
                    rule.state = 1
                if event.key == pygame.K_SPACE:
                    rule.state = 0
                if event.key == pygame.K_q:
                    for cell in cell_list:
                        cell.is_live = random.randint(0, 1)

        if rule.state == 1:
            rule.get_neighbour()
            for cell in cell_list:
                cell.change()
            time_running = time_running + 1
            # time.sleep(1)
        if rule.state == 0:
            world.divide()
            for cell in cell_list:
                if cell.position == pos:
                    cell.charge = 1
                    dest = (cell.position[0] * rule.wow, cell.position[1] * rule.wow)
                    if cell.is_live == 0:
                        draw(green, dest)
                        update()
                    elif cell.is_live == 1:
                        draw(red, dest)
                        update()


运行:

创造模式

创造模式

运行

运行


运行下来还是比较顺利的,但是能明显感觉到一些问题:
1、遍历算法实在效率太低,能感觉到计算量有点大(如果能从编号直接访问类产生的对象,应该能好很多)
2、面向对象的方法确实很强,(比如只加了三行代码就添加了随机图案功能)
但是初步运用,思路还比较混乱,没法摆脱刻在DNA里的面向过程的思考方式(笑)
对于pygame这种东西,还不是很清楚怎么用面向对象的思想来编程,代码中的不足希望大佬帮忙指出,感激不尽!

完整代码及其他附件:
创造模式:q随机图案,r开始运行
运行模式下:空格暂停、修改
Life-Game.zip (425.08 KB, 下载次数: 50)

免费评分

参与人数 2吾爱币 +9 热心值 +2 收起 理由
苏紫方璇 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
zqguang3708 + 2 + 1 元胞自动机

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

列明 发表于 2021-4-20 20:25
面向對象編程?
你在做夢?
你得先有個對象!
璐璐诺 发表于 2021-4-20 19:52
狐白本白 发表于 2021-4-20 20:15
虽然你说很粗糙,但是,对于我这种小白,真是牛批,多谢分享
zqguang3708 发表于 2021-4-20 20:34
元胞自动机
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 18:58

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表