diff --git "a/5030102_30202/\320\232\320\276\320\267\320\260\320\272 \320\222\320\273\320\260\320\264\320\270\321\201\320\273\320\260\320\262 \320\222\320\270\321\202\320\260\320\273\321\214\320\265\320\262\320\270\321\207/TK.py" "b/5030102_30202/\320\232\320\276\320\267\320\260\320\272 \320\222\320\273\320\260\320\264\320\270\321\201\320\273\320\260\320\262 \320\222\320\270\321\202\320\260\320\273\321\214\320\265\320\262\320\270\321\207/TK.py" new file mode 100644 index 0000000..d4a297a --- /dev/null +++ "b/5030102_30202/\320\232\320\276\320\267\320\260\320\272 \320\222\320\273\320\260\320\264\320\270\321\201\320\273\320\260\320\262 \320\222\320\270\321\202\320\260\320\273\321\214\320\265\320\262\320\270\321\207/TK.py" @@ -0,0 +1,390 @@ +import tkinter as tk +from tkinter import ttk +from enum import Enum, auto +from typing import Optional, Iterator, List +import threading +import time + +# --- Классы из main.py --- +class WorkshopCellType(Enum): + Floor = auto() + Detail = auto() + Repaired = auto() + Tool = auto() + Obstacle = auto() + Oil = auto() + Finish = auto() + +class WorkDirection(Enum): + Forward = auto() + Backward = auto() + Left = auto() + Right = auto() + DiagUp = auto() + DiagDown = auto() + +class WorkshopCell: + def __init__(self, cell_type: WorkshopCellType, has_robot: bool = False, x: int = 0, y: int = 0): + self.cell_type = cell_type + self.has_robot = has_robot + self.x = x + self.y = y + self.visited = False + +class Workshop: + def __init__(self, width: int = 8, height: int = 6): + self.width = width + self.height = height + self.cells = [[WorkshopCell(WorkshopCellType.Floor, False, x, y) + for y in range(height)] for x in range(width)] + self.setup_default() + + def setup_default(self): + """Настройка по умолчанию""" + for x in range(self.width): + for y in range(self.height): + self.cells[x][y] = WorkshopCell(WorkshopCellType.Floor, False, x, y) + + # Старт + self.cells[0][0].cell_type = WorkshopCellType.Floor + self.cells[0][0].has_robot = True + + # Детали + self.cells[2][2].cell_type = WorkshopCellType.Detail + self.cells[5][3].cell_type = WorkshopCellType.Detail + + # Препятствия + self.cells[3][2].cell_type = WorkshopCellType.Obstacle + self.cells[4][4].cell_type = WorkshopCellType.Obstacle + + # Финиш + self.cells[7][5].cell_type = WorkshopCellType.Finish + + def get_adjacent_cell(self, current_cell: WorkshopCell, direction_value: int) -> Optional[WorkshopCell]: + direction = WorkDirection(direction_value) + dx, dy = 0, 0 + + if direction == WorkDirection.Forward: # Вперед + dy = 1 + elif direction == WorkDirection.Backward: # Назад + dy = -1 + elif direction == WorkDirection.Left: # Влево + dx = -1 + elif direction == WorkDirection.Right: # Вправо + dx = 1 + elif direction == WorkDirection.DiagUp: # Диаг вверх + dx = -1 + dy = 1 + elif direction == WorkDirection.DiagDown: # Диаг вниз + dx = 1 + dy = -1 + + nx = current_cell.x + dx + ny = current_cell.y + dy + + if 0 <= nx < self.width and 0 <= ny < self.height: + return self.cells[nx][ny] + return None + +class RobotMechanic: + def __init__(self, workshop: Workshop): + self.workshop = workshop + self.current_cell = self._find_robot_cell() + self.auto_running = False + + def _find_robot_cell(self) -> WorkshopCell: + for x in range(self.workshop.width): + for y in range(self.workshop.height): + if self.workshop.cells[x][y].has_robot: + return self.workshop.cells[x][y] + return self.workshop.cells[0][0] + + def move(self, direction: WorkDirection) -> bool: + next_cell = self.workshop.get_adjacent_cell(self.current_cell, direction.value) + if next_cell is None: + return False + if next_cell.cell_type in (WorkshopCellType.Obstacle, WorkshopCellType.Oil): + return False + + self.current_cell.has_robot = False + next_cell.has_robot = True + next_cell.visited = True + self.current_cell = next_cell + + if next_cell.cell_type == WorkshopCellType.Detail: + next_cell.cell_type = WorkshopCellType.Repaired + + return True + + def repair(self): + if self.current_cell.cell_type == WorkshopCellType.Detail: + self.current_cell.cell_type = WorkshopCellType.Repaired + return True + return False + + def execute_task(self): + """Умный автоматический обход""" + if self.auto_running: + return + + self.auto_running = True + + def run_task(): + # Находим детали + details = [] + for x in range(self.workshop.width): + for y in range(self.workshop.height): + if self.workshop.cells[x][y].cell_type == WorkshopCellType.Detail: + details.append((x, y)) + + # Находим финиш + finish = None + for x in range(self.workshop.width): + for y in range(self.workshop.height): + if self.workshop.cells[x][y].cell_type == WorkshopCellType.Finish: + finish = (x, y) + break + if finish: + break + + if not finish: + self.auto_running = False + return + + # Обход в ширину для поиска путей + def bfs(start, targets): + from collections import deque + + queue = deque([(start[0], start[1], [])]) + visited = set() + + while queue: + x, y, path = queue.popleft() + + if (x, y) in visited: + continue + visited.add((x, y)) + + new_path = path + [(x, y)] + + if (x, y) in targets: + return new_path[1:] # Исключаем стартовую позицию + + # Проверяем соседей + for dx, dy in [(0, 1), (1, 0), (0, -1), (-1, 0), (-1, 1), (1, -1)]: + nx, ny = x + dx, y + dy + if 0 <= nx < self.workshop.width and 0 <= ny < self.workshop.height: + cell = self.workshop.cells[nx][ny] + if cell.cell_type not in (WorkshopCellType.Obstacle, WorkshopCellType.Oil): + if (nx, ny) not in visited: + queue.append((nx, ny, new_path)) + + return None + + current_pos = (self.current_cell.x, self.current_cell.y) + + # Посещаем все детали + for target in details: + path = bfs(current_pos, [target]) + if path: + for x, y in path: + # Обновляем в основном потоке + tk.Tk.after(root, 0, lambda x=x, y=y: move_to_cell(x, y)) + time.sleep(0.3) + + current_pos = target + if self.current_cell.cell_type == WorkshopCellType.Detail: + tk.Tk.after(root, 0, lambda: repair_cell()) + time.sleep(0.5) + + # Идем к финишу + if finish: + path = bfs(current_pos, [finish]) + if path: + for x, y in path: + tk.Tk.after(root, 0, lambda x=x, y=y: move_to_cell(x, y)) + time.sleep(0.3) + + tk.Tk.after(root, 0, lambda: set_status("Автоматический обход завершен")) + self.auto_running = False + + thread = threading.Thread(target=run_task) + thread.daemon = True + thread.start() + +# --- Tkinter GUI --- +root = tk.Tk() +root.title("Робот-Механик") +root.geometry("600x500") + +# Переменные +workshop = Workshop() +robot = RobotMechanic(workshop) +selected_cell_type = WorkshopCellType.Floor +colors = { + WorkshopCellType.Floor: "white", + WorkshopCellType.Detail: "lightblue", + WorkshopCellType.Repaired: "lightgreen", + WorkshopCellType.Tool: "yellow", + WorkshopCellType.Obstacle: "gray", + WorkshopCellType.Oil: "brown", + WorkshopCellType.Finish: "pink" +} + +# Функции +def update_display(): + canvas.delete("all") + + cell_size = 40 + margin = 50 + + for x in range(workshop.width): + for y in range(workshop.height): + cell = workshop.cells[x][y] + + # Координаты + x1 = margin + x * cell_size + y1 = margin + y * cell_size + x2 = x1 + cell_size + y2 = y1 + cell_size + + # Цвет фона + if cell.visited: + bg = "#e0e0e0" + else: + bg = colors.get(cell.cell_type, "white") + + canvas.create_rectangle(x1, y1, x2, y2, fill=bg, outline="black") + + # Робот + if cell.has_robot: + center_x = (x1 + x2) / 2 + center_y = (y1 + y2) / 2 + radius = cell_size // 4 + canvas.create_oval(center_x - radius, center_y - radius, + center_x + radius, center_y + radius, + fill="red", outline="darkred") + + # Координатная сетка + for x in range(workshop.width): + x_pos = margin + x * cell_size + cell_size // 2 + canvas.create_text(x_pos, margin - 10, text=str(x)) + + for y in range(workshop.height): + y_pos = margin + y * cell_size + cell_size // 2 + canvas.create_text(margin - 10, y_pos, text=str(y)) + +def on_canvas_click(event): + cell_size = 40 + margin = 50 + + x = (event.x - margin) // cell_size + y = (event.y - margin) // cell_size + + if 0 <= x < workshop.width and 0 <= y < workshop.height: + cell = workshop.cells[x][y] + + # Не изменяем клетку с роботом + if cell.has_robot: + set_status("Нельзя изменить клетку с роботом") + return + + # Изменяем тип клетки + cell.cell_type = selected_cell_type + update_display() + set_status(f"Клетка ({x},{y}) изменена на {selected_cell_type.name}") + +def move_robot(direction: WorkDirection): + if robot.move(direction): + update_display() + set_status(f"Робот перемещен") + else: + set_status(f"Невозможно переместиться") + +def repair_cell(): + if robot.repair(): + update_display() + set_status("Деталь отремонтирована") + else: + set_status("Здесь нет детали") + +def move_to_cell(x, y): + cell = workshop.cells[x][y] + if cell.cell_type not in (WorkshopCellType.Obstacle, WorkshopCellType.Oil): + robot.current_cell.has_robot = False + cell.has_robot = True + cell.visited = True + robot.current_cell = cell + + if cell.cell_type == WorkshopCellType.Detail: + cell.cell_type = WorkshopCellType.Repaired + + update_display() + +def set_status(text): + status_label.config(text=text) + +def start_auto(): + set_status("Запущен автоматический обход...") + robot.execute_task() + +# Интерфейс +canvas = tk.Canvas(root, width=400, height=300, bg="white") +canvas.pack(pady=10) +canvas.bind("", on_canvas_click) + +# Панель управления +control_frame = tk.Frame(root) +control_frame.pack(pady=5) + +# Кнопки ручного управления +move_frame = tk.Frame(control_frame) +move_frame.pack(side=tk.LEFT, padx=10) + +tk.Button(move_frame, text="↑", width=3, command=lambda: move_robot(WorkDirection.Forward)).grid(row=0, column=1) +tk.Button(move_frame, text="↓", width=3, command=lambda: move_robot(WorkDirection.Backward)).grid(row=2, column=1) +tk.Button(move_frame, text="←", width=3, command=lambda: move_robot(WorkDirection.Left)).grid(row=1, column=0) +tk.Button(move_frame, text="→", width=3, command=lambda: move_robot(WorkDirection.Right)).grid(row=1, column=2) +tk.Button(move_frame, text="↖", width=3, command=lambda: move_robot(WorkDirection.DiagUp)).grid(row=0, column=0) +tk.Button(move_frame, text="↘", width=3, command=lambda: move_robot(WorkDirection.DiagDown)).grid(row=2, column=2) +tk.Button(move_frame, text="🔧", width=3, command=repair_cell).grid(row=1, column=1) + +# Выбор типа клетки +type_frame = tk.Frame(control_frame) +type_frame.pack(side=tk.LEFT, padx=10) + +tk.Label(type_frame, text="Тип клетки:").pack() +type_var = tk.StringVar(value="Floor") +type_menu = ttk.Combobox(type_frame, textvariable=type_var, + values=["Floor", "Detail", "Repaired", "Tool", "Obstacle", "Oil", "Finish"], + state="readonly", width=10) +type_menu.pack() + +def on_type_select(event): + global selected_cell_type + selected_cell_type = WorkshopCellType[type_var.get()] + +type_menu.bind("<>", on_type_select) + +# Кнопка автоматического обхода +auto_frame = tk.Frame(control_frame) +auto_frame.pack(side=tk.LEFT, padx=10) + +tk.Button(auto_frame, text="🤖 Автоматический обход", command=start_auto, width=20).pack() + +# Статус +status_label = tk.Label(root, text="Готов", font=("Arial", 10)) +status_label.pack(pady=5) + +# Информация +info_frame = tk.Frame(root) +info_frame.pack() + +tk.Label(info_frame, text="Управление:").grid(row=0, column=0, sticky="w") +tk.Label(info_frame, text="• ЛКМ: изменить тип клетки").grid(row=1, column=0, sticky="w") +tk.Label(info_frame, text="• Кнопки: управление роботом").grid(row=2, column=0, sticky="w") + +# Инициализация +update_display() + +root.mainloop() diff --git "a/5030102_30202/\320\232\320\276\320\267\320\260\320\272 \320\222\320\273\320\260\320\264\320\270\321\201\320\273\320\260\320\262 \320\222\320\270\321\202\320\260\320\273\321\214\320\265\320\262\320\270\321\207/app.py" "b/5030102_30202/\320\232\320\276\320\267\320\260\320\272 \320\222\320\273\320\260\320\264\320\270\321\201\320\273\320\260\320\262 \320\222\320\270\321\202\320\260\320\273\321\214\320\265\320\262\320\270\321\207/app.py" new file mode 100644 index 0000000..84e30e5 --- /dev/null +++ "b/5030102_30202/\320\232\320\276\320\267\320\260\320\272 \320\222\320\273\320\260\320\264\320\270\321\201\320\273\320\260\320\262 \320\222\320\270\321\202\320\260\320\273\321\214\320\265\320\262\320\270\321\207/app.py" @@ -0,0 +1,736 @@ +from flask import Flask, render_template_string, jsonify, request +from enum import Enum, auto +from typing import Optional, List, Tuple +import json + +app = Flask(__name__) + +# HTML шаблон +HTML_TEMPLATE = ''' + + + + Робот-Механик + + + +
+

