Как сравнить элементы в pygame.Surface?
Я хотел создать игру пазл, где нужно собрать все кусочки экрана правильно и после того как картинка собрана правильно, игра завершится.
Но есть одна проблема: игра не завершается, потому что при сравнении координат кусков, они разные.
import pygame
import pyautogui
import random
screenshot = pyautogui.screenshot()
screenshot.save("screenshot.png")
pygame.init()
screen_width, screen_height = pyautogui.size()
screen = pygame.display.set_mode((screen_width, screen_height), pygame.FULLSCREEN)
rows = 2
cols = 2
piece_width = screen_width // cols
piece_height = screen_height // rows
key = 0
pieces = []
for y in range(rows):
for x in range(cols):
piece = pygame.Surface((piece_width, piece_height))
piece.blit(pygame.image.load("screenshot.png"), (0, 0),
(x * piece_width, y * piece_height, piece_width, piece_height))
pieces.append(piece)
print(pieces)
for piece in pieces:
pygame.draw.rect(piece, (0, 0, 0), pygame.Rect(0, 0, piece_width, piece_height), 2)
random.shuffle(pieces)
selected_piece = None
move_x, move_y = 0, 0
def get_initial_coordinates(cols, rows, piece_width, piece_height):
initial_coords = {}
for i in range(rows):
for j in range(cols):
initial_coords[i * cols + j] = (j * piece_width, i * piece_height)
return initial_coords
initial_coords = get_initial_coordinates(cols, rows, piece_width, piece_height)
def check_completed_puzzle(pieces, initial_coords):
for i, piece in enumerate(pieces):
x = i % cols
y = i // cols
if piece.get_rect().topleft != initial_coords[i]:
return False
return True
running = True
selected_piece = None
initial_coords = get_initial_coordinates(cols, rows, piece_width, piece_height)
while running:
move_x, move_y = 0, 0
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
elif event.key == pygame.K_UP:
move_x, move_y = 0, -1
elif event.key == pygame.K_DOWN:
move_x, move_y = 0, 1
elif event.key == pygame.K_LEFT:
move_x, move_y = -1, 0
elif event.key == pygame.K_RIGHT:
move_x, move_y = 1, 0
if event.type == pygame.MOUSEBUTTONDOWN:
x, y = pygame.mouse.get_pos()
col = x // piece_width
row = y // piece_height
selected_piece = row * cols + col
if selected_piece is not None:
x = selected_piece % cols
y = selected_piece // cols
new_x = x + move_x
new_y = y + move_y
new_index = new_y * cols + new_x
if 0 <= new_x < cols and 0 <= new_y < rows and abs(move_x) + abs(move_y) == 1:
pieces[selected_piece], pieces[new_index] = pieces[new_index], pieces[selected_piece]
selected_piece = new_index
if check_completed_puzzle(pieces, initial_coords):
print("Вы собрали пазл!")
running = False
screen.fill((0, 0, 0))
for i, piece in enumerate(pieces):
x = i % cols
y = i // cols
screen.blit(piece, (x * piece_width, y * piece_height))
if selected_piece is not None:
x = selected_piece % cols
y = selected_piece // cols
pygame.draw.rect(screen, (0, 0, 255), pygame.Rect(x * piece_width, y * piece_height, piece_width, piece_height), 2)
pygame.display.flip()
pygame.quit()
При попытке сравнить списки, содержащие тип данных pygame.Surface до и после перемешивания, они оказывались одинаковыми(True):
P1 = pieces
random.shuffle(pieces)
P2 = pieces
print(P1 == P2)
Даже пытался узнать и сравнить координаты пазлов вручную:
for i, piece in enumerate(pieces):
x = i % cols
y = i // cols
print(f"Кубик {i} находится в координатах x:{x*piece_width}, y:{y*piece_height}")
random.shuffle(pieces)
for i, piece in enumerate(pieces):
x = i % cols
y = i // cols
print(f"Кубик {i} находится в координатах x:{x*piece_width}, y:{y*piece_height}")
Координаты были одинаковыми, как будто ничего и не произошло.
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Sorry, я не вникал в вашу логику. Я просто решил добавить что-то (y, x)
для сравнения в список pieces
. Попробуйте.
import pygame
import pyautogui
import random
import copy # +++
screenshot = pyautogui.screenshot()
screenshot.save("screenshot.png")
pygame.init()
screen_width, screen_height = pyautogui.size()
screen = pygame.display.set_mode(
(screen_width, screen_height), pygame.FULLSCREEN)
rows = 2
cols = 2
piece_width = screen_width // cols
piece_height = screen_height // rows
key = 0
pieces = []
for y in range(rows):
for x in range(cols):
piece = pygame.Surface((piece_width, piece_height))
piece.blit(
pygame.image.load("screenshot.png"),
(0, 0),
(x * piece_width, y * piece_height, piece_width, piece_height)
)
# +++
pieces.append([piece, (y, x)]) # +++ , (y, x)
# +++ v vvv
for piece, y_x in pieces:
pygame.draw.rect(
piece,
(222, 0, 0),
pygame.Rect(0, 0, piece_width, piece_height),
2
)
# +++
P1 = copy.deepcopy(pieces) # +++
random.shuffle(pieces)
selected_piece = None
move_x, move_y = 0, 0
def get_initial_coordinates(cols, rows,
piece_width, piece_height):
initial_coords = {}
for i in range(rows):
for j in range(cols):
initial_coords[i * cols + j] = (
j * piece_width, i * piece_height)
return initial_coords
initial_coords = get_initial_coordinates(
cols, rows, piece_width, piece_height)
def check_completed_puzzle(pieces, initial_coords):
'''
for i, piece in enumerate(pieces):
x = i % cols
y = i // cols
if piece.get_rect().topleft != initial_coords[i]:
return False
return True
'''
# +++ # +++
if P1[0][1] == pieces[0][1] and P1[1][1] == pieces[1][1] and \
P1[2][1] == pieces[2][1] and P1[3][1] == pieces[3][1] : # +++
return True
return False
running = True
selected_piece = None
initial_coords = get_initial_coordinates(cols, rows, piece_width, piece_height)
while running:
move_x, move_y = 0, 0
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
elif event.key == pygame.K_UP:
move_x, move_y = 0, -1
elif event.key == pygame.K_DOWN:
move_x, move_y = 0, 1
elif event.key == pygame.K_LEFT:
move_x, move_y = -1, 0
elif event.key == pygame.K_RIGHT:
move_x, move_y = 1, 0
if event.type == pygame.MOUSEBUTTONDOWN:
x, y = pygame.mouse.get_pos()
col = x // piece_width
row = y // piece_height
selected_piece = row * cols + col
if selected_piece is not None:
x = selected_piece % cols
y = selected_piece // cols
new_x = x + move_x
new_y = y + move_y
new_index = new_y * cols + new_x
if 0 <= new_x < cols and 0 <= new_y < rows and \
abs(move_x) + abs(move_y) == 1:
pieces[selected_piece], pieces[new_index] = pieces[new_index], \
pieces[selected_piece]
selected_piece = new_index
# ----------------------------------> ?????????????????????? <------------
if check_completed_puzzle(pieces, initial_coords):
print("Вы собрали пазл!")
running = False
screen.fill((0, 0, 0))
for i, piece in enumerate(pieces):
# print(f'y_x ==== {piece[1]} ---- {i}') #
x = i % cols
y = i // cols
# ----------------------> v <----------------------------------------------
screen.blit(piece[0], (x * piece_width, y * piece_height))
if selected_piece is not None:
x = selected_piece % cols
y = selected_piece // cols
pygame.draw.rect(
screen,
(0, 222, 255),
pygame.Rect(
x * piece_width,
y * piece_height,
piece_width,
piece_height),
2
)
pygame.display.flip()
pygame.quit()
input("Игра закончена. Нажмите Enter.")