mirror of
https://github.com/jcreek/Sarpy.git
synced 2026-07-13 11:13:44 +00:00
feat(*): Add default bot code
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
import numpy as np
|
||||
from rlgym_compat import GameState
|
||||
|
||||
|
||||
class ContinuousAction:
|
||||
"""
|
||||
Simple continuous action space. Operates in the range -1 to 1, even for the binary actions which are converted back to binary later.
|
||||
This is for improved compatibility, stable baselines doesn't support tuple spaces right now.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def get_action_space(self):
|
||||
raise NotImplementedError("We don't implement get_action_space to remove the gym dependency")
|
||||
|
||||
def parse_actions(self, actions: np.ndarray, state: GameState) -> np.ndarray:
|
||||
actions = actions.reshape((-1, 8))
|
||||
|
||||
actions[..., :5] = actions[..., :5].clip(-1, 1)
|
||||
# The final 3 actions handle are jump, boost and handbrake. They are inherently discrete so we convert them to either 0 or 1.
|
||||
actions[..., 5:] = actions[..., 5:] > 0
|
||||
|
||||
return actions
|
||||
@@ -0,0 +1,30 @@
|
||||
import numpy as np
|
||||
from rlgym_compat import GameState
|
||||
from .continuous_act import ContinuousAction
|
||||
from typing import Union, List
|
||||
|
||||
|
||||
class DefaultAction(ContinuousAction):
|
||||
"""
|
||||
Continuous Action space, that also accepts a few other input formats for QoL reasons and to remain
|
||||
compatible with older versions.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def get_action_space(self):
|
||||
return super().get_action_space()
|
||||
|
||||
def parse_actions(self, actions: Union[np.ndarray, List[np.ndarray], List[float]], state: GameState) -> np.ndarray:
|
||||
|
||||
# allow other data types, this part should not be necessary but is nice to have in the default action parser.
|
||||
if type(actions) != np.ndarray:
|
||||
actions = np.asarray(actions)
|
||||
|
||||
if len(actions.shape) == 1:
|
||||
actions = actions.reshape((-1, 8))
|
||||
elif len(actions.shape) > 2:
|
||||
raise ValueError('{} is not a valid action shape'.format(actions.shape))
|
||||
|
||||
return super().parse_actions(actions, state)
|
||||
@@ -0,0 +1,24 @@
|
||||
import numpy as np
|
||||
from rlgym_compat import GameState
|
||||
|
||||
|
||||
class DiscreteAction:
|
||||
"""
|
||||
Simple discrete action space. All the analog actions have 3 bins by default: -1, 0 and 1.
|
||||
"""
|
||||
|
||||
def __init__(self, n_bins=3):
|
||||
assert n_bins % 2 == 1, "n_bins must be an odd number"
|
||||
self._n_bins = n_bins
|
||||
|
||||
def get_action_space(self):
|
||||
raise NotImplementedError("We don't implement get_action_space to remove the gym dependency")
|
||||
|
||||
def parse_actions(self, actions: np.ndarray, state: GameState) -> np.ndarray:
|
||||
actions = actions.reshape((-1, 8)).astype(dtype=np.float32)
|
||||
|
||||
# map all binned actions from {0, 1, 2 .. n_bins - 1} to {-1 .. 1}.
|
||||
actions[..., :5] = actions[..., :5] / (self._n_bins // 2) - 1
|
||||
|
||||
return actions
|
||||
|
||||
Reference in New Issue
Block a user