如何创建具有从 csv 文件中的列表收集的唯一名称值的类的多个对象

Posted

技术标签:

【中文标题】如何创建具有从 csv 文件中的列表收集的唯一名称值的类的多个对象【英文标题】:How to create multiple objects of a class with unique name values gathered from a list in a csv file 【发布时间】:2021-06-04 08:42:55 【问题描述】:

我是编程新手,我正在努力弄清楚如何让它发挥作用。我正在尝试构建一个名为“宠物流行病”的简单游戏,您基本上只需按开始键,用不同颜色的点标记的“宠物”就会在窗口的网格上四处游荡。一些宠物与“病毒”一起产卵。在漫游时,宠物会查看它们是否彼此相距一定距离,如果是,它们会将病毒传播给尚未感染病毒的另一只,进而更新该宠物的状态以具有“病毒”和点图像将更新为红色。游戏将一直运行,直到每个“宠物”都感染了“病毒”。我正在努力实现一种方法来生成具有独特名称的“宠物”,例如“Alex”或“Doug”。我想为此使用 .csv 文件中的名称列表。

感谢您的宝贵时间。 以下是文件: https://drive.google.com/drive/folders/1tjEY6Eo1nKKtEr0st1CUFkcnBvvbiMn1?usp=sharing

import pygame
import random
import math
import time

# Window settings
WIDTH = 960
HEIGHT = 660
TITLE = "PET PANDEMIC"
FPS = 60

#create window
pygame.init()
screen = pygame.display.set_mode([WIDTH, HEIGHT])
pygame.display.set_caption(TITLE)
clock = pygame.time.Clock()

#Game Stages
START = 0
PLAYING = 1
END = 2

#Define colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
BLUE = (132, 201, 217)

# Load fonts
title_font = default_font = pygame.font.Font("fonts/recharge bd.ttf", 60)
default_font = pygame.font.Font(None, 55)

# Load images
has_v_img = pygame.image.load("red_dot.png").convert_alpha()
no_v_img = pygame.image.load("grey_dot.png").convert_alpha()
no_v_mask_img = pygame.image.load("black_dot.png").convert_alpha()

#Game classes
class Pet(pygame.sprite.Sprite):
    
   def __init__(self, name, x, y):
      super().__init__()
      
      self.wearing_mask = random.randint(0, 1) # 0 = no, 1 = yes.
      self.has_virus = random.randint(0, 6) # 6 = Virus
      if self.has_virus == 6:
          self.image = has_v_img
      elif self.wearing_mask != 1 and self.has_virus != 6:
          self.image = no_v_mask_img
      else:
          self.image = no_v_img
      self.rect = self.image.get_rect()
      self.rect.center = x, y
      self.name = name
      self.dir = random.randint(0, 3)
      self.is_alive = True
      self.print_name()
      
   def print_name(self):
       amnt_w_virus = 0
       if self.has_virus == 6:
         print("Spawned  ".format(self.name) + "With The Virus!")
         amnt_w_virus += 1
       else:
           print("Spawned .".format(self.name))
       return amnt_w_virus


   def check_distance(self, other):
      distance = math.sqrt(((self.x - other.x) ** 2) + ((self.y - other.y) ** 2))
      if distance < 6 and self.has_virus == 6:
               other.has_virus = 6
               print(self.name + " Was In Range Of " + other.name + " And Gave Them The Virus.")
               amnt_w_virus += 1
      else:
        return amnt_w_virus

   def roam(self):
          while game_running:
             if self.is_alive == True:
                time.sleep(1.5)
                self.dir = random.randint(0, 3)
                self.move()

   def move(self):
       if self.dir == 0:
           self.rect.y += 1
           
       elif self.dir == 1:
           self.rect.x += 1
           
       elif self.dir == 2:
           self.rect.y -= 1
               
       elif self.dir == 3:
           self.rect.x -= 1
               
       if self.rect.left < 0:
           self.rect.left = 0
                
       elif self.rect.top > HEIGHT:
           self.rect.top = HEIGHT
               
       elif self.rect.right > WIDTH:
           self.rect.right = WIDTH
               
       print(self.name + " Moved Forward In Direction " + str(self.dir) + " (" + str(self.x) + "," + str(self.y) + ").")

       
class Players(pygame.sprite.Group):
    
    def __init__(self, *sprites):
        super().__init__(*sprites)
        


    def update(self, *args):
        super().update(*args)
        
        self.check_distance()
        self.roam()


