问题描述
我使用Pygame制作了一个小游戏(令人费解的StackExchange助手)。
以下是其工作方式的演示:
如果您不知道,该程序将允许用户选择2个相邻的单元格,然后选择 两个单元均匀地分布在两个单元中。如果两个数字之和为奇数, 首先,编号最大的单元将比另一个大。
当用户第一次选择一个单元格时,将仅突出显示与该单元格至少相差2的相邻单元格。
我想知道如何为所有没有的单元格提供与该单元格至少有2个差的相邻单元格灰色阴影。
换句话说,如何在单击它们的单元格上加阴影,将没有相邻的单元格可供单击以更改其编号。
我的代码(向下滚动以查看注释,这是我尝试使其起作用但失败的方式):
import pygame
# You can change the grid & size to whatever you like
grid = [[7,24,12,8,11],[13,21,3,20,19],[10,22,15,2,9],[23,1,6,16,17],[5,25,14,4,18]]
size = 60
pygame.init()
pygame.font.init()
font = pygame.font.SysFont("Arial",size-10)
wn = pygame.display.set_mode((600,600))
class Square():
def __init__(self,pos,num):
self.x = pos[0] * size
self.y = pos[1] * size
self.num = num
self.color = (255,255,255)
self.rect = pygame.Rect(self.x,self.y,size-5,size-5)
def clear(self):
self.color = (255,255)
def draw(self):
pygame.draw.rect(wn,self.color,self.rect)
text = font.render(str(self.num),True,(0,0))
if len(str(self.num)) == 1:
wn.blit(text,(self.x+size*.25,self.y*.98))
else:
wn.blit(text,(self.x+size*.055,self.y*.98))
class Box():
def __init__(self,grid,square=None):
self.square = square
self.grid = grid
self.clicked = []
def Box(self): # Returns a list of all adjancent squares that can change the number of the selected square
x,y = self.square.x//size,self.square.y//size
y1 = x-1 if x else 0
y2 = len(self.grid)+2 if x > len(self.grid)+2 else x+2
x1 = y-1 if y else 0
x2 = len(self.grid[0])+2 if y > len(self.grid[0])+2 else y+2
b = []
for r in self.grid[y1:y2]:
for c in r[x1:x2]:
if abs(c.num - self.grid[x][y].num) > 1:
b.append(c)
elif c != self.square:
c.clear()
return b
def color(self,color):
for square in self.Box():
square.color = color
def clear(self):
for c in self.clicked:
c.clear()
self.clicked.clear()
def avg(n1,n2):
n = n1 + n2
if n % 2:
if n1 > n2:
return n // 2 + 1,n // 2
return n // 2,n // 2 + 1
return n // 2,n // 2
squares = [[Square((i,j),col) for j,col in enumerate(row)] for i,row in enumerate(grid)]
Box = Box(squares)
Box2 = Box(squares)
total = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.MOUSEBUTTONDOWN:
for row in squares:
for square in row:
if square.rect.collidepoint(pygame.mouse.get_pos()):
if not Box.clicked:
Box.clicked.append(square)
square.color = (140,255)
Box.square = square
Box.color((255,140))
else:
if square in Box.Box():
Box.clicked.append(square)
if square == Box.clicked[0]:
Box.color((255,255))
Box.clear()
if len(Box.clicked) == 2:
total += 1
print(total)
Box.clicked[0].num,Box.clicked[1].num = avg(Box.clicked[0].num,Box.clicked[1].num)
Box.color((255,255))
Box.clear()
for row in squares:
for square in row:
# temp = Box(squares,square)
# if not temp.Box():
# square.color = (140,140,140)
# del(temp)
square.draw()
pygame.display.update()
解决方法
使用嵌套循环和索引( i , j )遍历网格的所有单元格:
for i in range(len(squares)):
for j in range(len(squares[i])):
# [...]
查找单元格( i , j )的所有相邻索引元组( l , k ) :
adjacent = []
for k in range(max(0,i-1),min(len(squares),i+2)):
for l in range(max(0,j-1),min(len(squares[k]),j+2)):
if i != k or j != l:
adjacent.append((k,l))
如果一个单元格( i , j )没有邻居(not any()
)( l , k ),其中差异至少为2:
if not any((k,l) for (k,l) in adjacent if abs(squares[i][j].num - squares[k][l].num) > 1):
squares[i][j].color = (140,140,140)
完成嵌套循环
while True:
# [...]
for i in range(len(squares)):
for j in range(len(squares[i])):
adjacent = []
for k in range(max(0,i+2)):
for l in range(max(0,j+2)):
if i != k or j != l:
adjacent.append((k,l))
if not any((k,l) in adjacent if abs(squares[i][j].num - squares[k][l].num) > 1):
squares[i][j].color = (140,140)
elif squares[i][j].color == (140,140):
square.clear()
for row in squares:
for square in row:
square.draw()
# [...]