Training gym files

This commit is contained in:
levdoescode
2022-11-16 01:43:49 -05:00
parent 4b6253d65c
commit 9dd0cb8c8b
15 changed files with 488 additions and 0 deletions

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Matthew Yee-King
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,17 @@
# Goldsmiths openai gym envs
We created some envs for AIs to play in, since we cannot show the original Atari games due to copyright.
To install:
```
pip install -e .
```
To try it out:
```
import gym
env = gym.make('gym_gs:breakwall-v0')
env.reset()
env.step(1)
```

View File

@ -0,0 +1,8 @@
import gym
env = gym.make('gym_gs:breakwall-v0')
env.reset()
print("running ")
for i in range(1000):
if i % 100 == 0: print(i)
env.step(1)
#env.render()

View File

@ -0,0 +1,10 @@
Metadata-Version: 1.0
Name: gym-gs
Version: 0.0.1
Summary: UNKNOWN
Home-page: UNKNOWN
Author: UNKNOWN
Author-email: UNKNOWN
License: UNKNOWN
Description: UNKNOWN
Platform: UNKNOWN

View File

@ -0,0 +1,7 @@
README.md
setup.py
gym_gs.egg-info/PKG-INFO
gym_gs.egg-info/SOURCES.txt
gym_gs.egg-info/dependency_links.txt
gym_gs.egg-info/requires.txt
gym_gs.egg-info/top_level.txt

View File

@ -0,0 +1,14 @@
from gym.envs.registration import register
register(
id='breakwall-v0',
entry_point='gym_gs.envs:BreakWall',
)
register(
id='BreakwallNoFrameskip-v1',
entry_point='gym_gs.envs:BreakWall',
)
# register(
# id='foo-extrahard-v0',
# entry_point='gym_foo.envs:FooExtraHardEnv',
# )

View File

@ -0,0 +1,2 @@
from gym_gs.envs.breakwall_env import BreakWall
#from gym_foo.envs.foo_extrahard_env import FooExtraHardEnv

View File

