习题:基于gym环境构建迷宫世界

迷宫世界

      • 效果演示
      • 环境测试代码
      • 测试代码的调用
      • 环境构建代码

效果演示

迷宫世界的最终演示效果如图。
黑色为墙不可通行,白色为道路可通行,黄色为出口。

习题:基于gym环境构建迷宫世界_第1张图片

环境测试代码

# 环境测试
import gym
import random
import time
env=gym.make('MazeWorld-v0')
env.reset()
reward=0
while True:
        action = env.actions[int(random.random()*len(env.actions))]
        next_state,r,is_terminal,info = env.step(action)
        env.render()
        reward += r
        if is_terminal == True:
            print("reward:",reward)
            break
        time.sleep(0.2)

测试代码的调用

方法请参考我的上一篇博客链接: 建立自己的gym环境并调用.

环境构建代码

import gym
from numpy import random
import time

class MazeEnv(gym.Env):
    def __init__(self):
        self.viewer = None
        # 状态空间
        self.states = [1, 2, 3, 4, 5,
                       6, 7, 8, 9, 10,
                       11, 12, 13, 14, 15,
                       16, 17, 18, 19, 20,
                       21, 22, 23, 24, 25]
        # 动作空间
        self.actions = ['n', 'e', 's', 'w']
        # 回报函数
        self.rewards = dict()
        self.rewards['10_s'] = 10
        self.rewards['14_e'] = 10
        self.rewards['20_n'] = 10

        # 状态转移概率,用状态_动作的模式存入字典
        self.t = dict()
        self.t['1_s'] = 6
        self.t['1_e'] = 2
        self.t['2_w'] = 1
        self.t['2_s'] = 7
        self.t['2_e'] = 3
        self.t['3_w'] = 2
        self.t['3_s'] = 8
        self.t['5_s'] = 10
        self.t['6_n'] = 1
        self.t['6_e'] = 7
        self.t['7_w'] = 6
        self.t['7_n'] = 2
        self.t['7_e'] = 8
        self.t['8_w'] = 7
        self.t['8_n'] = 3
        self.t['8_s'] = 13
        self.t['10_n'] = 5
        self.t['10_s'] = 15
        self.t['13_n'] = 8
        self.t['13_e'] = 14
        self.t['13_s'] = 18
        self.t['14_w'] = 13
        self.t['14_e'] = 15
        self.t['14_s'] = 19
        self.t['16_e'] = 17
        self.t['16_s'] = 21
        self.t['17_w'] = 16
        self.t['17_e'] = 18
        self.t['17_s'] = 22
        self.t['18_w'] = 17
        self.t['18_e'] = 19
        self.t['18_n'] = 13
        self.t['19_w'] = 18
        self.t['19_n'] = 14
        self.t['19_e'] = 20
        self.t['20_w'] = 19
        self.t['20_n'] = 15
        self.t['21_n'] = 16
        self.t['21_e'] = 22
        self.t['22_w'] = 21
        self.t['22_n'] = 17

    def step(self, action):
        #系统当前状态
        state = self.state
        #将状态和动作组成的字典的键值
        key = "%d_%s" % (state, action)
        #状态转移
        #self.t是状态转移表,如果键值在表中,则通过表选出下一状态
        if key in self.t:
            next_state = self.t[key]

        # 动作的下一刻是黑色墙壁的不在状态转移表中
        #如果键值不在状态转移表中,则维持当前状态
        else:
            next_state = state
        self.state = next_state

        #出口判断,初值为FALSE
        is_terminal = False
        #self.rewards为回报函数表,即下一状态为出口的的状态和动作
        #如果键值在回报函数表里,则出口判断函数is_terminal = True,奖励为10
        if key in self.rewards:
            r = 10
            is_terminal = True
        #如果键值不在回报函数里,则出口判断函数保持false值,奖励为-1
        else:
            r = -1
        return next_state, r, is_terminal, {}

    def reset(self):
        s = [4, 9, 11, 12, 23, 24, 25]
        self.state = self.states[int(random.random() * (len(self.states) ))]
        while self.state in s:
            self.state = self.states[int(random.random() * (len(self.states) - 1))]
        return self.state

    def close(self):
        if self.viewer:
            self.viewer.close()
            self.viewer = None

    def render(self, mode="human"):
        from gym.envs.classic_control import rendering
        width = 60
        height = 40
        edge_x = 0
        edge_y = 0
        if self.viewer is None:
            self.viewer = rendering.Viewer(300, 200)

        # 右下角                 用黑色表示墙
        self.viewer.draw_polygon([(0, 0), (0, height), (width, height), (width, 0)], filled=True,
                                 color=(0, 0, 0)).add_attr(
            rendering.Transform((edge_x + width * 2, edge_y + height * 1)))
        self.viewer.draw_polygon([(0, 0), (0, height), (width, height), (width, 0)], filled=True,
                                 color=(0, 0, 0)).add_attr(
            rendering.Transform((edge_x + width * 3, edge_y + height * 1)))
        self.viewer.draw_polygon([(0, 0), (0, height), (width, height), (width, 0)], filled=True,
                                 color=(0, 0, 0)).add_attr(
            rendering.Transform((edge_x + width * 4, edge_y + height * 1)))
        # 左边
        self.viewer.draw_polygon([(0, 0), (0, height), (width, height), (width, 0)], filled=True,
                                 color=(0, 0, 0)).add_attr(rendering.Transform((edge_x, edge_y + height * 3)))
        self.viewer.draw_polygon([(0, 0), (0, height), (width, height), (width, 0)], filled=True,
                                 color=(0, 0, 0)).add_attr(
            rendering.Transform((edge_x + width * 1, edge_y + height * 3)))
        # 上边
        self.viewer.draw_polygon([(0, 0), (0, height), (width, height), (width, 0)], filled=True,
                                 color=(0, 0, 0)).add_attr(
            rendering.Transform((edge_x + width * 3, edge_y + height * 4)))
        self.viewer.draw_polygon([(0, 0), (0, height), (width, height), (width, 0)], filled=True,
                                 color=(0, 0, 0)).add_attr(
            rendering.Transform((edge_x + width * 3, edge_y + height * 5)))
        # 出口,用黄色表示出口
        self.viewer.draw_polygon([(0, 0), (0, height), (width, height), (width, 0)], filled=True,
                                 color=(1, 0.9, 0)).add_attr(
            rendering.Transform((edge_x + width * 4, edge_y + height * 3)))
        # 画网格
        for i in range(1, 7):
            self.viewer.draw_line((edge_x, edge_y + height * i), (edge_x + 5 * width, edge_y + height * i))  # 横线
            self.viewer.draw_line((edge_x + width * (i - 1), edge_y + height),
                                  (edge_x + width * (i - 1), edge_y + height * 6))  # 竖线

        # 人的像素位置
        self.x = [edge_x + width * 0.5, edge_x + width * 1.5, edge_x + width * 2.5, 0, edge_x + width * 4.5,
                  edge_x + width * 0.5, edge_x + width * 1.5, edge_x + width * 2.5, 0, edge_x + width * 4.5,
                  0, 0, edge_x + width * 2.5, edge_x + width * 3.5, edge_x + width * 4.5,
                  edge_x + width * 0.5, edge_x + width * 1.5, edge_x + width * 2.5, edge_x + width * 3.5,
                  edge_x + width * 4.5,
                  edge_x + width * 0.5, edge_x + width * 1.5, 0, 0, 0]

        self.y = [edge_y + height * 5.5, edge_y + height * 5.5, edge_y + height * 5.5, 0, edge_y + height * 5.5,
                  edge_y + height * 4.5, edge_y + height * 4.5, edge_y + height * 4.5, 0, edge_y + height * 4.5,
                  0, 0, edge_y + height * 3.5, edge_y + height * 3.5, edge_y + height * 3.5,
                  edge_y + height * 2.5, edge_y + height * 2.5, edge_y + height * 2.5, edge_y + height * 2.5,
                  edge_y + height * 2.5,
                  edge_y + height * 1.5, edge_y + height * 1.5, 0, 0, 0]
        # 用圆表示人
        # self.viewer.draw_circle(18,color=(0.8,0.6,0.4)).add_attr(rendering.Transform(translation=(edge_x+width/2,edge_y+height*1.5)))
        self.viewer.draw_circle(18, color=(0.8, 0.6, 0.4)).add_attr(
            rendering.Transform(translation=(self.x[self.state - 1], self.y[self.state - 1])))

        return self.viewer.render(return_rgb_array=mode == 'rgb_array')




你可能感兴趣的:(强化学习,pycharm,深度学习,机器学习)