自动机渲染/状态问题

问题描述 投票:0回答:1

我正在研究一种自动机,其中有一个带有“state = 2”方块的红色方块,它按上、左、下、右的顺序检查相邻方块,如果其中一个方块具有“state = 0”,它将改变其状态到“state = 2”,它们的状态将更改为 1。问题是,当红色方块向左和向上“移动”时,它不会显示。另外,当我更改代码以在 squares 类的更新函数请求时进行渲染时,看起来有 2 个方块具有“state = 2”。

grid_size = 50
updated = False

class squares:
    def __init__(self,position,state = 0):
        self.position = position
        self.state = state
        self.operation_done = False
    def change_state(self):
        self.state = 2
    def update(self):
        global updated
        
        if not updated:
            if self.state == 2:
                self.operation_done =False
                if self.position[1] - grid_size >= 0 and not self.operation_done:
                    up = (self.position[0], self.position[1] - grid_size)
                    neighbor_up = squares_dict[up]
                    if neighbor_up.state == 0:
                        neighbor_up.change_state()
                        self.operation_done = True
                        self.state = 1
                        updated = True
                if self.position[0] - grid_size >= 0 and not self.operation_done: 
                    left = (self.position[0] - grid_size, self.position[1])
                    neighbor_left = squares_dict[left]
                    if neighbor_left.state == 0:
                        neighbor_left.change_state()
                        self.operation_done = True
                        self.state = 1
                        updated = True
                if self.position[1] + grid_size <= 450 and not self.operation_done: 
                    down = (self.position[0], self.position[1] + grid_size)
                    neighbor_down = squares_dict[down]
                    if neighbor_down.state == 0:
                        neighbor_down.change_state()
                        self.operation_done = True
                        self.state = 1
                        updated = True
                if self.position[0] + grid_size <= 450 and not self.operation_done: 
                    right = (self.position[0] + grid_size, self.position[1])
                    neighbor_right = squares_dict[right]
                    if neighbor_right.state == 0:
                        neighbor_right.change_state()
                        self.operation_done = True
                        self.state = 1
                        updated = True
                        
        if self.state == 2:
            pygame.draw.rect(screen_display,(255,0,0), (*self.position,grid_size,grid_size))
        elif self.state == 1:
            pygame.draw.rect(screen_display,(255,255,255), (*self.position,grid_size,grid_size))
        elif self.state == 0:
            pygame.draw.rect(screen_display,(0,0,0), (*self.position,grid_size,grid_size))

我不知道出了什么问题,因为当它向右和向下“移动”时它就可以正常工作。

pygame simulator
1个回答
0
投票

我认为问题在于你的代码正在推进正方形的

state
,而它仍在处理世界。 假设您更新了东邻,但下一个要处理的单元格是 x + 1
,并且状态值刚刚被重置!

您需要将“当前状态”和“下一个计算状态”分开。

我在下面实现的是保持两种状态,

self.state

self.next_state
。  当更新算法通过网格进行时,对 
self.state
 进行测试,但 
changes 存储在 self.next_state
 中。  一旦处理了整个网格世界,
然后方块就可以切换到下一个状态。

我不得不猜测你的程序应该做什么,也许我把这些部分弄错了。 提前致歉。

screen shot

import pygame import random # Window size WINDOW_WIDTH = 500 WINDOW_HEIGHT = 500 UPDATE_MILLIS = 1200 # time between updates GRID_CELLS = 10 # N x N sized world-grid GRID_SIZE = 50 # How biug cells are drawn in the window class Square: def __init__(self,position,state = 0): self.position = position # ( column, row ) position in the world grid self.state = state # Current state used for calculations self.next_state = state # The next state we become # References to our neighbours, with grid wrap-around self.north = None self.east = None self.south = None self.west = None def map_neighbours( self, world_grid, grid_width, grid_height ): """ Link references to other cells in the grid """ x, y = self.position # NORTH if ( y == 0 ): self.north = world_grid[grid_height-1][x] # wrap-around top->bottom else: self.north = world_grid[y-1][x] # EAST if ( x == grid_width-1 ): self.east = world_grid[y][0] else: self.east = world_grid[y][x+1] # SOUTH if ( y == grid_height-1 ): self.south = world_grid[0][x] else: self.south = world_grid[y+1][x] # WEST if ( x == 0 ): self.west = world_grid[y][grid_width-1] else: self.west = world_grid[y][x-1] def update(self): # Deternime the next state. # If I am state==2, and my neighbour is state==0 -> switch to state:=1 neighbours = [ self.north, self.east, self.south, self.west ] for neighbour in neighbours: if ( self.state == 2 and neighbour.state == 0 ): self.next_state = 1 neighbour.next_state = 2 # TODO: re-write in terms of "my" state, don't change neighbour, it should change itself def advance_state( self ): """ Move to the target state """ self.state = self.next_state def __str__( self ): s = "Square at (%3d,%3d) state=%d" % ( self.position[0], self.position[1], self.state ) return s def draw( self, surface ): if self.state == 2: colour = (255,0,0) elif self.state == 1: colour = (255,255,255) elif self.state == 0: colour = (0,0,0) else: colour = (0,255,255) # error, should not happen x,y = self.position pygame.draw.rect( surface, colour, (x*GRID_SIZE, y*GRID_SIZE, GRID_SIZE, GRID_SIZE ) ) ### ### MAIN ### pygame.init() window = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), pygame.HWSURFACE ) pygame.display.set_caption("Squares") # Define some Squares in a World world_grid = [] for y in range( GRID_CELLS ): world_grid.append( [] ) # empty row for x in range( GRID_CELLS ): position = ( x, y ) state = random.randint( 0, 2 ) world_grid[y].append( Square( position, state ) ) #print( "Added Square: " + str( world_grid[y][-1] ) ) # we can't find our neighbours until all cells are filled for y in range( GRID_CELLS ): for x in range( GRID_CELLS ): world_grid[y][x].map_neighbours( world_grid, GRID_CELLS, GRID_CELLS ) # Main loop clock = pygame.time.Clock() next_update = pygame.time.get_ticks() + UPDATE_MILLIS # time in future to update states running = True while running: time_now = pygame.time.get_ticks() # Handle user-input for event in pygame.event.get(): if ( event.type == pygame.QUIT ): running = False # Update the state-transition algorithm every period if ( time_now > next_update ): next_update = time_now + UPDATE_MILLIS # reschedule next update # Do the update for y_row in world_grid: for sq in y_row: sq.update() # calculate all the next states for y_row in world_grid: for sq in y_row: sq.advance_state() # now calc is done, switch to new state (if any) # Draw and update the world_grid for y_row in world_grid: for sq in y_row: sq.draw( window ) pygame.display.flip() # Clamp FPS clock.tick(60) pygame.quit()
    
© www.soinside.com 2019 - 2024. All rights reserved.