#python #pygame #grid
#python #pygame #сетка
Вопрос:
Я сделал небольшую игру (головоломный помощник StackExchange), используя Pygame.
Вот демонстрация того, как это работает:
Если вы не можете сказать, программа позволяет пользователю выбрать 2 соседние ячейки, а затем число в двух ячейках будет равномерно распределено между двумя ячейками. Если сумма двух чисел нечетна, ячейка с наибольшим числом на первом месте будет на одно число больше, чем другая.
Когда пользователь впервые выбирает ячейку, будут выделены только соседние ячейки, которые отличаются от этой ячейки как минимум на 2.
Я хочу знать, как придать всем ячейкам, в которых нет соседних ячеек с числами, отличающимися как минимум на 2 от этой ячейки, оттенок серого.
Другими словами, как затенить ячейки, чтобы при нажатии на них не было соседней ячейки, которую вы можете щелкнуть, чтобы изменить ее номер.
Мой код (прокрутите весь путь вниз, чтобы увидеть комментарии, как я пытался заставить его работать, но потерпел неудачу):
import pygame
# You can change the grid amp; 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, 255)
def draw(self):
pygame.draw.rect(wn, self.color, self.rect)
text = font.render(str(self.num), True, (0, 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, 255)
box.square = square
box.color((255, 255, 140))
else:
if square in box.box():
box.clicked.append(square)
if square == box.clicked[0]:
box.color((255, 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, 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()
Комментарии:
1. для каждой соседней ячейки, которая не соответствует критериям, не загорается, другими словами, проверьте каждую соседнюю ячейку и, если она соответствует условию, загорается
2. @Matiiss На самом деле, для каждой соседней ячейки, которая соответствует критериям, не загорается, другими словами, проверьте каждую соседнюю ячейку и, если она соответствует условию, загорается.
3. @Matiiss Критерием является то, что если мы нажмем на квадрат, ни один соседний квадрат не станет желтым.
4. Другими словами, как затенить ячейки, чтобы при нажатии на них не было соседней ячейки, которую вы можете щелкнуть, чтобы изменить ее номер. поэтому каждый раз, когда игрок нажимает и в начале проверяет все ячейки и определяет, какие из них должны быть в тени
Ответ №1:
Перебирайте все ячейки сетки, используя вложенные циклы и индексы (i, j):
for i in range(len(squares)):
for j in range(len(squares[i])):
# [...]
Найдите все соседние индексные кортежи (l, k) ячейки (i, j):
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-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))
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)
elif squares[i][j].color == (140, 140, 140):
square.clear()
for row in squares:
for square in row:
square.draw()
# [...]