Загрузка данных


import turtle

# Настройка главного окна
window = turtle.Screen()
window.title("2D Лабиринт")
window.bgcolor("black")
window.setup(width=700, height=750)  
window.tracer(0)

GRID_SIZE = 24

# Карта лабиринта: X - стена, O - старт, E - финиш
maze_map = [
    "XXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "XO    X                X  X",
    "XXXXX X XXXXXXXXXXXXX XX  X",
    "X   X X X           X     X",
    "X X X X X XXXXXXX XXXXXX XX",
    "X            X         X  X",
    "X XXXXXXX X XXXXXXXXXX    X",
    "X       X X          X X  X",
    "XXXXXXX   XXXXXXXXXX X   XX",
    "X     XXXXX          X X  X",
    "X XXXXX     XXXXXXXXXXX   X",
    "X X     XXX               X",
    "X X XXXXXXX XXXXXXXXXX XXXX",
    "X X       X X             X",
    "X XXXXXXX X X X XXXXXXXXXXX",
    "X X     X X X X           X",
    "X X XXX X X X X XXXXXX XX X",
    "X   X   X X   X    X X X  X",
    "XXXXX XXX XXXXXXXXXX XXX XX",
    "X     X                   X",
    "X XXXXXXXXXXXXXXXXXXXX XXXX",
    "X X                       X",
    "X XXXXXX XXXXXXXX XXXXX   X",
    "X            X       X    EX",
    "XXXXXXXXXXXXXXXXXXXXXXXXXXX"
]

# Глобальные переменные игры
walls = []
player = None
finish = None
steps_count = 0
is_game_over = False

# Отдельные исполнители (Turtles) для интерфейса, чтобы они не стирали друг друга
button_pen = turtle.Turtle()
button_pen.hideturtle()
button_pen.penup()

text_pen = turtle.Turtle()
text_pen.hideturtle()
text_pen.penup()

score_pen = turtle.Turtle()
score_pen.hideturtle()
score_pen.penup()
score_pen.color("yellow")

class Wall(turtle.Turtle):
    def __init__(self, x, y):
        super().__init__()
        self.shape("square")
        self.color("white")
        self.penup()
        self.goto(x, y)

class Player(turtle.Turtle):
    def __init__(self, x, y):
        super().__init__()
        self.shape("circle")
        self.color("cyan")
        self.penup()
        self.goto(x, y)

    def move(self, dx, dy):
        global steps_count, is_game_over
        if is_game_over:
            return  # Блокируем движения, если игра завершена

        target_x = self.xcor() + dx
        target_y = self.ycor() + dy
        
        if (target_x, target_y) not in walls:
            self.goto(target_x, target_y)
            steps_count += 1
            update_score_display()
            check_win()
            window.update()

class Finish(turtle.Turtle):
    def __init__(self, x, y):
        super().__init__()
        self.shape("square")
        self.color("gold")
        self.penup()
        self.goto(x, y)

# Функции перемещения
def go_up(): player.move(0, GRID_SIZE)
def go_down(): player.move(0, -GRID_SIZE)
def go_left(): player.move(-GRID_SIZE, 0)
def go_right(): player.move(GRID_SIZE, 0)

# Обновление текста со счетом (шагами)
def update_score_display():
    score_pen.clear()
    score_pen.goto(-280, 312)
    score_pen.write(f"Шаги: {steps_count}", align="left", font=("Arial", 14, "bold"))

# Отрисовка кнопок интерфейса
def draw_interface():
    button_pen.clear()
    text_pen.clear()
    
    # Кнопка ЗАГРУЗИТЬ ЗАНОВО (R)
    button_pen.goto(-60, 305)
    button_pen.color("gray")
    button_pen.begin_fill()
    for _ in range(2):
        button_pen.forward(140)
        button_pen.left(90)
        button_pen.forward(35)
        button_pen.left(90)
    button_pen.end_fill()
    
    button_pen.goto(10, 313)
    button_pen.color("white")
    button_pen.write("Заново (R)", align="center", font=("Arial", 11, "bold"))

    # Кнопка ВЫХОД (Q)
    button_pen.goto(110, 305)
    button_pen.color("darkred")
    button_pen.begin_fill()
    for _ in range(2):
        button_pen.forward(140)
        button_pen.left(90)
        button_pen.forward(35)
        button_pen.left(90)
    button_pen.end_fill()
    
    button_pen.goto(180, 313)
    button_pen.color("white")
    button_pen.write("Выход (Q)", align="center", font=("Arial", 11, "bold"))

def check_win():
    global is_game_over
    if player.distance(finish) < 5:
        is_game_over = True
        text_pen.goto(0, 0)
        text_pen.color("lime")
        text_pen.write("ВЫ ПОБЕДИЛИ!", align="center", font=("Arial", 28, "bold"))

# Функция полного сброса и старта игры
def start_new_game():
    global player, finish, walls, steps_count, is_game_over
    
    # Сбрасываем переменные состояния
    steps_count = 0
    is_game_over = False
    
    # Очищаем старые объекты стен и персонажей, чтобы не забивать память
    window.clearscreen()
    window.bgcolor("black")
    window.tracer(0)
    
    walls.clear()
    
    # Пересоздаем интерфейс на чистом экране
    draw_interface()
    update_score_display()

    # Генерация лабиринта
    start_x = -300
    start_y = 270

    for row_idx, row in enumerate(maze_map):
        for col_idx, char in enumerate(row):
            screen_x = start_x + (col_idx * GRID_SIZE)
            screen_y = start_y - (row_idx * GRID_SIZE)

            if char == "X":
                Wall(screen_x, screen_y)
                walls.append((screen_x, screen_y))
            elif char == "O":
                player = Player(screen_x, screen_y)
            elif char == "E":
                finish = Finish(screen_x, screen_y)

    # Перепривязка управления и кнопок после очистки экрана
    window.listen()
    window.onkey(go_up, "Up")
    window.onkey(go_down, "Down")
    window.onkey(go_left, "Left")
    window.onkey(go_right, "Right")
    
    # Горячие клавиши (работают и на английской раскладке, и на заглавных)
    window.onkey(start_new_game, "r")
    window.onkey(start_new_game, "R")
    window.onkey(close_game, "q")
    window.onkey(close_game, "Q")
    
    window.onclick(check_click)
    window.update()

def close_game():
    window.bye()

# Обработка кликов мыши по координатам кнопок
def check_click(x, y):
    # Кнопка "Заново"
    if -60 <= x <= 80 and 305 <= y <= 340:
        start_new_game()
    # Кнопка "Выход"
    elif 110 <= x <= 250 and 305 <= y <= 340:
        close_game()

# Первичный запуск программы
start_new_game()
window.mainloop()