我正在研究一种自动机,其中有一个带有“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))
我不知道出了什么问题,因为当它向右和向下“移动”时它就可以正常工作。
我认为问题在于你的代码正在推进正方形的
state
,而它仍在处理世界。 假设您更新了东邻,但下一个要处理的单元格是 x + 1
,并且状态值刚刚被重置!您需要将“当前状态”和“下一个计算状态”分开。
我在下面实现的是保持两种状态,
self.state
和
self.next_state
。 当更新算法通过网格进行时,对
self.state
进行测试,但changes 存储在
self.next_state
中。 一旦处理了整个网格世界,然后方块就可以切换到下一个状态。 我不得不猜测你的程序应该做什么,也许我把这些部分弄错了。 提前致歉。
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()