@ -0,0 +1,399 @@
import gym
from gym import error, spaces, utils
from gym.utils import seeding
import pygame
import random
from random import randint
import numpy as np
import os
def getFilledRect(w,h,r,g,b):
img = np.zeros((h,w,3),dtype=np.uint8)
for x in range(len(img)): # rows
for y in range(len(img[x])): # cols
img[x][y][0] = r # R
img[x][y][1] = g # G
img[x][y][2] = b # B
image = pygame.image.frombuffer(img.tostring(), img.shape[1::-1], "RGB")
return image
# Derives from the "Sprite" class in Pygame
class Ball(pygame.sprite.Sprite):
def __init__(self,screen_width, screen_height):
# Sprite super constructor
super().__init__()
# Init ball variables
self.diameter = 10
self.velocity = [random.choice([-3,-2,2,3]),1]
self.maxSpeed = 6
self.velocity_increment = -0.05
# Load ball image and scale
self.image = getFilledRect(self.diameter, self.diameter, 255, 255, 255)
# Fetch the rectangle object that has the dimensions of the image
self.rect = self.image.get_rect()
# Position the ball in the middle
self.rect.x = screen_width/2
self.rect.y = screen_height/2
# Update ball speed
def update(self):
self.rect.x += self.velocity[0]
self.rect.y += self.velocity[1]
if self.velocity[0] > -0.1 and self.velocity[0] < 0.1:
self.velocity[0] += 0.1
# Collision with paddle
def bounceOffPaddle(self,paddle):
# Check collision with paddle
if pygame.sprite.collide_mask(self, paddle):
# If left paddle collision
if (self.rect.x > paddle.rect.x + (paddle.width/2)):
# Check velocity and bounce appropriately
if (self.velocity[0]) < 0:
self.velocity[0] = -self.velocity[0]
else:
self.velocity[0] = self.velocity[0]
# If right paddle collision
elif (self.rect.x < paddle.rect.x + (paddle.width/2)):
# Check velocity and bounce appropriately
if (self.velocity[0]) < 0:
self.velocity[0] = self.velocity[0]
else:
self.velocity[0] = -self.velocity[0]
# Increase speed up to maxSpeed
if self.velocity[1] < self.maxSpeed:
self.velocity[1] = -self.velocity[1] + self.velocity_increment
else:
self.velocity[1] = -self.velocity[1]
# Collision with briks
def bounceOffBriks(self,briks):
# List of collisions with ball and brik group
brick_collision_list = pygame.sprite.spritecollide(self,briks,False)
# Check for collision and remove brik
for brick in brick_collision_list:
self.velocity[0] = self.velocity[0]
self.velocity[1] = -self.velocity[1]
brick.kill()
return True
# Collision with sides and upper wall
def bounceOffWalls(self,screen_width,screen_height):
if self.rect.x>=(screen_width-self.diameter):
self.velocity[0] = -self.velocity[0]
if self.rect.x<=0:
self.velocity[0] = -self.velocity[0]
if self.rect.y<=40:
self.velocity[1] = -self.velocity[1]
# Collision with ground
def bounceOffGround(self,screen_height):
if self.rect.y>(screen_height-self.diameter):
self.velocity[1] = -self.velocity[1]
return True
# Derives from the "Sprite" class in Pygame
class Brick(pygame.sprite.Sprite):
def __init__(self):
# Sprite super constructor
super().__init__()
# Init brick variables
self.width = 64
self.height = 20
self.image = getFilledRect(self.width, self.height, 255, 0, 0)
# Fetch the rectangle object that has the dimensions of the image.
self.rect = self.image.get_rect()
import pygame
# Derives from the "Sprite" class in Pygame
class Paddle(pygame.sprite.Sprite):
def __init__(self,screen_width,screen_height):
# Sprite super constructor
super().__init__()
# Init paddle variables
self.width = 100
self.height = 10
# Load paddle image and scale
self.image = getFilledRect(self.width, self.height, 0, 255, 255)
# Fetch the rectangle object that has the dimensions of the image.
self.rect = self.image.get_rect()
# Position the paddle in the middle
self.rect.x = (screen_width/2) - (self.width/2)
self.rect.y = screen_height - (self.height * 4)
# Move paddle left
def moveLeft(self, speed):
self.rect.x -= speed
# Constrain off-screen
if self.rect.x < 0:
self.rect.x = 0
# Move paddle right
def moveRight(self, speed,screen_width):
self.rect.x += speed
# Constrain off-screen
if self.rect.x > (screen_width - self.width):
self.rect.x = (screen_width - self.width)
# Utility function to initialise the bricks wall
def initBriksEasy(all_sprites_list,bricks_sprites_list):
# Grid custom layout
offset_x = 65
offset_y = 25
offest_row = 70
rows = 8
columns = 10
# Used to load images for themed modes
count = 1
# Create grid of bricks
for row in range(rows):
for col in range(columns):
# Create brick and position
brick = Brick()
brick.rect.x = 20 + (offset_x*col)+ brick.width
brick.rect.y = offest_row + (offset_y*row)+brick.height
# Add brick to all sprites group and briks group
all_sprites_list.add(brick)
bricks_sprites_list.add(brick)
# Increase counter to load the next image on the brick
count+=1
# Utility function to initialise the bricks wall
def initBriks(all_sprites_list,bricks_sprites_list, rows=8,columns=12, col_width=65):
# Grid custom layout
offset_x = col_width
offset_y = 25
offest_row = 70
# Used to load images for themed modes
count = 1
# Create grid of bricks
for row in range(rows):
for col in range(columns):
# Create brick and position
brick = Brick()
brick.rect.x = (offset_x*col)
brick.rect.y = offest_row + (offset_y*row)+brick.height
# Add brick to all sprites group and briks group
all_sprites_list.add(brick)
bricks_sprites_list.add(brick)
# Increase counter to load the next image on the brick
count+=1
class BreakWallGame():
def __init__(self):
# Choose the game theme (Standard, Coursera, Authors)
#game_theme = "Standard"
# Initialise game environment variables
self.screen_width = 65 * 12
self.screen_height = 600
#background_image = pygame.image.load("./images/background.png")
self.background_image = getFilledRect(self.screen_width, self.screen_height, 0, 0, 0) # b g r
self.reset()
# Initialise game screen and caption
pygame.init()
self.screen = pygame.display.set_mode((self.screen_width,self.screen_height))
pygame.display.set_caption("Breawall")
def reset(self):
self.initial_score = 0
self.game_over = False
self.lives = 1
# List of all the sprites used in the game
self.all_sprites_list = pygame.sprite.Group()
# List of all the bricks sprites
self.bricks_sprites_list = pygame.sprite.Group()
# Initialise paddle and ball
self.paddle = Paddle(self.screen_width,self.screen_height)
self.ball = Ball(self.screen_width,self.screen_height)
# Add the paddle and the ball to the list of sprites
self.all_sprites_list.add(self.paddle)
self.all_sprites_list.add(self.ball)
# Initialise wall of bricks
# Display them in a grid
initBriks(self.all_sprites_list,
self.bricks_sprites_list)
def step(self, action):
"""
"""
assert action in ["NOOP", "FIRE", "LEFT", "RIGHT"], "Invalid action" + action
if action == "LEFT":
self.paddle.moveLeft(5)
if action == "RIGHT":
self.paddle.moveRight(5, self.screen_width)
# Add background image
#self.screen.blit(self.background_image, (0, 0))
# faster way to make black background
self.screen.fill([0, 0, 0])
# # Update the sprites position
self.all_sprites_list.update()
# Check if the ball is bouncing against any of the 3 walls (left, right, top)
self.ball.bounceOffWalls(self.screen_width,self.screen_height)
# Check collision with bottom wall (ground)
if self.ball.bounceOffGround(self.screen_height):
self.lives -=1 # Remove one life
if self.lives == 0:
self.game_over = True
# Check ball-paddle collision
self.ball.bounceOffPaddle(self.paddle)
# Check ball-bricks collision
if self.ball.bounceOffBriks(self.bricks_sprites_list):
self.initial_score+=1
# Check win status
if len(self.bricks_sprites_list) == 0:
self.game_over=True
# Draw all the sprites in the game
self.all_sprites_list.draw(self.screen)
# # Update full display screen
pygame.display.flip()
def getScreenRGB(self):
# nicked this from Pygame-Learning-Environment
# pix = pygame.surfarray.array3d(
# pygame.display.get_surface()).astype(np.uint8)
# pix = np.rot90(pix, 3) # rotate it 90x3 ->270
# 100 x faster version :)
# get raw framebuffer and convert to numpy
pix = np.frombuffer(pygame.display.get_surface().get_buffer().raw, dtype=np.uint8)
# reshape to 3D array of RGBA
pix = np.reshape(pix, [self.screen_height,self.screen_width,4])
# this tricky bit reverses the order of the RGBA and loses the A
pix = pix[:,:,2::-1]
#pix = np.rot90(pix, 3) # rotate it 90x3 ->270
return pix
# def _get_image(self):
# image_rotated = np.fliplr(np.rot90(self.game_state.getScreenRGB(),3)) #
# Hack to fix the rotated image returned by ple
# return image_rotated
class BreakWall(gym.Env):
"""
This is a simple, high level wrapper class for the breakwall game which presents it with an openai gym compatible interface as per:
https://github.com/openai/gym/blob/master/docs/creating_environments.md
"""
metadata = {'render.modes': ['human']}
def __init__(self):
# offscreen mode
os.environ['SDL_VIDEODRIVER'] = 'dummy'
self.game = BreakWallGame()
self.viewer = None
# these variables allow atari wrapper to work
self._action_set = [0,1,3,4] # NOOP, FIRE, LEFT, RIGHT
self.action_space = spaces.Discrete(len(self._action_set))
self.observation_space = spaces.Box(low=0, high=255, shape=(self.game.screen_height, self.game.screen_width, 3), dtype=np.uint8)
self.seed()
# need this to provide a self.ale object with a lives function
class ale:
def __init__(self, game):
self.game = game
def lives(self):
return self.game.lives
self.ale = ale(self.game)
self.ACTION_MEANING = {
0: "NOOP",
1: "FIRE",
2: "UP",
3: "RIGHT",
4: "LEFT",
5: "DOWN",
6: "UPRIGHT",
7: "UPLEFT",
8: "DOWNRIGHT",
9: "DOWNLEFT",
10: "UPFIRE",
11: "RIGHTFIRE",
12: "LEFTFIRE",
13: "DOWNFIRE",
14: "UPRIGHTFIRE",
15: "UPLEFTFIRE",
16: "DOWNRIGHTFIRE",
17: "DOWNLEFTFIRE",
}
def step(self, action):
"""
"""
start_score = self.game.initial_score
action = self._action_set[action]
self.game.step(self.ACTION_MEANING[action])
state = self.game.getScreenRGB()
end_score = self.game.initial_score
reward = end_score - start_score
terminal = self.game.game_over
return state, reward, terminal, {}
def seed(self, seed=None):
self.np_random, seed1 = seeding.np_random(seed)
def reset(self):
self.game.reset()
state = self.game.getScreenRGB()
return state
def render(self, mode='human'):
"""
show the current screen
"""
img = self.game.getScreenRGB()
if mode == 'rgb_array':
return img
elif mode == 'human':
from gym.envs.classic_control import rendering
if self.viewer is None:
self.viewer = rendering.SimpleImageViewer()
self.viewer.imshow(img)
def close(self):
pass
def get_action_meanings(self):
"""
copied from atari_env.py
"""
return [self.ACTION_MEANING[i] for i in self._action_set]

View File

@ -0,0 +1,6 @@
from setuptools import setup
setup(name='gym_gs',
version='0.0.1',
install_requires=['gym', 'pygame'] # And any other dependencies foo needs
)