diff --git "a/5030102_30202/\320\235\320\260\320\267\320\260\321\200\320\276\320\262\320\260 \320\220\320\275\320\260\321\201\321\202\320\260\321\201\320\270\321\217 \320\224\320\265\320\275\320\270\321\201\320\276\320\262\320\275\320\260/Readme.md" "b/5030102_30202/\320\235\320\260\320\267\320\260\321\200\320\276\320\262\320\260 \320\220\320\275\320\260\321\201\321\202\320\260\321\201\320\270\321\217 \320\224\320\265\320\275\320\270\321\201\320\276\320\262\320\275\320\260/Readme.md" new file mode 100644 index 0000000..fadedbd --- /dev/null +++ "b/5030102_30202/\320\235\320\260\320\267\320\260\321\200\320\276\320\262\320\260 \320\220\320\275\320\260\321\201\321\202\320\260\321\201\320\270\321\217 \320\224\320\265\320\275\320\270\321\201\320\276\320\262\320\275\320\260/Readme.md" @@ -0,0 +1,25 @@ +# Робот-Программист + +## Описание: +Робот-Программист выполняет задачи в контексте 'Серверов'. +Координатная система: ось Y направлена вверх (на север), ось X направлена вправо (на восток). Начало координат — в нижней левой ячейке. + +--- + +### Методы специализации и их действие: +- Код: заменяет Код -> Развернуто +- Терминал: заменяет Терминал -> Код + +--- + +### Цель: +- После завершения работы не должно остаться ячеек следующих типов: + - Код + - Терминал +- Программа должна завершиться на ячейке типа Финиш + +--- + +### Ограничения перемещения: +- нельзя заходить на ячейки типа Сервер +- нельзя заходить на ячейки типа Баг diff --git "a/5030102_30202/\320\235\320\260\320\267\320\260\321\200\320\276\320\262\320\260 \320\220\320\275\320\260\321\201\321\202\320\260\321\201\320\270\321\217 \320\224\320\265\320\275\320\270\321\201\320\276\320\262\320\275\320\260/Video.mp4" "b/5030102_30202/\320\235\320\260\320\267\320\260\321\200\320\276\320\262\320\260 \320\220\320\275\320\260\321\201\321\202\320\260\321\201\320\270\321\217 \320\224\320\265\320\275\320\270\321\201\320\276\320\262\320\275\320\260/Video.mp4" new file mode 100644 index 0000000..e6685df Binary files /dev/null and "b/5030102_30202/\320\235\320\260\320\267\320\260\321\200\320\276\320\262\320\260 \320\220\320\275\320\260\321\201\321\202\320\260\321\201\320\270\321\217 \320\224\320\265\320\275\320\270\321\201\320\276\320\262\320\275\320\260/Video.mp4" differ diff --git "a/5030102_30202/\320\235\320\260\320\267\320\260\321\200\320\276\320\262\320\260 \320\220\320\275\320\260\321\201\321\202\320\260\321\201\320\270\321\217 \320\224\320\265\320\275\320\270\321\201\320\276\320\262\320\275\320\260/main1.py" "b/5030102_30202/\320\235\320\260\320\267\320\260\321\200\320\276\320\262\320\260 \320\220\320\275\320\260\321\201\321\202\320\260\321\201\320\270\321\217 \320\224\320\265\320\275\320\270\321\201\320\276\320\262\320\275\320\260/main1.py" new file mode 100644 index 0000000..3b9549c --- /dev/null +++ "b/5030102_30202/\320\235\320\260\320\267\320\260\321\200\320\276\320\262\320\260 \320\220\320\275\320\260\321\201\321\202\320\260\321\201\320\270\321\217 \320\224\320\265\320\275\320\270\321\201\320\276\320\262\320\275\320\260/main1.py" @@ -0,0 +1,560 @@ +import enum +import tkinter as tk +from tkinter import messagebox, scrolledtext +from typing import Iterator, Optional, List +import time + + +class ТипНаправленийDevOpsНапр(enum.Enum): + ДеплойВперёд = "ДеплойВперёд" + ОткатНазад = "ОткатНазад" + ВлевоСеть = "ВлевоСеть" + ВправоСеть = "ВправоСеть" + ДиагDevСЗ = "ДиагDevСЗ" + ДиагDevЮВ = "ДиагDevЮВ" + + +class ТипЯчеекСерверов(enum.IntEnum): + Сервер = 0 + Терминал = 1 + Развернуто = 2 + Код = 3 + Баг = 4 + Финиш = 5 + Сеть = 6 + + +class ЯчейкаРоботПрограммист: + def копия(self): + return ЯчейкаРоботПрограммист( + self.ячейка_робота, + self.тип_ячейки + ) + def __init__(self, ячейка_робота: bool, тип_ячейки: ТипЯчеекСерверов): + self.ячейка_робота = ячейка_робота + self.тип_ячейки = тип_ячейки + + def получить_значение(self) -> int: + значение = int(self.тип_ячейки) + if self.ячейка_робота: + значение |= 0x8 + return значение + + def __repr__(self) -> str: + return f"Ячейка(робот={self.ячейка_робота}, тип=0x{self.получить_значение():X})" + + def __eq__(self, other): + if not isinstance(other, ЯчейкаРоботПрограммист): + return False + return (self.ячейка_робота == other.ячейка_робота and + self.тип_ячейки == other.тип_ячейки) + + +class ЛабиринтРоботПрограммист: + def __init__(self, ширина: int, длина: int): + self.ширина = ширина + self.длина = длина + self.ячейки: List[List[ЯчейкаРоботПрограммист]] = [] + + def ИнициализироватьЛабиринт(self, тип_ячейки: ТипЯчеекСерверов): + self.ячейки = [] + for y in range(self.длина): + row = [] + for x in range(self.ширина): + row.append(ЯчейкаРоботПрограммист(False, тип_ячейки)) + self.ячейки.append(row) + + def ПолучитьСоседнююЯчейку(self, текущая_ячейка: ЯчейкаРоботПрограммист, + направление_поиска: ТипНаправленийDevOpsНапр) -> Optional[ЯчейкаРоботПрограммист]: + current_x = current_y = -1 + for y in range(self.длина): + for x in range(self.ширина): + if self.ячейки[y][x] is текущая_ячейка: + current_x, current_y = x, y + break + if current_x != -1: + break + + if current_x == -1 or current_y == -1: + return None + + if направление_поиска == ТипНаправленийDevOpsНапр.ДеплойВперёд: + dx, dy = (0, 1) + elif направление_поиска == ТипНаправленийDevOpsНапр.ОткатНазад: + dx, dy = (0, -1) + elif направление_поиска == ТипНаправленийDevOpsНапр.ВлевоСеть: + dx, dy = (-1, 0) + elif направление_поиска == ТипНаправленийDevOpsНапр.ВправоСеть: + dx, dy = (1, 0) + elif направление_поиска == ТипНаправленийDevOpsНапр.ДиагDevСЗ: + dx, dy = (-1, 1) + elif направление_поиска == ТипНаправленийDevOpsНапр.ДиагDevЮВ: + dx, dy = (1, -1) + else: + return None + + new_x, new_y = current_x + dx, current_y + dy + + if not (0 <= new_x < self.ширина and 0 <= new_y < self.длина): + return None + + новая_ячейка = self.ячейки[new_y][new_x] + + if новая_ячейка.тип_ячейки in (ТипЯчеекСерверов.Сервер, ТипЯчеекСерверов.Баг): + return None + + return новая_ячейка + + def ПолучитьИтератор(self) -> Iterator[ЯчейкаРоботПрограммист]: + if not self.ячейки or self.длина == 0 or self.ширина == 0: + return + + x, y = 0, self.длина - 1 + direction = 1 + + while y >= 0: + yield self.ячейки[y][x] + + if direction == 1: + if x + 1 < self.ширина: + x += 1 + else: + y -= 1 + if y >= 0: + direction = -1 + else: + if x - 1 >= 0: + x -= 1 + else: + y -= 1 + if y >= 0: + direction = 1 + + +class РоботПрограммист: + def __init__(self, лабиринт: ЛабиринтРоботПрограммист): + self.лабиринт = лабиринт + self.деплоэнергия: Optional[ЯчейкаРоботПрограммист] = None + self.откатный: Optional[ЯчейкаРоботПрограммист] = None + + # Находим ячейку с роботом + self.текущая_ячейка = None + for y in range(self.лабиринт.длина): + for x in range(self.лабиринт.ширина): + if self.лабиринт.ячейки[y][x].ячейка_робота: + self.текущая_ячейка = self.лабиринт.ячейки[y][x] + return + + def Деплойнуть(self) -> Optional[ЯчейкаРоботПрограммист]: + if self.текущая_ячейка is None: + return None + + старая_ячейка = self.текущая_ячейка + новая_ячейка = self.лабиринт.ПолучитьСоседнююЯчейку( + старая_ячейка, ТипНаправленийDevOpsНапр.ДеплойВперёд) + + старая_ячейка_до = старая_ячейка.копия() + + if новая_ячейка: + старая_ячейка.ячейка_робота = False + новая_ячейка.ячейка_робота = True + self.текущая_ячейка = новая_ячейка + + return старая_ячейка_до + + def Откатнуть(self) -> Optional[ЯчейкаРоботПрограммист]: + if self.текущая_ячейка is None: + return None + + старая_ячейка = self.текущая_ячейка + новая_ячейка = self.лабиринт.ПолучитьСоседнююЯчейку( + старая_ячейка, ТипНаправленийDevOpsНапр.ОткатНазад) + + старая_ячейка_до = старая_ячейка.копия() + + if новая_ячейка: + старая_ячейка.ячейка_робота = False + новая_ячейка.ячейка_робота = True + self.текущая_ячейка = новая_ячейка + + return старая_ячейка_до + + def СдвинутьВлево(self) -> Optional[ЯчейкаРоботПрограммист]: + if self.текущая_ячейка is None: + return None + + старая_ячейка = self.текущая_ячейка + новая_ячейка = self.лабиринт.ПолучитьСоседнююЯчейку( + старая_ячейка, ТипНаправленийDevOpsНапр.ВлевоСеть) + + старая_ячейка_до = старая_ячейка.копия() + + if новая_ячейка: + старая_ячейка.ячейка_робота = False + новая_ячейка.ячейка_робота = True + self.текущая_ячейка = новая_ячейка + + return старая_ячейка_до + + def СдвинутьВправо(self) -> Optional[ЯчейкаРоботПрограммист]: + if self.текущая_ячейка is None: + return None + + старая_ячейка = self.текущая_ячейка + новая_ячейка = self.лабиринт.ПолучитьСоседнююЯчейку( + старая_ячейка, ТипНаправленийDevOpsНапр.ВправоСеть) + + старая_ячейка_до = старая_ячейка.копия() + + if новая_ячейка: + старая_ячейка.ячейка_робота = False + новая_ячейка.ячейка_робота = True + self.текущая_ячейка = новая_ячейка + + return старая_ячейка_до + + def ПоднятьКонтейнер(self) -> Optional[ЯчейкаРоботПрограммист]: + if self.текущая_ячейка is None: + return None + + старая_ячейка = self.текущая_ячейка + новая_ячейка = self.лабиринт.ПолучитьСоседнююЯчейку( + старая_ячейка, ТипНаправленийDevOpsНапр.ДиагDevСЗ) + + старая_ячейка_до = старая_ячейка.копия() + + if новая_ячейка: + старая_ячейка.ячейка_робота = False + новая_ячейка.ячейка_робота = True + self.текущая_ячейка = новая_ячейка + + return старая_ячейка_до + + def ОпуститьКонтейнер(self) -> Optional[ЯчейкаРоботПрограммист]: + if self.текущая_ячейка is None: + return None + + старая_ячейка = self.текущая_ячейка + новая_ячейка = self.лабиринт.ПолучитьСоседнююЯчейку( + старая_ячейка, ТипНаправленийDevOpsНапр.ДиагDevЮВ) + + старая_ячейка_до = старая_ячейка.копия() + + if новая_ячейка: + старая_ячейка.ячейка_робота = False + новая_ячейка.ячейка_робота = True + self.текущая_ячейка = новая_ячейка + + return старая_ячейка_до + + def Код(self) -> Optional[ЯчейкаРоботПрограммист]: + if self.текущая_ячейка is None: + return None + + до = self.текущая_ячейка.копия() + + if self.текущая_ячейка.тип_ячейки == ТипЯчеекСерверов.Код: + self.текущая_ячейка.тип_ячейки = ТипЯчеекСерверов.Развернуто + + return до + + def Терминал(self) -> Optional[ЯчейкаРоботПрограммист]: + if self.текущая_ячейка is None: + return None + + до = self.текущая_ячейка.копия() + + if self.текущая_ячейка.тип_ячейки == ТипЯчеекСерверов.Терминал: + self.текущая_ячейка.тип_ячейки = ТипЯчеекСерверов.Код + + return до + + +class DevOpsApp: + def __init__(self, root, width=5, height=6): + self.root = root + self.root.title("Робот-Программист") + + self.lab = ЛабиринтРоботПрограммист(width, height) + self.lab.ИнициализироватьЛабиринт(ТипЯчеекСерверов.Сервер) + + self._setup_demo_map() + self.robot = РоботПрограммист(self.lab) + + self.cell_size = 60 + self.canvas = tk.Canvas( + root, + width=width * self.cell_size, + height=height * self.cell_size, + bg="white" + ) + self.canvas.pack(side=tk.LEFT, padx=10, pady=10) + + panel = tk.Frame(root) + panel.pack(side=tk.RIGHT, fill=tk.Y) + + self.log = scrolledtext.ScrolledText( + panel, + width=30, + height=12, + state="disabled" + ) + self.log.pack(fill=tk.BOTH, pady=(0, 10)) + + self.auto_running = False + + style = {'bg': '#F0F0F0', 'activebackground': '#E0E0E0', 'relief': 'flat'} + + tk.Button( + panel, + text="Авто", + bg="#C9E2CD", + command=self.toggle_auto + ).pack(fill=tk.X, pady=10) + + tk.Button(panel, text="Деплой", + command=lambda: self.step(self.robot.Деплойнуть)).pack(fill=tk.X) + + tk.Button(panel, text="Откат", + command=lambda: self.step(self.robot.Откатнуть)).pack(fill=tk.X) + + tk.Button(panel, text="Влево", + command=lambda: self.step(self.robot.СдвинутьВлево)).pack(fill=tk.X) + + tk.Button(panel, text="Вправо", + command=lambda: self.step(self.robot.СдвинутьВправо)).pack(fill=tk.X) + + tk.Button(panel, text="Поднять", + command=lambda: self.step(self.robot.ПоднятьКонтейнер)).pack(fill=tk.X) + + tk.Button(panel, text="Опустить", + command=lambda: self.step(self.robot.ОпуститьКонтейнер)).pack(fill=tk.X) + + tk.Button(panel, text="Код", bg="#F6D6A1", + command=lambda: self.step(self.robot.Код)).pack(fill=tk.X, pady=(10, 0)) + + tk.Button(panel, text="Терминал", bg="#D4DDF1", + command=lambda: self.step(self.robot.Терминал)).pack(fill=tk.X) + + + self.iterator = self.lab.ПолучитьИтератор() + self.draw() + + def toggle_auto(self): + self.auto_running = not self.auto_running + if self.auto_running: + self.write_log("Авто-режим запущен") + self.auto_step_loop() + else: + self.write_log("Авто-режим остановлен") + + def auto_step_loop(self): + if not self.auto_running: + return + + cur = self.robot.текущая_ячейка + + if self.handle_cell_action(): + self.draw() + self.root.after(300, self.auto_step_loop) + return + + try: + target = self.auto_target + except AttributeError: + try: + self.auto_target = next(self.iterator) + target = self.auto_target + except StopIteration: + self.finish_check() + self.auto_running = False + return + + cx = cy = tx = ty = None + + for y in range(self.lab.длина): + for x in range(self.lab.ширина): + if self.lab.ячейки[y][x] is cur: + cx, cy = x, y + if self.lab.ячейки[y][x] is target: + tx, ty = x, y + + prev_cell = self.robot.текущая_ячейка + + moved = False + + if cx != tx: + prev = self.robot.текущая_ячейка + if cx < tx: + self.robot.СдвинутьВправо() + else: + self.robot.СдвинутьВлево() + moved = self.robot.текущая_ячейка is not prev + + if not moved and cy != ty: + prev = self.robot.текущая_ячейка + if cy < ty: + self.robot.Деплойнуть() + else: + self.robot.Откатнуть() + moved = self.robot.текущая_ячейка is not prev + + if not moved: + self.write_log("Авто: путь заблокирован, цель пропущена") + try: + del self.auto_target + self.auto_target = next(self.iterator) + except StopIteration: + ... + self.root.after(50, self.auto_step_loop) + return + + if self.robot.текущая_ячейка is prev_cell: + self.write_log("Авто: цель недостижима, пропуск") + try: + self.auto_target = next(self.iterator) + except StopIteration: + if self.robot.текущая_ячейка.тип_ячейки == ТипЯчеекСерверов.Финиш: + self.finish_check() + else: + self.write_log("Авто: обход завершен, финиш не достигнут") + self.auto_running = False + return self.root.after(50, self.auto_step_loop) + return + + if self.robot.текущая_ячейка is target: + del self.auto_target + + self.draw() + self.root.after(300, self.auto_step_loop) + + + def handle_cell_action(self): + cell = self.robot.текущая_ячейка + + if cell.тип_ячейки == ТипЯчеекСерверов.Терминал: + self.robot.Терминал() + self.write_log("Авто: Терминал -> Код") + return True + + if cell.тип_ячейки == ТипЯчеекСерверов.Код: + self.robot.Код() + self.write_log("Авто: Код -> Развернуто") + return True + + return False + + def finish_check(self): + if self.robot.текущая_ячейка.тип_ячейки != ТипЯчеекСерверов.Финиш: + self.show_fail() + return + + for row in self.lab.ячейки: + for cell in row: + if cell.тип_ячейки in ( + ТипЯчеекСерверов.Код, + ТипЯчеекСерверов.Терминал, + ): + self.show_fail() + return + + self.show_success() + + def show_success(self): + messagebox.showinfo( + "Результат", + "успешный успех" + ) + self.root.destroy() + + def show_fail(self): + messagebox.showwarning( + "Результат", + "робот еще не доделал все" + ) + + def write_log(self, text): + self.log.config(state="normal") + self.log.insert(tk.END, text + "\n") + self.log.see(tk.END) + self.log.config(state="disabled") + + def step(self, action): + before = self.robot.текущая_ячейка + result = action() + after = self.robot.текущая_ячейка + + if result is None: + self.write_log("Действие невозможно") + else: + self.write_log(f"{action.__name__}: {before} -> {after}") + + if self.robot.текущая_ячейка.тип_ячейки == ТипЯчеекСерверов.Финиш: + self.finish_check() + + self.draw() + + def _setup_demo_map(self): + data = [ + [14, 6, 3, 4, 1], + [3, 0, 6, 4, 6], + [6, 0, 6, 6, 3], + [1, 0, 4, 4, 1], + [4, 6, 3, 4, 1], + [5, 0, 1, 3, 6], + ] + + for y in range(self.lab.длина): + for x in range(self.lab.ширина): + v = data[y][x] + has_robot = v == 14 + cell_type = ТипЯчеекСерверов(v if v != 14 else 6) + cell = self.lab.ячейки[y][x] + cell.тип_ячейки = cell_type + cell.ячейка_робота = has_robot + + def draw(self): + self.canvas.delete("all") + h = self.lab.длина + w = self.lab.ширина + + colors = { + ТипЯчеекСерверов.Сервер: "#B3B3B3", + ТипЯчеекСерверов.Терминал: "#D4DDF1", + ТипЯчеекСерверов.Развернуто: "#C9E2CD", + ТипЯчеекСерверов.Код: "#F6D6A1", + ТипЯчеекСерверов.Баг: "#EBACAB", + ТипЯчеекСерверов.Финиш: "#896487", + ТипЯчеекСерверов.Сеть: "#F9F0EE", + } + + for y in range(h): + for x in range(w): + cell = self.lab.ячейки[y][x] + gui_y = (h - 1 - y) * self.cell_size + gui_x = x * self.cell_size + + color = colors[cell.тип_ячейки] + self.canvas.create_rectangle( + gui_x, + gui_y, + gui_x + self.cell_size, + gui_y + self.cell_size, + fill=color, + outline="white", + ) + + if cell.ячейка_робота: + self.canvas.create_text( + gui_x + 30, + gui_y + 30, + font= ("Arial", 40), + text="🤖", + ) + + + +if __name__ == "__main__": + root = tk.Tk() + DevOpsApp(root) + root.mainloop() \ No newline at end of file diff --git "a/5030102_30202/\320\235\320\260\320\267\320\260\321\200\320\276\320\262\320\260 \320\220\320\275\320\260\321\201\321\202\320\260\321\201\320\270\321\217 \320\224\320\265\320\275\320\270\321\201\320\276\320\262\320\275\320\260/main2.py" "b/5030102_30202/\320\235\320\260\320\267\320\260\321\200\320\276\320\262\320\260 \320\220\320\275\320\260\321\201\321\202\320\260\321\201\320\270\321\217 \320\224\320\265\320\275\320\270\321\201\320\276\320\262\320\275\320\260/main2.py" new file mode 100644 index 0000000..dfe3bf2 --- /dev/null +++ "b/5030102_30202/\320\235\320\260\320\267\320\260\321\200\320\276\320\262\320\260 \320\220\320\275\320\260\321\201\321\202\320\260\321\201\320\270\321\217 \320\224\320\265\320\275\320\270\321\201\320\276\320\262\320\275\320\260/main2.py" @@ -0,0 +1,723 @@ +import streamlit as st +import yaml +from enum import Enum + + +class ТипНаправленийDevOpsНапр(Enum): + ДеплойВперёд = "ДеплойВперёд" + ОткатНазад = "ОткатНазад" + ВлевоСеть = "ВлевоСеть" + ВправоСеть = "ВправоСеть" + ДиагDevСЗ = "ДиагDevСЗ" + ДиагDevЮВ = "ДиагDevЮВ" + + +class ТипЯчеекСерверов(Enum): + Сервер = "Сервер" + Терминал = "Терминал" + Развернуто = "Развернуто" + Код = "Код" + Баг = "Баг" + Финиш = "Финиш" + Сеть = "Сеть" + + +class ЯчейкаРоботПрограммист: + def __init__(self, тип_ячейки=None, ячейка_робота=False, x=0, y=0): + self.ячейка_робота = ячейка_робота + self.тип_ячейки = тип_ячейки + self.x = x + self.y = y + + +class ЛабиринтРоботПрограммист: + def __init__(self, ширина=5, длина=6): + self.ширина = ширина + self.длина = длина + self.ячейки = [] + self.создать_демо_лабиринт() + + def ПолучитьСоседнююЯчейку(self, текущая_ячейка, направление_поиска): + if текущая_ячейка is None or not self.ячейки: + return None + + x, y = текущая_ячейка.x, текущая_ячейка.y + + if направление_поиска == ТипНаправленийDevOpsНапр.ДеплойВперёд: + dx, dy = (0, 1) + elif направление_поиска == ТипНаправленийDevOpsНапр.ОткатНазад: + dx, dy = (0, -1) + elif направление_поиска == ТипНаправленийDevOpsНапр.ВлевоСеть: + dx, dy = (-1, 0) + elif направление_поиска == ТипНаправленийDevOpsНапр.ВправоСеть: + dx, dy = (1, 0) + elif направление_поиска == ТипНаправленийDevOpsНапр.ДиагDevСЗ: + dx, dy = (-1, 1) + elif направление_поиска == ТипНаправленийDevOpsНапр.ДиагDevЮВ: + dx, dy = (1, -1) + else: + return None + + nx, ny = x + dx, y + dy + + if not (0 <= nx < self.ширина and 0 <= ny < self.длина): + return None + + соседняя = self.ячейки[ny][nx] + + if соседняя.тип_ячейки in (ТипЯчеекСерверов.Сервер, ТипЯчеекСерверов.Баг): + return None + + return соседняя + + def ПолучитьИтератор(self): + if not self.ячейки: + return iter(()) + + x = 0 + y = self.длина - 1 + direction = 1 + + while True: + yield self.ячейки[y][x] + + if direction == 1: + if x < self.ширина - 1: + x += 1 + else: + if y == 0: + break + y -= 1 + direction = -1 + else: + if x > 0: + x -= 1 + else: + if y == 0: + break + y -= 1 + direction = 1 + + def создать_демо_лабиринт(self): + data = [ + [14, 6, 3, 4, 1], + [3, 0, 6, 4, 6], + [6, 0, 6, 6, 2], + [1, 0, 4, 4, 1], + [4, 6, 3, 4, 2], + [5, 0, 1, 3, 6], + ] + + self.ячейки = [] + + for y in range(self.длина): + row = [] + for x in range(self.ширина): + cell_type_val = data[y][x] + has_robot = cell_type_val == 14 + if has_robot: + cell_type_val = 6 + + cell_type_map = { + 0: ТипЯчеекСерверов.Сервер, + 1: ТипЯчеекСерверов.Терминал, + 2: ТипЯчеекСерверов.Развернуто, + 3: ТипЯчеекСерверов.Код, + 4: ТипЯчеекСерверов.Баг, + 5: ТипЯчеекСерверов.Финиш, + 6: ТипЯчеекСерверов.Сеть + } + + cell_type = cell_type_map.get(cell_type_val, ТипЯчеекСерверов.Сеть) + row.append(ЯчейкаРоботПрограммист(тип_ячейки=cell_type, ячейка_робота=has_robot, x=x, y=y)) + self.ячейки.append(row) + + +class РоботПрограммист: + def __init__(self, лабиринт): + self.лабиринт = лабиринт + self.деплоэнергия = None + self.откатный = None + self.шаги = 0 + + for row in self.лабиринт.ячейки: + for cell in row: + if cell.ячейка_робота: + self.текущая_ячейка = cell + return + + def _переместить_робота(self, направление): + if self.текущая_ячейка is None: + return None + + цель = self.лабиринт.ПолучитьСоседнююЯчейку(self.текущая_ячейка, направление) + + if цель is None: + return None + + self.текущая_ячейка.ячейка_робота = False + цель.ячейка_робота = True + self.текущая_ячейка = цель + self.шаги += 1 + + return цель + + def Деплойнуть(self): + return self._переместить_робота(ТипНаправленийDevOpsНапр.ДеплойВперёд) + + def Откатнуть(self): + return self._переместить_робота(ТипНаправленийDevOpsНапр.ОткатНазад) + + def СдвинутьВлево(self): + return self._переместить_робота(ТипНаправленийDevOpsНапр.ВлевоСеть) + + def СдвинутьВправо(self): + return self._переместить_робота(ТипНаправленийDevOpsНапр.ВправоСеть) + + def ПоднятьКонтейнер(self): + return self._переместить_робота(ТипНаправленийDevOpsНапр.ДиагDevСЗ) + + def ОпуститьКонтейнер(self): + return self._переместить_робота(ТипНаправленийDevOpsНапр.ДиагDevЮВ) + + def Код(self): + if self.текущая_ячейка is None: + return None + + if self.текущая_ячейка.тип_ячейки == ТипЯчеекСерверов.Код: + self.текущая_ячейка.тип_ячейки = ТипЯчеекСерверов.Развернуто + return True + return False + + def Терминал(self): + if self.текущая_ячейка is None: + return None + + if self.текущая_ячейка.тип_ячейки == ТипЯчеекСерверов.Терминал: + self.текущая_ячейка.тип_ячейки = ТипЯчеекСерверов.Код + return True + return False + + def обработать_текущую_ячейку(self): + if self.текущая_ячейка is None: + return False + + if self.текущая_ячейка.тип_ячейки == ТипЯчеекСерверов.Терминал: + self.Терминал() + self.Код() + return True + + if self.текущая_ячейка.тип_ячейки == ТипЯчеекСерверов.Код: + self.Код() + return True + + return False + + def проверить_цель(self): + if self.текущая_ячейка is None: + return False + + for row in self.лабиринт.ячейки: + for cell in row: + if cell.тип_ячейки in [ТипЯчеекСерверов.Код, ТипЯчеекСерверов.Терминал]: + return False + + return self.текущая_ячейка.тип_ячейки == ТипЯчеекСерверов.Финиш + + +def init_session_state(): + if 'robot' not in st.session_state: + maze = ЛабиринтРоботПрограммист(ширина=5, длина=6) + st.session_state.robot = РоботПрограммист(maze) + st.session_state.iterator = None + st.session_state.auto_mode = False + st.session_state.auto_targets = [] + st.session_state.current_target_index = 0 + st.session_state.logs = ["робот готов к работе"] + st.session_state.show_success = False + st.session_state.show_fail = False + + +def get_cell_color(cell_type): + colors = { + "Сервер": "#B3B3B3", + "Терминал": "#D4DDF1", + "Развернуто": "#C9E2CD", + "Код": "#F6D6A1", + "Баг": "#EBACAB", + "Финиш": "#896487", + "Сеть": "#F9F0EE", + } + return colors.get(cell_type, "#FFFFFF") + + +def render_grid(): + robot = st.session_state.robot + maze = robot.лабиринт + + for y in range(maze.длина - 1, -1, -1): + cols = st.columns(maze.ширина + 1) + + for x in range(maze.ширина): + cell = maze.ячейки[y][x] + cell_type = cell.тип_ячейки.value if cell.тип_ячейки else "Сеть" + color = get_cell_color(cell_type) + + with cols[x + 1]: + border_color = "#85A1D2" if cell.ячейка_робота else "#848484" + border_width = "3px" if cell.ячейка_робота else "1px" + + st.markdown(f""" +