我做了模拟,物体消失了

2024-04-19 19:09:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我做了这个源代码,模拟一大群行人的行为 我在源代码上留下了描述,但我找不到问题所在给。它是一种心理决策模型
请阅读源代码上的描述,并请检查我的源代码中有什么错误。物体不应该消失,但它们确实消失了 拜托,帮帮我。你知道吗

import pygame
import random
import math
import time
import numpy


class MapGrid():
    def __init__(self, map_width, map_height): # create a coordinate with dimension map_width * map_height

        self.map_width = map_width
        self.map_height = map_width

        self.outside_terrain_grid = self._generate_empty_noise_grid(self.map_width, self.map_height)

    def _generate_empty_noise_grid(self, map_width, map_height): 
        ''' 
            creates objects with value of 0,1,2 when y < 20 
            0 means nothing, 1 is a object that moves with velocity 1, 2 is a object that moves with velocity 2
            and random sequence of 1 or 2 will be added to objects(value of 1,2) which is desire
            they are going to move to right
        '''
        number_count = 0 
        sum_velocity = 0
        new_map_grid = []
        for x in range(map_width):

            new_map_grid.append([])
            for y in range(map_height):
                if y < 20: 
                    new_map_grid[x].append(random.choice([0,1,2]))
                else:
                    new_map_grid[x].append(0)

                if new_map_grid[x][y] != 0:
                    number_count += 1
                    sum_velocity += new_map_grid[x][y]
                    new_map_grid[x][y] += self._individual_desire(sum_velocity, number_count)

        return new_map_grid


    def _individual_desire(self, sum_velocity, number_count): 
        '''
        Gaussian destribution of random number(1 or 2)
        '''
        mu = 1.5
        sigma = 0.125
        average_velocity = sum_velocity / number_count
        critical_number = numpy.random.normal(mu, sigma)

        value = average_velocity - critical_number

        if value < 0:
            return 1
        else: 
            return 2


    def _generate_outside_terrain(self, empty_outside_terrain_grid, number_of_generations):
        '''
        This method creates a new list that will represent next phase
        For example, For example, in the grid[10][20] and in the 1st phase, 
        there was object with value 1 in the coordinate grid[0][0] 
        and it has velocity of 2, It moves to grid[0][2]
        and there is also change in velocity and desire in surrounding interactions 
        assume that there is object i and j and j is right in front of i
        Here, top_mid is j, and mid is i 
        if d_i(desire of i) <= v_j, then v_i = d_i
        elif d_i > v_j, then i moves to right or left with probability of 0.5 
        continue in the same direction
        '''
        grid = empty_outside_terrain_grid
        number_of_generations = number_of_generations

        for x in range(number_of_generations):
            next_grid = []
            for column_index, column in enumerate(grid): 
                next_column = []
                next_grid.append(next_column)

                for tile_index, tile in enumerate(column):

                    next_column.append(0) # append doesn't seem to work so I created dimension with full of 0 and change the value 0~4

                for tile_index, tile in enumerate(column):
                    #I made exception considering when index is bigger than map_width
                    try:
                        top_mid = grid[column_index][tile_index - 1]
                    except IndexError:
                        tile_index - 1 < 0
                    mid = grid[column_index][tile_index]

                    try:
                        d_top_mid = grid[column_index][tile_index + 1] % 2 
                    except IndexError:
                        tile_index + 1 > map_width

                    d_mid = grid[column_index][tile_index] % 2 

                    try:
                        v_top_mid = math.floor((grid[column_index][tile_index+1] + 1) / 2)
                    except IndexError:
                        tile_index + 1 > map_width

                    v_mid = math.floor((grid[column_index][tile_index] + 1) / 2)

                    the_value = grid[column_index][tile_index]


                    #Below is making surrounding interaction

                    if d_mid <= v_top_mid:
                        grid[column_index][tile_index] == d_mid * 2
                        try: 
                            next_grid[column_index][tile_index+v_mid] = the_value
                        except IndexError:
                            tile_index+v_mid > map_width

                    else:
                        next_grid[column_index-1].append(the_value)

        grid = next_grid
        return next_grid

if __name__ == '__main__':
    # general map stats
    map_width = 140
    map_height = 30

    # start with one generation
    tile_size = 8

    map_grid = MapGrid(map_width, map_height)
    #print map_grid.outside_terrain_grid

    pygame.init()

    screen = pygame.display.set_mode((map_width * tile_size,map_height * tile_size))
    zero_tile = pygame.Surface((1, 1)) 
    zero_tile.fill((0,0,0))
    one_tile = pygame.Surface((1, 1))
    one_tile.fill((255,255,255))
    two_tile = pygame.Surface((1,1))
    two_tile.fill((255,0,0))
    three_tile = pygame.Surface((1,1))
    three_tile.fill((0,0,204))
    four_tile = pygame.Surface((1,1))
    four_tile.fill((0,255,0))

    colors = {0: zero_tile, 1: one_tile, 2:two_tile, 3:three_tile, 4:four_tile}

    background = pygame.Surface((map_width * tile_size,map_height * tile_size))

    clock = pygame.time.Clock()

    first_gen = True
    timer = 12

    running = True
    while running == True:
        clock.tick(3)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

        if first_gen:
            themap = map_grid.outside_terrain_grid
        else:
            themap = map_grid._generate_outside_terrain(themap, 1)

        for column_index, column in enumerate(themap):
            for tile_index, tile in enumerate(column):
                screen.blit(colors[tile], (tile_index * tile_size, column_index * tile_size))

        pygame.display.flip()

        if first_gen:
            timer -= 1
            if timer < 0:
                first_gen = False

    pygame.quit()

Tags: ofinselfnumbermapindexiscolumn