1+ # An old version of OpenAI Gym's multi_discrete.py. (Was getting affected by Gym updates)
2+ # (https://github.com/openai/gym/blob/1fb81d4e3fb780ccf77fec731287ba07da35eb84/gym/spaces/multi_discrete.py)
3+
4+ import numpy as np
5+
6+ import gym
7+ from gym .spaces import prng
8+
9+ class MultiDiscrete (gym .Space ):
10+ """
11+ - The multi-discrete action space consists of a series of discrete action spaces with different parameters
12+ - It can be adapted to both a Discrete action space or a continuous (Box) action space
13+ - It is useful to represent game controllers or keyboards where each key can be represented as a discrete action space
14+ - It is parametrized by passing an array of arrays containing [min, max] for each discrete action space
15+ where the discrete action space can take any integers from `min` to `max` (both inclusive)
16+ Note: A value of 0 always need to represent the NOOP action.
17+ e.g. Nintendo Game Controller
18+ - Can be conceptualized as 3 discrete action spaces:
19+ 1) Arrow Keys: Discrete 5 - NOOP[0], UP[1], RIGHT[2], DOWN[3], LEFT[4] - params: min: 0, max: 4
20+ 2) Button A: Discrete 2 - NOOP[0], Pressed[1] - params: min: 0, max: 1
21+ 3) Button B: Discrete 2 - NOOP[0], Pressed[1] - params: min: 0, max: 1
22+ - Can be initialized as
23+ MultiDiscrete([ [0,4], [0,1], [0,1] ])
24+ """
25+ def __init__ (self , array_of_param_array ):
26+ self .low = np .array ([x [0 ] for x in array_of_param_array ])
27+ self .high = np .array ([x [1 ] for x in array_of_param_array ])
28+ self .num_discrete_space = self .low .shape [0 ]
29+
30+ def sample (self ):
31+ """ Returns a array with one sample from each discrete action space """
32+ # For each row: round(random .* (max - min) + min, 0)
33+ random_array = prng .np_random .rand (self .num_discrete_space )
34+ return [int (x ) for x in np .floor (np .multiply ((self .high - self .low + 1. ), random_array ) + self .low )]
35+ def contains (self , x ):
36+ return len (x ) == self .num_discrete_space and (np .array (x ) >= self .low ).all () and (np .array (x ) <= self .high ).all ()
37+
38+ @property
39+ def shape (self ):
40+ return self .num_discrete_space
41+ def __repr__ (self ):
42+ return "MultiDiscrete" + str (self .num_discrete_space )
43+ def __eq__ (self , other ):
44+ return np .array_equal (self .low , other .low ) and np .array_equal (self .high , other .high )
0 commit comments