Как можно реализовать логику создания колоды фишек, так чтобы игру можно было всегда решить?
вот код:
import sys
import copy
import pygame
import random
def init():
# Инициализация Pygame и модуля для работы со шрифтами.
pygame.init()
pygame.font.init()
# Создание заголовка и иконки игры.
pygame.display.set_caption("Пятнашки")
icon = pygame.image.load("Pyatnashki\image\icon.png")
pygame.display.set_icon(icon)
# Создание окна и объекта шрифта.
return pygame.display.set_mode((600, 600)), pygame.font.SysFont('Consolas', 36)
def start_screen(screen, font):
# Отрисовка стартового экрана.
screen.fill(pygame.Color(255, 255, 255))
fontsurf = font.render("Пятнашки", True, pygame.Color(0, 0, 0))
left, top = (screen.get_width() / 2 - fontsurf.get_width() / 2, screen.get_height() / 4 - fontsurf.get_height() / 2)
screen.blit(fontsurf, (left, top))
fontsurf = font.render("Нажмите любую кнопку для начала игры", True, pygame.Color(0, 0, 0))
left, top = (screen.get_width() / 2 - fontsurf.get_width() / 2, screen.get_height() / 2 - fontsurf.get_height() / 2)
screen.blit(fontsurf, (left, top))
pygame.display.flip()
# Ожидание нажатия кнопки для начала игры.
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN:
screen.fill('black')
return
def create_board():
# Определение начального и перемешанного игрового поля.
board = [
[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,0]
]
board_copy = copy.deepcopy(board)
for i in range(4):
for j in range(4):
x1, y1 = i, j
x2, y2 = random.randint(0, 3), random.randint(0, 3)
board_copy[x1][y1], board_copy[x2][y2] = board_copy[x2][y2], board_copy[x1][y1] # Перемешивание фишек.
return board, board_copy
def is_solvable(board):
flat_board = [elem for row in board for elem in row] # Преобразование двумерного списка в одномерный.
inversions = sum(1 for i in range(len(flat_board)) for j in range(i + 1, len(flat_board)) if flat_board[i] > flat_board[j]) # Подсчет количества инверсий.
return inversions % 2 == 0 # Проверка на четность количества инверсий.
def handle_events():
# Обработка событий (нажатие на кнопку "выход" и клик мышью).
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
return pygame.mouse.get_pos() # Возвращение координат клика мыши.
return None
def draw_board(screen, font, board):
# Отрисовка игрового поля на экране.
for x in range(4):
for y in range(4):
rect = pygame.Rect(150*x+10, 150*y+10, 130, 130) # Определение координат фишек.
pygame.draw.rect(screen, pygame.Color(255, 255, 255), rect) # Отрисовка фишек.
piece = board[y][x] # Получение цифры на фишке.
if piece:
fontsurf = font.render(str(piece), True, pygame.Color(255, 0, 0)) # Создание текстовой поверхности.
left, top = (rect.x + (rect.width / 2 - fontsurf.get_width() / 2),
rect.y + (rect.height / 2 - fontsurf.get_height() / 2)) # Центрирование текста на фишке.
screen.blit(fontsurf, (left, top)) # Отображение цифры на фишке.
def update_board(board, pos):
# Обновление игрового поля при кликах пользователя.
if pos:
x, y = pos
x, y = (x - 10) // 150, (y - 10) // 150 # Вычисление координат фишки, на которую кликнул пользователь.
current_piece = board[y][x] # Получение цифры на фишке.
if x > 0 and board[y][x-1] == 0:
board[y][x-1] = current_piece
board[y][x] = 0
if x < 3 and board[y][x+1] == 0:
board[y][x+1] = current_piece
board[y][x] = 0
if y > 0 and board[y-1][x] == 0:
board[y-1][x] = current_piece
board[y][x] = 0
if y < 3 and board[y+1][x] == 0:
board[y+1][x] = current_piece
board[y][x] = 0 # Обновление игрового поля.
def check_win(board,board_copy):
# Проверка, выиграл ли пользователь.
if board == board_copy:
return True
def show_win_screen(screen, font):
# Отображение окна победы и кнопки для перезапуска игры.
screen.fill(pygame.Color(255, 255, 255))
fontsurf = font.render("Вы выиграли!", True, pygame.Color(0, 0, 0))
left, top = (screen.width() / 2 - fontsurf.width() / 2, screen.height() / 4 - fontsurf.height() / 2)
screen.blit(fontsurf, (left, top))
fontsurf = font.render("Нажмите любую кнопку для перезапуска игры", True, pygame.Color(0, 0, 0))
left, top = (screen.width() / 2 - fontsurf.width() / 2, screen.height() / 2 - fontsurf.height() / 2)
screen.blit(fontsurf, (left, top))
pygame.display.flip()
def main():
# Основная функция игры.
screen, font = init() # Инициализация окна и объекта шрифта.
start_screen(screen, font)
board, board_copy = create_board() # Создание и перемешивание игрового поля.
if not is_solvable(board_copy):
board, board_copy = create_board() # Создание и перемешивание игрового поля.
while True:
pos = handle_events() # Обработка событий.
draw_board(screen, font, board_copy) # Отрисовка игрового поля на экране.
update_board(board_copy, pos) # Обновление игрового поля при кликах пользователя.
pygame.display.flip() # Обновление экрана.
if check_win(board,board_copy): # Проверка на победу.
print("Вы выиграли!")
# pygame.time.wait(1000) # Пауза перед началом новой игры.
# board, board_copy = create_board() # Создание и перемешивание нового игрового поля.
show_win_screen(screen, font)
if __name__ == "__main__":
main() # Запуск основной функции игры.