OpenAI/Tensorflow 自定义游戏环境而不是使用 'gym.make()'
OpenAI/Tensorflow Custom Game Environment Instead of using 'gym.make()'
[简介]
我有一个定制的 Python 游戏,它使用 'w' 's' 键移动和 'space' 键射击作为输入。我找到了一种强化学习算法,我想尝试将其应用到游戏中。
然而,RL 算法使用 openAI 的 atari 游戏作为环境,命令为 'gym.make (env_name)'。我在 Windows OS 上,所以无法对代码进行实验,因为 gym[atari] 对我不起作用。
class Agent:
def __init__(self, env_name, training, render=False, use_logging=True):
self.env = gym.make(env_name)
[问题]
在这个 class 中,我可以使用另一个命令来代替 'gym.make()' 来实施 RL 算法来训练我的定制游戏,还是制作我自己的健身房环境的唯一选择?
'pygame.surfarray.array2d()' return 会类似于 'gym.make()' 吗?
如果需要其他信息,请告诉我,我是 gym 和 tensorflow 的新手,所以我的理解可能有缺陷。
[编辑]
我使用函数制作游戏,如果我要将游戏转换为健身房环境,唯一的选择是将函数转换为 classes 吗?作为我的代码的示例,这里是游戏循环:(我不能 post 整个代码,因为它是年末成绩的受控评估,因此希望避免任何剽窃问题)
def game_loop():
global pause
x = (display_width * 0.08)
y = (display_height * 0.2)
x_change = 0
y_change = 0
blob_speed = 2
velocity = [2, 2]
score = 0
lives = 3
pos_x = display_width/1.2
pos_y = display_height/1.2
previous_time = pygame.time.get_ticks()
previous_time2 = pygame.time.get_ticks()
gameExit = False
while not gameExit:
for event in pygame.event.get():#monitors hardware movement/ clicks
if event.type == pygame.QUIT:
pygame.quit()
quit()
pos_x += velocity[0]
pos_y += velocity[1]
if pos_x + blob_width > display_width or pos_x < 601:
velocity[0] = -velocity[0]
if pos_y + blob_height > display_height or pos_y < 0:
velocity[1] = -velocity[1]
for b in range(len(bullets2)):
bullets2[b][0] -= 6
for bullet in bullets2:
if bullet[0] < 0:
bullets2.remove(bullet)
current_time2 = pygame.time.get_ticks()
#ready to fire when 500 ms have passed.
if current_time2 - previous_time2 > 500:
previous_time2 = current_time2
bullets2.append([pos_x+25, pos_y+24])
keys = pygame.key.get_pressed()
for b in range(len(bullets)):
bullets[b][0] += 6
for bullet in bullets:
if bullet[0] > 1005:
bullets.remove(bullet)
if keys[pygame.K_SPACE]:
current_time = pygame.time.get_ticks()
#ready to fire when 500 ms have passed.
if current_time - previous_time > 600:
previous_time = current_time
bullets.append([x+25, y+24])
if x < 0:
x = 0
if keys[pygame.K_a]:
x_change = -blob_speed
if x > 401 - blob_width:
x = 401 - blob_width
if keys[pygame.K_d]:
x_change = blob_speed
if keys[pygame.K_p]:
pause = True
paused()
if keys[pygame.K_a] and keys[pygame.K_d]:
x_change = 0
if not keys[pygame.K_a] and not keys[pygame.K_d]:
x_change = 0
if y < 0:
y = 0
if keys[pygame.K_w]:
y_change = -blob_speed
if y > display_height - blob_height:
y = display_height - blob_height
if keys[pygame.K_s]:
y_change = blob_speed
if keys[pygame.K_w] and keys[pygame.K_s]:
y_change = 0
if not keys[pygame.K_w] and not keys[pygame.K_s]:
y_change = 0
#print(event)
# Reset x and y to new position
x += x_change
y += y_change
gameDisplay.fill(blue) #changes background surface
bullets_hit(score)
player_lives(lives)
pygame.draw.line(gameDisplay, black, (601, display_height), (601, 0), 3)
pygame.draw.line(gameDisplay, black, (401, display_height), (401, 0), 3)
blob(pos_x, pos_y)
blob(x, y)
for bullet in bullets:
gameDisplay.blit(bulletpicture, pygame.Rect(bullet[0], bullet[1], 0, 0))
if bullet[0] > pos_x and bullet[0] < pos_x + blob_width:
if bullet[1] > pos_y and bullet[1] < pos_y + blob_height or bullet[1] + bullet_height > pos_y and bullet[1] + bullet_height < pos_y + blob_height:
bullets.remove(bullet)
score+=1
for bullet in bullets2:
gameDisplay.blit(bulletpicture, pygame.Rect(bullet[0], bullet[1], 0, 0))
if bullet[0] + bullet_width < x + blob_width and bullet[0] > x:
if bullet[1] > y and bullet[1] < y + blob_height or bullet[1] + bullet_height > y and bullet[1] + bullet_height < y + blob_height:
bullets2.remove(bullet)
lives-=1
if lives == 0:
game_over()
pygame.display.update() #update screen
clock.tick(120)#moves frame on (fps in parameters)
最好的选择确实是简单地实现您自己的自定义环境。您可以在 gym repository on github 中找到一些关于实现自定义环境的说明。
其中一些说明可能仅在您还打算与他人共享您的环境时才相关,如果您只是想自己使用它则不是那么重要。我怀疑对你来说最重要的部分(假设你只是想自己而不是作为其他人可以使用的包上传)是(从上面的link复制) :
gym-foo/gym_foo/envs/foo_env.py
应该类似于:
import gym
from gym import error, spaces, utils
from gym.utils import seeding
class FooEnv(gym.Env):
metadata = {'render.modes': ['human']}
def __init__(self):
...
def step(self, action):
...
def reset(self):
...
def render(self, mode='human', close=False):
...
gym-foo/gym_foo/__init__.py
应该有:
from gym.envs.registration import register
register(
id='foo-v0',
entry_point='gym_foo.envs:FooEnv',
)
register(
id='foo-extrahard-v0',
entry_point='gym_foo.envs:FooExtraHardEnv',
)
gym-foo/gym_foo/envs/__init__.py
应该有:
from gym_foo.envs.foo_env import FooEnv
from gym_foo.envs.foo_extrahard_env import FooExtraHardEnv
第一块是环境本身的实现。如果您已经实现了一个游戏,您希望不必在那里实现很多。 gym.Env
的这个 subclass 应该只是 "wrapper" 围绕 already-existing 游戏,形成期望 gym
API 的 RL 代理之间的桥梁(step()
、reset()
等)和游戏本身。您可以从 gym
中的 atari_env
实现中获取灵感,它本身也只是 already-existing Atari 游戏的包装器,并不直接包含这些游戏的完整游戏逻辑。
需要第二个和第三个块以确保您可以使用 gym.make()
函数开始创建自定义环境的实例。
您确实需要制作一个以 gym.Env
class 作为基础 class 的 class,并确保您实现了它的所有重要功能(例如step
和 reset
)。也就是说,假设您想要使用已经实现的 RL 算法并期望这些函数存在。当然,另一种方法是将 gym
完全从 window 中删除并从头开始实现所有内容,但您很可能最终只会做更多的工作并以类似的 API 无论如何。
[简介] 我有一个定制的 Python 游戏,它使用 'w' 's' 键移动和 'space' 键射击作为输入。我找到了一种强化学习算法,我想尝试将其应用到游戏中。
然而,RL 算法使用 openAI 的 atari 游戏作为环境,命令为 'gym.make (env_name)'。我在 Windows OS 上,所以无法对代码进行实验,因为 gym[atari] 对我不起作用。
class Agent:
def __init__(self, env_name, training, render=False, use_logging=True):
self.env = gym.make(env_name)
[问题] 在这个 class 中,我可以使用另一个命令来代替 'gym.make()' 来实施 RL 算法来训练我的定制游戏,还是制作我自己的健身房环境的唯一选择? 'pygame.surfarray.array2d()' return 会类似于 'gym.make()' 吗?
如果需要其他信息,请告诉我,我是 gym 和 tensorflow 的新手,所以我的理解可能有缺陷。
[编辑] 我使用函数制作游戏,如果我要将游戏转换为健身房环境,唯一的选择是将函数转换为 classes 吗?作为我的代码的示例,这里是游戏循环:(我不能 post 整个代码,因为它是年末成绩的受控评估,因此希望避免任何剽窃问题)
def game_loop():
global pause
x = (display_width * 0.08)
y = (display_height * 0.2)
x_change = 0
y_change = 0
blob_speed = 2
velocity = [2, 2]
score = 0
lives = 3
pos_x = display_width/1.2
pos_y = display_height/1.2
previous_time = pygame.time.get_ticks()
previous_time2 = pygame.time.get_ticks()
gameExit = False
while not gameExit:
for event in pygame.event.get():#monitors hardware movement/ clicks
if event.type == pygame.QUIT:
pygame.quit()
quit()
pos_x += velocity[0]
pos_y += velocity[1]
if pos_x + blob_width > display_width or pos_x < 601:
velocity[0] = -velocity[0]
if pos_y + blob_height > display_height or pos_y < 0:
velocity[1] = -velocity[1]
for b in range(len(bullets2)):
bullets2[b][0] -= 6
for bullet in bullets2:
if bullet[0] < 0:
bullets2.remove(bullet)
current_time2 = pygame.time.get_ticks()
#ready to fire when 500 ms have passed.
if current_time2 - previous_time2 > 500:
previous_time2 = current_time2
bullets2.append([pos_x+25, pos_y+24])
keys = pygame.key.get_pressed()
for b in range(len(bullets)):
bullets[b][0] += 6
for bullet in bullets:
if bullet[0] > 1005:
bullets.remove(bullet)
if keys[pygame.K_SPACE]:
current_time = pygame.time.get_ticks()
#ready to fire when 500 ms have passed.
if current_time - previous_time > 600:
previous_time = current_time
bullets.append([x+25, y+24])
if x < 0:
x = 0
if keys[pygame.K_a]:
x_change = -blob_speed
if x > 401 - blob_width:
x = 401 - blob_width
if keys[pygame.K_d]:
x_change = blob_speed
if keys[pygame.K_p]:
pause = True
paused()
if keys[pygame.K_a] and keys[pygame.K_d]:
x_change = 0
if not keys[pygame.K_a] and not keys[pygame.K_d]:
x_change = 0
if y < 0:
y = 0
if keys[pygame.K_w]:
y_change = -blob_speed
if y > display_height - blob_height:
y = display_height - blob_height
if keys[pygame.K_s]:
y_change = blob_speed
if keys[pygame.K_w] and keys[pygame.K_s]:
y_change = 0
if not keys[pygame.K_w] and not keys[pygame.K_s]:
y_change = 0
#print(event)
# Reset x and y to new position
x += x_change
y += y_change
gameDisplay.fill(blue) #changes background surface
bullets_hit(score)
player_lives(lives)
pygame.draw.line(gameDisplay, black, (601, display_height), (601, 0), 3)
pygame.draw.line(gameDisplay, black, (401, display_height), (401, 0), 3)
blob(pos_x, pos_y)
blob(x, y)
for bullet in bullets:
gameDisplay.blit(bulletpicture, pygame.Rect(bullet[0], bullet[1], 0, 0))
if bullet[0] > pos_x and bullet[0] < pos_x + blob_width:
if bullet[1] > pos_y and bullet[1] < pos_y + blob_height or bullet[1] + bullet_height > pos_y and bullet[1] + bullet_height < pos_y + blob_height:
bullets.remove(bullet)
score+=1
for bullet in bullets2:
gameDisplay.blit(bulletpicture, pygame.Rect(bullet[0], bullet[1], 0, 0))
if bullet[0] + bullet_width < x + blob_width and bullet[0] > x:
if bullet[1] > y and bullet[1] < y + blob_height or bullet[1] + bullet_height > y and bullet[1] + bullet_height < y + blob_height:
bullets2.remove(bullet)
lives-=1
if lives == 0:
game_over()
pygame.display.update() #update screen
clock.tick(120)#moves frame on (fps in parameters)
最好的选择确实是简单地实现您自己的自定义环境。您可以在 gym repository on github 中找到一些关于实现自定义环境的说明。
其中一些说明可能仅在您还打算与他人共享您的环境时才相关,如果您只是想自己使用它则不是那么重要。我怀疑对你来说最重要的部分(假设你只是想自己而不是作为其他人可以使用的包上传)是(从上面的link复制) :
gym-foo/gym_foo/envs/foo_env.py
应该类似于:
import gym
from gym import error, spaces, utils
from gym.utils import seeding
class FooEnv(gym.Env):
metadata = {'render.modes': ['human']}
def __init__(self):
...
def step(self, action):
...
def reset(self):
...
def render(self, mode='human', close=False):
...
gym-foo/gym_foo/__init__.py
应该有:
from gym.envs.registration import register
register(
id='foo-v0',
entry_point='gym_foo.envs:FooEnv',
)
register(
id='foo-extrahard-v0',
entry_point='gym_foo.envs:FooExtraHardEnv',
)
gym-foo/gym_foo/envs/__init__.py
应该有:
from gym_foo.envs.foo_env import FooEnv
from gym_foo.envs.foo_extrahard_env import FooExtraHardEnv
第一块是环境本身的实现。如果您已经实现了一个游戏,您希望不必在那里实现很多。 gym.Env
的这个 subclass 应该只是 "wrapper" 围绕 already-existing 游戏,形成期望 gym
API 的 RL 代理之间的桥梁(step()
、reset()
等)和游戏本身。您可以从 gym
中的 atari_env
实现中获取灵感,它本身也只是 already-existing Atari 游戏的包装器,并不直接包含这些游戏的完整游戏逻辑。
需要第二个和第三个块以确保您可以使用 gym.make()
函数开始创建自定义环境的实例。
您确实需要制作一个以 gym.Env
class 作为基础 class 的 class,并确保您实现了它的所有重要功能(例如step
和 reset
)。也就是说,假设您想要使用已经实现的 RL 算法并期望这些函数存在。当然,另一种方法是将 gym
完全从 window 中删除并从头开始实现所有内容,但您很可能最终只会做更多的工作并以类似的 API 无论如何。