Advertisement
pavel_777

simple_maze_env.py

Sep 29th, 2024
44
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.49 KB | None | 0 0
  1. import gymnasium as gym
  2. from gymnasium import spaces
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5.  
  6.  
  7. class MazeEnv(gym.Env):
  8.     def __init__(self, pause=0.1):
  9.         super(MazeEnv, self).__init__()
  10.  
  11.         self.pause = pause  # for render
  12.         # Размеры лабиринта (5x5)
  13.         self.maze_size = (5, 5)
  14.  
  15.         # Определяем перегородки (стены) между клетками
  16.         self.walls = {
  17.             ((1, 0), (1, 1)),
  18.             ((2, 0), (3, 0)),
  19.             ((4, 0), (4, 1)),
  20.             ((1, 1), (1, 2)),
  21.             ((2, 1), (2, 2)),
  22.             ((2, 1), (3, 1)),
  23.             ((3, 1), (3, 2)),
  24.             ((0, 2), (0, 3)),
  25.             ((1, 2), (1, 3)),
  26.             ((2, 2), (2, 3)),
  27.             ((3, 2), (3, 3)),
  28.             ((0, 3), (1, 3)),
  29.             ((2, 3), (2, 4)),
  30.             ((3, 3), (3, 4)),
  31.             ((4, 3), (4, 4)),
  32.         }
  33.  
  34.         self.start_pos = np.array([0, 0])
  35.         self.goal_pos = np.array([4, 4])
  36.  
  37.         # Действия: вверх (0), вниз (1), влево (2), вправо (3)
  38.         self.action_space = spaces.Discrete(4)
  39.  
  40.         # Состояние: координаты агента (y, x)
  41.         self.observation_space = spaces.Box(low=0, high=4, shape=(2,), dtype=np.int32)
  42.  
  43.         # Инициализация позиции агента
  44.         self.agent_pos = self.start_pos.copy()
  45.  
  46.         # Создаём фигуру и оси для рендеринга (инициализация один раз)
  47.         self.fig, self.ax = plt.subplots()
  48.         self.render_initialized = False
  49.  
  50.     def reset(self):
  51.         # Сброс позиции агента на старт
  52.         self.agent_pos = self.start_pos.copy()
  53.         return self.agent_pos
  54.  
  55.     def step(self, action):
  56.         # Сохраним старую позицию
  57.         old_pos = self.agent_pos.copy()
  58.  
  59.         # Определяем новую позицию
  60.         if action == 0:  # Вниз - Move south (down)
  61.             new_pos = [min(self.agent_pos[0] + 1, 4), self.agent_pos[1]]
  62.         elif action == 1:  # Вверх - Move north (up)
  63.             new_pos = [max(self.agent_pos[0] - 1, 0), self.agent_pos[1]]
  64.         elif action == 2:  # Вправо - Move east (right)
  65.             new_pos = [self.agent_pos[0], min(self.agent_pos[1] + 1, 4)]
  66.         elif action == 3:  # Влево - Move west (left)
  67.             new_pos = [self.agent_pos[0], max(self.agent_pos[1] - 1, 0)]
  68.         else:
  69.             new_pos = old_pos  # Неверное действие
  70.  
  71.         # Проверяем наличие стены между клетками
  72.         if not self.is_wall_between(old_pos, new_pos):
  73.             self.agent_pos = np.array(new_pos)
  74.  
  75.         # Проверка завершения: достигли цели или нет
  76.         done = np.array_equal(self.agent_pos, self.goal_pos)
  77.  
  78.         # Вознаграждение: 1 за достижение цели, -0.004 в других случаях
  79.         reward = 1 if done else -0.004
  80.  
  81.         return self.agent_pos, reward, done, {}
  82.  
  83.     def is_wall_between(self, pos1, pos2):
  84.         """Проверка наличия стены между двумя клетками"""
  85.         return (tuple(pos1), tuple(pos2)) in self.walls or (
  86.             tuple(pos2),
  87.             tuple(pos1),
  88.         ) in self.walls
  89.  
  90.     def save_settings_axis(self):
  91.         self.xlim = self.ax.get_xlim()
  92.         self.ylim = self.ax.get_ylim()
  93.         self.aspect = self.ax.get_aspect()
  94.  
  95.     def set_settings_axis(self):
  96.         self.ax.set_xlim(self.xlim)
  97.         self.ax.set_ylim(self.ylim)
  98.         self.ax.set_aspect(self.aspect)
  99.  
  100.     def render(self, mode="human"):
  101.         # Если рендер не был инициализирован, создаем оси и отображаем лабиринт
  102.         if not self.render_initialized:
  103.             self.ax.set_xlim(0, self.maze_size[1])
  104.             self.ax.set_ylim(0, self.maze_size[0])
  105.             self.ax.set_aspect("equal")
  106.             self.ax.invert_yaxis()  # Инвертируем ось Y, чтобы (0,0) был в верхнем левом углу
  107.             self.save_settings_axis()
  108.             self.render_initialized = True
  109.  
  110.         # Очищаем старые объекты
  111.         self.ax.clear()
  112.         self.set_settings_axis()
  113.  
  114.         # Отображаем клетки лабиринта
  115.         for y in range(self.maze_size[0]):
  116.             for x in range(self.maze_size[1]):
  117.                 self.ax.add_patch(
  118.                     plt.Rectangle((x, y), 1, 1, fill=None, edgecolor="yellow")
  119.                 )
  120.  
  121.         # Отображаем стены
  122.         for p1, p2 in self.walls:
  123.             y1, x1 = p1
  124.             y2, x2 = p2
  125.             # print('y1, x1', y1, x1, 'y2, x2', y2, x2)
  126.             if y1 == y2:  # Вертикальная стена
  127.                 self.ax.plot([x2, x2], [y1, y2 + 1], color="black", linewidth=3)
  128.             else:  # Горизонтальная стена
  129.                 self.ax.plot([x1, x2 + 1], [y2, y2], color="black", linewidth=3)
  130.  
  131.         # Отображаем агента и цель
  132.         self.ax.scatter(
  133.             self.agent_pos[1] + 0.5,
  134.             self.agent_pos[0] + 0.5,
  135.             c="red",
  136.             marker="o",
  137.             s=200,
  138.             label="Agent",
  139.         )
  140.         self.ax.scatter(
  141.             self.goal_pos[1] + 0.5,
  142.             self.goal_pos[0] + 0.5,
  143.             c="green",
  144.             marker="*",
  145.             s=200,
  146.             label="Goal",
  147.         )
  148.  
  149.         # Обновляем изображение
  150.         plt.draw()
  151.         plt.pause(self.pause)  # Пауза для визуализации шагов
  152.  
  153.     def close(self):
  154.         # Закрываем окно рендеринга при завершении
  155.         plt.close(self.fig)
  156.  
  157.  
  158. def main():
  159.     # Пример использования среды и анимации
  160.     # env = MazeEnv()
  161.     env = MazeEnv(0.01)
  162.     obs = env.reset()
  163.     env.render()
  164.  
  165.     # Запланируем шаги агента до достижения цели
  166.     # while True:
  167.     for _ in range(200):
  168.         action = env.action_space.sample()  # Выбираем случайное действие
  169.         obs, reward, done, _ = env.step(action)
  170.         env.render()
  171.         if done:
  172.             print("Goal reached!")
  173.             break
  174.  
  175.     env.close()
  176.  
  177.  
  178. if __name__ == "__main__":
  179.     main()
  180.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement