Skip to content

Commit

Permalink
Merge pull request #1 from MiscellaneousStuff/gym
Browse files Browse the repository at this point in the history
Noop and Random Gym Env Scripts Working
  • Loading branch information
MiscellaneousStuff authored Feb 11, 2023
2 parents c37b983 + a80c896 commit e036df6
Show file tree
Hide file tree
Showing 8 changed files with 462 additions and 0 deletions.
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
gym==0.18.0
14 changes: 14 additions & 0 deletions tlol_rl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,20 @@

import os

from gym.envs.registration import register

register(
id='LoLGame-v0',
entry_point='tlol_rl.envs:LoLGameEnv',
kwargs={}
)

register(
id='LoL1DEscape-v0',
entry_point='tlol_rl.envs:Escape1DEnv',
kwargs={}
)

def load_tests(loader, standard_tests, unused_pattern):
"""Our tests end in `_test.py`, so need to ovveride the test directory."""
this_dir = os.path.dirname(__file__)
Expand Down
44 changes: 44 additions & 0 deletions tlol_rl/bin/gym_escape.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# MIT License
#
# Copyright (c) 2023 MiscellaneousStuff
#
# 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.
"""Example of a basic full game environment implementing PPO.
Runs the `Escape1DEnv` environment which trains the agent to go the
opposite direction of the enemy agent by clicking away or using spells."""

from absl import flags
from absl import app

FLAGS = flags.FLAGS
flags.DEFINE_string("config_path", "./config.txt",
"File containing directories of GameServer, League client respectively")
flags.DEFINE_string("host", "localhost", "IP Host of Redis")
flags.DEFINE_integer("redis_port", 6379, "IP Port of Redis")
flags.DEFINE_integer("max_episodes", 0, "Maximum number of episodes to run")
flags.DEFINE_integer("max_steps", 0, "Maximum number of steps to run")
flags.DEFINE_string("map", "Summoners Rift", "Name of league map to use.")
flags.DEFINE_string("champion", None, "Champion for agent to play.")

def main(unused_argv):
pass

if __name__ == "__main__":
app.run(main)
68 changes: 68 additions & 0 deletions tlol_rl/bin/gym_noop.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# MIT License
#
# Copyright (c) 2023 MiscellaneousStuff
#
# 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.
"""Example of a basic full game environment with no actions."""

import gym
from absl import flags
from tlol_rl.lib import actions

import tlol_rl.envs

from absl import logging
from absl import flags
from absl import app

FLAGS = flags.FLAGS
flags.DEFINE_string("config_path", "./config.txt",
"File containing directories of GameServer, League client respectively")
flags.DEFINE_string("host", "localhost", "IP Host of Redis")
flags.DEFINE_integer("redis_port", 6379, "IP Port of Redis")
flags.DEFINE_integer("max_episodes", 0, "Maximum number of episodes to run")
flags.DEFINE_integer("max_steps", 0, "Maximum number of steps to run")
flags.DEFINE_string("map", "Summoners Rift", "Name of league map to use.")
flags.DEFINE_string("champion", None, "Champion for agent to play.")

flags.mark_flag_as_required("champion")

_NO_OP = [actions.FUNCTIONS.no_op.id]

def main(unused_argv):
env = gym.make("LoLGame-v0")
env.settings["host"] = FLAGS.host
env.settings["redis_port"] = FLAGS.redis_port
env.settings["map_name"] = FLAGS.map
env.settings["champion"] = FLAGS.champion
env.settings["config_path"] = FLAGS.config_path

obs_n = env.reset()

for step in range(10000):
action = [_NO_OP] * env.n_agents
obs_n, reward_n, done_n, _ = env.step(action)
logging.info("Step, Reward: " + str(step+1) + "," + str(reward_n))
if any(done_n):
break

env.close()

if __name__ == "__main__":
app.run(main)
76 changes: 76 additions & 0 deletions tlol_rl/bin/gym_random.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# MIT License
#
# Copyright (c) 2023 MiscellaneousStuff
#
# 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.
"""Example of a basic full game environment with random actions."""

import gym
import numpy as np

import tlol_rl.envs
from tlol_rl.lib import actions

from absl import logging
from absl import flags
from absl import app

FLAGS = flags.FLAGS
flags.DEFINE_string("config_path", "./config.txt",
"File containing directories of GameServer, League client respectively")
flags.DEFINE_string("host", "localhost", "IP Host of Redis")
flags.DEFINE_integer("redis_port", 6379, "IP Port of Redis")
flags.DEFINE_integer("max_episodes", 0, "Maximum number of episodes to run")
flags.DEFINE_integer("max_steps", 0, "Maximum number of steps to run")
flags.DEFINE_string("map", "Summoners Rift", "Name of league map to use.")
flags.DEFINE_string("champion", None, "Champion for agent to play.")

flags.mark_flag_as_required("champion")

_NO_OP = [actions.FUNCTIONS.no_op.id]

def main(unused_argv):
env = gym.make("LoLGame-v0")
env.settings["host"] = FLAGS.host
env.settings["redis_port"] = FLAGS.redis_port
env.settings["map_name"] = FLAGS.map
env.settings["champion"] = FLAGS.champion
env.settings["config_path"] = FLAGS.config_path

done_n = [False for _ in range(env.n_agents)]

obs_n = env.reset()

for step in range(10000):
actions = [random_action(env, timestep) for timestep in obs_n]
obs_n, reward_n, done_n, _ = env.step(actions)
logging.info("Step, Reward: " + str(step+1) + "," + str(reward_n))
if any(done_n):
break

env.close()

def random_action(env, obs):
function_id = np.random.choice(obs.observation["available_actions"])
args = [[np.random.randint(0, size) for size in arg.sizes]
for arg in env.action_spec[0].functions[function_id].args]
return [function_id] + args

if __name__ == "__main__":
app.run(main)
25 changes: 25 additions & 0 deletions tlol_rl/envs/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# MIT License
#
# Copyright (c) 2023 MiscellaneousStuff
#
# 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.
"""Import all of the available OpenAI Gym environments."""

from tlol_rl.envs.escape_1d import Escape1DEnv
from tlol_rl.envs.lol_game import LoLGameEnv
72 changes: 72 additions & 0 deletions tlol_rl/envs/escape_1d.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# MIT License
#
# Copyright (c) 2023 MiscellaneousStuff
#
# 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.
"""Escape the enemy champion only by moving along the X-Axis."""

import numpy as np

from gym.spaces import Box, Discrete

from tlol_rl.lib import actions, point
from tlol_rl.envs.lol_game import LoLGameEnv

_NO_OP = [actions.FUNCTIONS.no_op.id]


class Escape1DEnv(LoLGameEnv):
def __init__(self, **kwargs) -> None:
super().__init__()

def transform_obs(self, obs):
obs = np.array(obs[0]["enemy_unit"].distance_to_me, dtype=np.float32)
return obs

def reset(self):
obs = self.transform_obs(super().reset())
return obs

def _safe_step(self, act):
act_x = 8 if act else 0
act_y = 4
act = [[1, point.Point(act_x, act_y)],
_NO_OP]

obs_n, reward_n, done_n, _ = super()._safe_step(act)

obs = self.transform_obs(obs_n)
reward = obs_n[0]["enemy_unit"].distance_to_me.item()
reward = reward if reward else 0.0
done = all(done_n)
return obs, reward, done, {}

@property
def action_space(self):
if self._env is None:
self._init_env()
action_space = Discrete(2)
return action_space

@property
def observation_space(self):
if self._env is None:
self._init_env()
observation_space = Box(low=0, high=16000, shape=(1,), dtype=np.float32)
return observation_space
Loading

0 comments on commit e036df6

Please sign in to comment.