🤖 Робот-Механик

+ +
Готов к работе
+ +
+ + + + +
+ +
+ +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
Пол
+
Деталь
+
Отремонтировано
+
Инструмент
+
Препятствие
+
Масло
+
Финиш
+
Посещено
+
Робот
+
+ +
+ Инструкция:
+ • ЛКМ по клетке: изменить тип клетки
+ • Используйте кнопки для ручного управления роботом
+ • Нажмите "Автообход" для автоматического выполнения задачи
+ • Робот найдет и отремонтирует все детали, затем пойдет к финишу +
+
+ + + + +''' + +# --- Классы (упрощенные) --- +class WorkshopCellType(Enum): + Floor = auto() + Detail = auto() + Repaired = auto() + Tool = auto() + Obstacle = auto() + Oil = auto() + Finish = auto() + +class WorkDirection(Enum): + Forward = auto() + Backward = auto() + Left = auto() + Right = auto() + DiagUp = auto() + DiagDown = auto() + +class WorkshopCell: + def __init__(self, cell_type: WorkshopCellType, x: int = 0, y: int = 0): + self.cell_type = cell_type + self.has_robot = False + self.x = x + self.y = y + self.visited = False + + def to_dict(self): + return { + 'type': self.cell_type.name, + 'robot': self.has_robot, + 'visited': self.visited, + 'x': self.x, + 'y': self.y + } + +class Workshop: + def __init__(self, width: int = 8, height: int = 6): + self.width = width + self.height = height + self.cells = [[WorkshopCell(WorkshopCellType.Floor, x, y) + for y in range(height)] for x in range(width)] + self.setup_default() + + def setup_default(self): + # Очищаем все ячейки + for x in range(self.width): + for y in range(self.height): + self.cells[x][y] = WorkshopCell(WorkshopCellType.Floor, x, y) + + # Стартовая позиция робота + self.cells[0][0].has_robot = True + self.cells[0][0].visited = True + + # Детали для ремонта + self.cells[2][2].cell_type = WorkshopCellType.Detail + self.cells[5][3].cell_type = WorkshopCellType.Detail + self.cells[4][5].cell_type = WorkshopCellType.Detail + + # Препятствия + self.cells[3][2].cell_type = WorkshopCellType.Obstacle + self.cells[4][4].cell_type = WorkshopCellType.Obstacle + + # Масло + self.cells[6][2].cell_type = WorkshopCellType.Oil + + # Инструменты + self.cells[2][5].cell_type = WorkshopCellType.Tool + + # Финиш + self.cells[7][5].cell_type = WorkshopCellType.Finish + + def get_adjacent_cell(self, x: int, y: int, direction: WorkDirection): + dx, dy = 0, 0 + + if direction == WorkDirection.Forward: # Вперед (север) + dy = 1 + elif direction == WorkDirection.Backward: # Назад (юг) + dy = -1 + elif direction == WorkDirection.Left: # Влево (запад) + dx = -1 + elif direction == WorkDirection.Right: # Вправо (восток) + dx = 1 + elif direction == WorkDirection.DiagUp: # Диаг. вверх (северо-запад) + dx = -1 + dy = 1 + elif direction == WorkDirection.DiagDown: # Диаг. вниз (юго-восток) + dx = 1 + dy = -1 + + nx, ny = x + dx, y + dy + if 0 <= nx < self.width and 0 <= ny < self.height: + return self.cells[nx][ny] + return None + + def find_robot(self) -> Tuple[int, int]: + for x in range(self.width): + for y in range(self.height): + if self.cells[x][y].has_robot: + return x, y + return 0, 0 + + def find_all_details(self) -> List[Tuple[int, int]]: + details = [] + for x in range(self.width): + for y in range(self.height): + if self.cells[x][y].cell_type == WorkshopCellType.Detail: + details.append((x, y)) + return details + + def find_finish(self) -> Optional[Tuple[int, int]]: + for x in range(self.width): + for y in range(self.height): + if self.cells[x][y].cell_type == WorkshopCellType.Finish: + return (x, y) + return None + + def to_dict(self): + return { + 'width': self.width, + 'height': self.height, + 'cells': [[self.cells[x][y].to_dict() for y in range(self.height)] + for x in range(self.width)] + } + +# Глобальные переменные +workshop = Workshop() + +# --- Улучшенный алгоритм поиска пути --- +def find_path(start: Tuple[int, int], target: Tuple[int, int]) -> List[Tuple[int, int]]: + """Находит путь от start до target с помощью BFS""" + from collections import deque + + if start == target: + return [start] + + visited = set() + queue = deque() + queue.append((start, [])) # (position, path) + + # Все возможные направления движения + directions = [ + (1, 0, WorkDirection.Right), # вправо + (-1, 0, WorkDirection.Left), # влево + (0, 1, WorkDirection.Forward), # вперед + (0, -1, WorkDirection.Backward), # назад + (-1, 1, WorkDirection.DiagUp), # диаг. вверх + (1, -1, WorkDirection.DiagDown) # диаг. вниз + ] + + while queue: + (x, y), path = queue.popleft() + + if (x, y) in visited: + continue + visited.add((x, y)) + + new_path = path + [(x, y)] + + if (x, y) == target: + return new_path # Возвращаем путь включая стартовую позицию + + # Проверяем соседние клетки + for dx, dy, direction in directions: + nx, ny = x + dx, y + dy + + if 0 <= nx < workshop.width and 0 <= ny < workshop.height: + cell = workshop.cells[nx][ny] + # Можно проходить через пол, детали, инструменты, финиш + if cell.cell_type not in (WorkshopCellType.Obstacle, WorkshopCellType.Oil): + if (nx, ny) not in visited: + queue.append(((nx, ny), new_path)) + + return [] # Путь не найден + +def convert_path_to_directions(path: List[Tuple[int, int]]) -> List[WorkDirection]: + """Конвертирует путь в последовательность направлений""" + directions = [] + + for i in range(len(path) - 1): + x1, y1 = path[i] + x2, y2 = path[i + 1] + + dx = x2 - x1 + dy = y2 - y1 + + if dx == 1 and dy == 0: + directions.append(WorkDirection.Right) + elif dx == -1 and dy == 0: + directions.append(WorkDirection.Left) + elif dx == 0 and dy == 1: + directions.append(WorkDirection.Forward) + elif dx == 0 and dy == -1: + directions.append(WorkDirection.Backward) + elif dx == -1 and dy == 1: + directions.append(WorkDirection.DiagUp) + elif dx == 1 and dy == -1: + directions.append(WorkDirection.DiagDown) + + return directions + +# API маршруты +@app.route('/') +def index(): + return render_template_string(HTML_TEMPLATE) + +@app.route('/api/maze') +def get_maze(): + return jsonify({'maze': workshop.to_dict()}) + +@app.route('/api/change_cell', methods=['POST']) +def change_cell(): + data = request.json + x, y, type_name = data['x'], data['y'], data['type'] + + # Не меняем клетку с роботом + if workshop.cells[x][y].has_robot: + return jsonify({ + 'maze': workshop.to_dict(), + 'status': 'Нельзя изменить клетку с роботом' + }) + + workshop.cells[x][y].cell_type = WorkshopCellType[type_name] + return jsonify({ + 'maze': workshop.to_dict(), + 'status': f'Клетка ({x},{y}) изменена на {type_name}' + }) + +@app.route('/api/move', methods=['POST']) +def move_robot(): + data = request.json + direction = WorkDirection[data['direction']] + + x, y = workshop.find_robot() + next_cell = workshop.get_adjacent_cell(x, y, direction) + + if next_cell is None: + return jsonify({ + 'maze': workshop.to_dict(), + 'status': 'Невозможно переместиться за пределы лабиринта' + }) + + if next_cell.cell_type in (WorkshopCellType.Obstacle, WorkshopCellType.Oil): + return jsonify({ + 'maze': workshop.to_dict(), + 'status': 'Препятствие на пути' + }) + + # Перемещаем робота + workshop.cells[x][y].has_robot = False + next_cell.has_robot = True + next_cell.visited = True + + # Ремонт детали, если робот на ней + if next_cell.cell_type == WorkshopCellType.Detail: + next_cell.cell_type = WorkshopCellType.Repaired + status = 'Робот перемещен, деталь отремонтирована' + else: + status = 'Робот перемещен' + + return jsonify({ + 'maze': workshop.to_dict(), + 'status': status + }) + +@app.route('/api/repair', methods=['POST']) +def repair_cell(): + x, y = workshop.find_robot() + cell = workshop.cells[x][y] + + if cell.cell_type == WorkshopCellType.Detail: + cell.cell_type = WorkshopCellType.Repaired + status = 'Деталь отремонтирована' + else: + status = 'Здесь нет детали' + + return jsonify({ + 'maze': workshop.to_dict(), + 'status': status + }) + +@app.route('/api/get_auto_plan', methods=['POST']) +def get_auto_plan(): + """Строит план автоматического обхода""" + plan = [] + + # Находим текущую позицию робота + start_x, start_y = workshop.find_robot() + + # Находим все детали + details = workshop.find_all_details() + + # Находим финиш + finish = workshop.find_finish() + + if not finish: + return jsonify({'error': 'Финиш не найден'}) + + current_pos = (start_x, start_y) + + # Посещаем все детали + for detail in details: + detail_x, detail_y = detail + + # Находим путь к детали + path = find_path(current_pos, (detail_x, detail_y)) + if not path: + continue + + # Конвертируем путь в направления + directions = convert_path_to_directions(path) + + # Добавляем перемещения в план + for direction in directions: + plan.append({ + 'type': 'move', + 'direction': direction.name, + 'message': f'Движение к детали в ({detail_x},{detail_y})' + }) + + # Добавляем ремонт детали + plan.append({ + 'type': 'repair', + 'message': f'Ремонт детали в ({detail_x},{detail_y})' + }) + + current_pos = (detail_x, detail_y) + + # Идем к финишу + finish_x, finish_y = finish + path_to_finish = find_path(current_pos, (finish_x, finish_y)) + + if path_to_finish: + directions = convert_path_to_directions(path_to_finish) + + for direction in directions: + plan.append({ + 'type': 'move', + 'direction': direction.name, + 'message': f'Движение к финишу в ({finish_x},{finish_y})' + }) + + # Создаем копию лабиринта для симуляции выполнения плана + # (чтобы вернуть конечное состояние) + import copy + + # Внимание: это упрощенная симуляция + # В реальном приложении нужно было бы выполнять план шаг за шагом + final_workshop = copy.deepcopy(workshop) + + # Симулируем выполнение плана + robot_x, robot_y = start_x, start_y + for step in plan: + if step['type'] == 'move': + direction = WorkDirection[step['direction']] + next_cell = final_workshop.get_adjacent_cell(robot_x, robot_y, direction) + if next_cell: + final_workshop.cells[robot_x][robot_y].has_robot = False + next_cell.has_robot = True + next_cell.visited = True + robot_x, robot_y = next_cell.x, next_cell.y + + # Ремонт детали при движении + if next_cell.cell_type == WorkshopCellType.Detail: + next_cell.cell_type = WorkshopCellType.Repaired + elif step['type'] == 'repair': + cell = final_workshop.cells[robot_x][robot_y] + if cell.cell_type == WorkshopCellType.Detail: + cell.cell_type = WorkshopCellType.Repaired + + return jsonify({ + 'plan': plan, + 'final_maze': final_workshop.to_dict() + }) + +if __name__ == '__main__': + app.run(debug=True, port=5005) diff --git "a/5030102_30202/\320\232\320\276\320\267\320\260\320\272 \320\222\320\273\320\260\320\264\320\270\321\201\320\273\320\260\320\262 \320\222\320\270\321\202\320\260\320\273\321\214\320\265\320\262\320\270\321\207/\320\255\321\202\320\260\320\277 1.mp4" "b/5030102_30202/\320\232\320\276\320\267\320\260\320\272 \320\222\320\273\320\260\320\264\320\270\321\201\320\273\320\260\320\262 \320\222\320\270\321\202\320\260\320\273\321\214\320\265\320\262\320\270\321\207/\320\255\321\202\320\260\320\277 1.mp4" new file mode 100644 index 0000000..7490e95 Binary files /dev/null and "b/5030102_30202/\320\232\320\276\320\267\320\260\320\272 \320\222\320\273\320\260\320\264\320\270\321\201\320\273\320\260\320\262 \320\222\320\270\321\202\320\260\320\273\321\214\320\265\320\262\320\270\321\207/\320\255\321\202\320\260\320\277 1.mp4" differ diff --git "a/5030102_30202/\320\232\320\276\320\267\320\260\320\272 \320\222\320\273\320\260\320\264\320\270\321\201\320\273\320\260\320\262 \320\222\320\270\321\202\320\260\320\273\321\214\320\265\320\262\320\270\321\207/\320\255\321\202\320\260\320\277 2.mp4" "b/5030102_30202/\320\232\320\276\320\267\320\260\320\272 \320\222\320\273\320\260\320\264\320\270\321\201\320\273\320\260\320\262 \320\222\320\270\321\202\320\260\320\273\321\214\320\265\320\262\320\270\321\207/\320\255\321\202\320\260\320\277 2.mp4" new file mode 100644 index 0000000..7c62930 Binary files /dev/null and "b/5030102_30202/\320\232\320\276\320\267\320\260\320\272 \320\222\320\273\320\260\320\264\320\270\321\201\320\273\320\260\320\262 \320\222\320\270\321\202\320\260\320\273\321\214\320\265\320\262\320\270\321\207/\320\255\321\202\320\260\320\277 2.mp4" differ