# Setup
def new_game():
    global players
    #Random Spawn Location Inside Window
    start_x = random.randint(0,WIDTH)
    start_y = random.randint(0,HEIGHT)

    #Open List Of Names To Use For The Pets
    f = open("names.csv", "r")
    reader = csv.reader(f)
    name = []

    for row in reader:
        name.append(row)
        pet = 
        #Here Im trying to spawn the pets and assign them unique names from the list but this code is all messed up
        for item in name:
            name = ''.format(item)
            pet[name] = pet.get(name, Pet(name=name))
            pets = Pet([name], start_x, start_y)
            #making players = a sprite group of all the pets
            players = Players(pets)
    #trying to calculate the number of pets without the virus
    players.amount_alive = len(players) - amnt_w_virus
    print(players.amnt_alive) 

#grid overlay
def draw_grid(width, height, scale):
    for x in range(0, WIDTH, scale):
        pygame.draw.line(screen, WHITE, [x, 0], [x, HEIGHT], 1)
    for y in range(0, HEIGHT, scale):
        pygame.draw.line(screen, WHITE, [0, y], [WIDTH, y], 1)
          
def display_stats():
    infected_text = default_font.render("Infected: " + str(amnt_w_virus), True, WHITE)
    rect = infected_text.get_rect()
    rect.top = 20
    rect.left = 20
    screen.blit(infected_text, rect)

    non_infected_text = default_font.render("Non-Infected: " + str(players.amount_alive), True, WHITE)
    rect = non_infected_text.get_rect()
    rect.top = 20
    rect.right = WIDTH - 20
    screen.blit(non_infected_text, rect)

    time_text = default_font.render("Time: " + str(time.time), True, WHITE)
    rect = time_text.get_rect()
    rect.bottom = HEIGHT - 20
    rect.left = 20
    screen.blit(time_text, rect)

def start_screen():
    screen.fill(BLACK)
    
    title_text = title_font.render(TITLE, True, WHITE)
    rect = title_text.get_rect()
    rect.centerx = WIDTH // 2
    rect.bottom = HEIGHT // 2 - 15
    screen.blit(title_text, rect)

    sub_text = default_font.render("Press Any Key To Start The Spread", True, WHITE)
    rect = sub_text.get_rect()
    rect.centerx = WIDTH // 2
    rect.top = HEIGHT // 2 + 15 
    screen.blit(sub_text, rect)
          
def end_screen():
    end_text = default_font.render("GAME OVER, EVERYONE IS INFECTED.", True, WHITE)
    rect = end_text.get_rect() 
    rect.centerx = WIDTH // 2
    rect.centery = HEIGHT // 2
    screen.blit(end_text, rect)

# Game loop
new_game()
stage = START

running = True

while running:
    # Input handling
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        elif event.type == pygame.KEYDOWN:
            if stage == START:
                stage = PLAYING
            elif stage == END:
                if event.key == pygame.K_r:
                    new_game()
                    stage = START
    
    # Game logic
    if stage != START:
        players.update()


    if len(players) == 0:
         stage = END

    # Drawing Code
    screen.fill(BLUE)
    draw_grid(960, 660, 20)
    players.draw(screen)
    display_stats()
    pygame.display.flip()
   
    if stage == START:
        start_screen()
    elif stage == END:
        end_screen()
    
        
    # Update screen
    pygame.display.update()


    # Limit refresh rate of game loop 
    clock.tick(FPS)


# Close window and quit
pygame.quit() ```

【问题讨论】:

【参考方案1】:

您正在覆盖名为 name 的对象:

    for item in name:
        name = ''.format(item) ### BAD BAD BAD BAD BAD
        pet[name] = pet.get(name, Pet(name=name))
        pets = Pet([name], start_x, start_y)
        #making players = a sprite group of all the pets
        players = Players(pets)

如果您真的想这样做,那么您需要通过将其转换为列表来保留 name 中的项目。

    for item in list(name):
        name = ''.format(item)
        pet[name] = pet.get(name, Pet(name=name))
        pets = Pet([name], start_x, start_y)
        #making players = a sprite group of all the pets
        players = Players(pets)

我确定您实际上并不想这样做,所以只需使用不同的变量名(例如 _name)。

    for item in name:
        _name = ''.format(item)
        pet[_name] = pet.get(_name, Pet(name=_name))
        pets = Pet([_name], start_x, start_y)
        #making players = a sprite group of all the pets
        players = Players(pets)

【讨论】:

当我运行你的代码时,它给了我这个错误。 line 219, in new_game pet[_name] = pet.get(_name, Pet(name=_name)) TypeError: __init__() missing 2 required positional arguments: 'x' and 'y'

以上是关于如何创建具有从 csv 文件中的列表收集的唯一名称值的类的多个对象的主要内容,如果未能解决你的问题,请参考以下文章

如何从多个 .csv 文件中的命名列中选择唯一值?

Ms-Access 尝试使用“传输文本”创建具有唯一文件名的 csv 文件

如何在 Python 中使用 CSV 文件的唯一值创建列表?

使用列表理解 Python 创建新列

如何列出 CSV 文件中的各个列?

如何比较具有不同名称引用但具有相同实际数据的两个列表