Metadata-Version: 2.4
Name: gymDSM
Version: 2.1.0
Summary: gymDSM (Didactically Supercharged Mod): a small library that provides didactically enhanced Gymnasium environments (e.g., a MountainCar variant whose render color shows the last action, and an educational Dino environment inspired by Chrome Dino).
Home-page: https://github.com/DanielSaromo/gymDSM
Author: Daniel Saromo
Author-email: danielsaromo@gmail.com
License: MIT
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: gymnasium>=1.0
Requires-Dist: numpy
Provides-Extra: render
Requires-Dist: gymnasium[classic-control]; extra == "render"
Requires-Dist: matplotlib; extra == "render"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license
Dynamic: license-file
Dynamic: provides-extra
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# gymDSM
gymDSM (Didactically Supercharged Mod): A modified version of [Gymnasium](https://gymnasium.farama.org/) (the maintained successor of OpenAI Gym).

## What is gymDSM?
**gymDSM** is a small Python package that provides **didactically enhanced** (teaching-friendly) [Gymnasium](https://gymnasium.farama.org/) environments: modified versions of classic environments, and new environments designed for teaching reinforcement learning.

| Environment | IDs | Description |
|---|---|---|
| [MountainCar](#mountaincar) | `MountainCar-v0` | Gymnasium's Mountain Car, where the car's color shows the last action. |
| [Dino](#dino-environment-in-spanish) | `Dino-v0`, `DinoAumentado-v0` | An educational Dino runner inspired by the **Chrome Dino** game. **Written in Spanish.** |

### MountainCar

The MountainCar environment has a small (but important) visual modification: the car’s color reflects the **last action** taken:
- `0` (push left)  → red  
- `1` (no push)    → blue  
- `2` (push right) → green  

The goal is to make it easier to understand what an agent is doing while interacting with the environment.

Everything else (physics, rewards, observation/action spaces, seeding, the 200-step time limit, and the `goal_velocity` parameter) is **identical** to Gymnasium's [Mountain Car](https://gymnasium.farama.org/environments/classic_control/mountain_car/), because the gymDSM environment subclasses it and only changes the rendering.

### Dino environment (in Spanish)

The Dino environment is inspired by the **Chrome Dino** game (the T-Rex runner that appears in **Chromium-based browsers** such as Google Chrome when there is no internet connection, also available at `chrome://dino`). The agent controls a dinosaur that runs automatically and must avoid ground and aerial obstacles.

> 🇪🇸 **This environment was written in Spanish.** Its classes, configuration parameters, observation names, `info` keys, error messages, and the on-screen dashboard are all in Spanish (e.g., `EntornoDinosaurio`, `ConfiguracionEntorno`, `Accion.SALTO_GRANDE`, `info["obstaculos_superados"]`).

Compared to the original game, it adds features designed for teaching reinforcement learning: two jump heights, crouching, distance sensors, a variable speed profile, and optional domain randomization (random gravity, jump strength, speed, action latency, and sensor noise). Its dashboard (`render_mode="human"` or `"rgb_array"`) shows the game together with the sensors, the observation vector, the actions, and episode statistics.

**Actions** (`Discrete(5)`, also available as `gymDSM.dino.Accion`):

| Value | `Accion` | Meaning |
|---|---|---|
| `0` | `NO_OP` | Do nothing |
| `1` | `SALTO_PEQUENO` | Small jump |
| `2` | `SALTO_GRANDE` | Big jump |
| `3` | `AGACHARSE` | Crouch |
| `4` | `LEVANTARSE` | Stand up |

**Observations.** There are two versions of the environment, which only differ in the observation vector:

| ID | Size | Observation |
|---|---|---|
| `Dino-v0` (base state) | 9 | `s1`…`s6`: six binary obstacle sensors (2 distances × 3 heights); `y`: dinosaur height; `vx`: running speed; `vy`: vertical speed. |
| `DinoAumentado-v0` (augmented state) | 39 | The 9 base values, plus: sensor history (`s*_hace_1`, `s*_hace_2`) and changes (`delta_s*`), predicted heights (`y_futura_0.1s`, `y_futura_0.3s`, `y_futura_0.5s`), speed change and estimated acceleration, kinetic and potential energy, and speed history (`vx_hace_*`, `vy_hace_*`). |

The names of all components are available in `env.unwrapped.constructor_observacion.nombres`.

**Rewards and episode end.** By default, the agent receives `+0.05` per step survived, `+5` per obstacle passed, and `-20` for a collision. The episode is `terminated` on a collision and `truncated` after 3000 steps (60 s of simulated time, with `dt = 0.02` s). All of these values can be changed with `ConfiguracionEntorno`.

## Installation

The library gymDSM is on the [Python Package Index](https://pypi.org/project/gymDSM/ "gymDSM page on PyPI").
To install the library, first install `pip` and then use the command `pip install gymDSM`. Alternatively, you can use `pip install gymdsm`. Remember that pip/PyPI treat distribution names case-insensitively.

This project requires **Python 3.9 or newer** and works with **Gymnasium 1.0 or newer** (tested with Gymnasium 1.0.0 and 1.4.0), which is installed automatically as a dependency.

If you want to use rendering (`render_mode="human"` or `render_mode="rgb_array"`), use the following installation command:

```bash
pip install "gymDSM[render]"
```

(The command above installs `gymnasium[classic-control]`, which brings in the pygame version that your Gymnasium release expects, and `matplotlib`, used by the color palette of the Dino population dashboard.)

> **Upgrading from gymDSM 1.x (Gym 0.22)?** See [Migrating from gymDSM 1.x](#migrating-from-gymdsm-1x-gym-022) below.

---

## Minimal Working Examples (MWE)

### MountainCar

#### 1) Create the environment using gymDSM.make
This is designed to be easily replaceable with the usual Gymnasium pattern:

```python
import gymDSM

env = gymDSM.make("MountainCar-v0")

obs, info = env.reset(seed=42)
done = False

while not done:
    action = env.action_space.sample()  # random policy
    obs, reward, terminated, truncated, info = env.step(action)
    done = terminated or truncated

env.close()
```

#### 2) Render in a window (optional)
In Gymnasium, the render mode is chosen when the environment is created. With `render_mode="human"`, the window is updated automatically on every `reset()` and `step()`, so there is no need to call `env.render()`:

```python
import gymDSM

env = gymDSM.make("MountainCar-v0", render_mode="human")  # requires pygame
obs, info = env.reset(seed=42)

done = False
while not done:
    action = env.action_space.sample()
    obs, reward, terminated, truncated, info = env.step(action)
    done = terminated or truncated

env.close()
```

#### 3) Get frames as images (optional)
Use `render_mode="rgb_array"` to get each frame as a NumPy array of shape `(400, 600, 3)`, e.g., to record videos or show them in a Jupyter notebook:

```python
import gymDSM

env = gymDSM.make("MountainCar-v0", render_mode="rgb_array")  # requires pygame
obs, info = env.reset(seed=42)
obs, reward, terminated, truncated, info = env.step(2)  # push right

frame = env.render()  # the car is green in this frame
env.close()
```

### Dino

#### 1) Base version: `Dino-v0`

```python
import gymDSM

env = gymDSM.make("Dino-v0")
print(env.observation_space.shape)  # (9,)

obs, info = env.reset(seed=42)
done = False

while not done:
    action = env.action_space.sample()  # random policy
    obs, reward, terminated, truncated, info = env.step(action)
    done = terminated or truncated

print("Obstacles passed:", info["obstaculos_superados"])
env.close()
```

#### 2) Augmented-state version: `DinoAumentado-v0`

```python
import gymDSM

env = gymDSM.make("DinoAumentado-v0")
print(env.observation_space.shape)  # (39,)

obs, info = env.reset(seed=42)
done = False

while not done:
    action = env.action_space.sample()  # random policy
    obs, reward, terminated, truncated, info = env.step(action)
    done = terminated or truncated

print("Obstacles passed:", info["obstaculos_superados"])
env.close()
```

#### 3) Render the dashboard and choose actions by name (optional)
The actions can be written with the `Accion` enum. This simple rule-based agent jumps when the nearest ground sensor (`s3`, i.e., `obs[2]`) detects an obstacle:

```python
import gymDSM
from gymDSM.dino import Accion

env = gymDSM.make("Dino-v0", render_mode="human")  # requires pygame
obs, info = env.reset(seed=42)

done = False
while not done:
    action = Accion.SALTO_GRANDE if obs[2] else Accion.NO_OP
    obs, reward, terminated, truncated, info = env.step(action)
    done = terminated or truncated

env.close()
```

With `render_mode="rgb_array"`, `env.render()` returns the dashboard as a NumPy array of shape `(1000, 1440, 3)`.

#### 4) Custom configuration (optional)
Both IDs accept a `configuracion` argument. For example, to enable domain randomization and shorten the episodes:

```python
import gymDSM
from gymDSM.dino import ConfiguracionEntorno

configuracion = ConfiguracionEntorno(usar_domain_randomization=True, max_pasos=1000)
env = gymDSM.make("DinoAumentado-v0", configuracion=configuracion)
obs, info = env.reset(seed=42)
print(info["parametros_dominio"])  # gravity, jump impulses, speeds, latency... sampled for this episode
env.close()
```

`DinoAumentado-v0` always uses the augmented state, even when a custom `configuracion` is given. `Dino-v0` with `ConfiguracionEntorno(usar_estado_aumentado=True)` is equivalent to `DinoAumentado-v0`.

#### 5) Population of dinosaurs (optional)
`EntornoPoblacion` runs many dinosaurs at once in the same world (same obstacles and speed), which is useful for evolutionary algorithms such as neuroevolution. It uses a vectorized API with one row per dinosaur:

```python
import numpy as np
from gymDSM.dino import EntornoPoblacion

n = 20
env = EntornoPoblacion(tamano_poblacion=n)
obs, info = env.reset(seed=42)
print(obs.shape)  # (20, 9)

while not env.finalizado:  # until all dinosaurs crash or the time limit is reached
    actions = np.random.randint(0, 5, size=n)
    obs, rewards, dead, truncated, info = env.step(actions)

env.close()
```

## Behavior and supported environments

gymDSM currently supports Gymnasium's [Mountain Car](https://gymnasium.farama.org/environments/classic_control/mountain_car/) environment and its own Dino environment.

- If you call:
  ```python
  env = gymDSM.make("MountainCar-v0")
  ```
  gymDSM will try to create the gymDSM MountainCar variant (with action-based colors).

- If you call `gymDSM.make("Dino-v0")` or `gymDSM.make("DinoAumentado-v0")`, gymDSM creates the Dino environment (these IDs only exist in gymDSM).

- If `env_id` is not supported by gymDSM, or if creating the gymDSM version of `MountainCar-v0` fails for any reason, `gymDSM.make(...)` falls back to:
  ```python
  gymnasium.make(env_id, ...)
  ```
  using the standard Gymnasium environment (a warning is shown if the gymDSM version failed).

- Importing gymDSM also registers its environments in Gymnasium under the IDs `ColoredActionMountainCar-v0`, `Dino-v0`, and `DinoAumentado-v0`, so they can be used with plain Gymnasium too (e.g., with vectorized environments or RL libraries that call `gymnasium.make` internally):
  ```python
  import gymnasium as gym
  import gymDSM  # registers "ColoredActionMountainCar-v0", "Dino-v0", and "DinoAumentado-v0"

  env = gym.make("ColoredActionMountainCar-v0", render_mode="rgb_array")
  env2 = gym.make("DinoAumentado-v0")
  ```

## Migrating from gymDSM 1.x (Gym 0.22)

gymDSM 2.0 follows the [Gymnasium API](https://gymnasium.farama.org/introduction/migration_guide/). If you have code written for gymDSM 1.x, update it as follows:

| gymDSM 1.x (Gym 0.22) | gymDSM 2.x (Gymnasium) |
|---|---|
| `obs = env.reset()` | `obs, info = env.reset(seed=None)` |
| `obs, reward, done, info = env.step(a)` | `obs, reward, terminated, truncated, info = env.step(a)`<br>`done = terminated or truncated` |
| `env.render()` / `env.render(mode="rgb_array")` | `gymDSM.make(..., render_mode="human")` or `render_mode="rgb_array"`, then `env.render()` (no arguments) |
| `env.seed(42)` | `env.reset(seed=42)` |
| `import gym` | `import gymnasium as gym` |

`terminated` is `True` when the car reaches the flag; `truncated` is `True` when the 200-step time limit is reached.

## License and Acknowledgments

**gymDSM** is an independent open-source project that originates from a fork of OpenAI Gym and is now built on top of Gymnasium. This project is **not** affiliated with or endorsed by OpenAI, the Farama Foundation, or Google. gymDSM is developed for research and educational purposes. It builds upon the foundation laid by the OpenAI Gym and Gymnasium libraries, and we acknowledge and thank the original OpenAI Gym authors, the Farama Foundation, and all contributors for their pioneering work. The Dino environment is an independent implementation inspired by the Chrome Dino game.

gymDSM, the original OpenAI Gym, and Gymnasium are released under the MIT License. We have retained the original project's MIT licensing for gymDSM, ensuring that any use or distribution of this fork complies with the same terms. Please see the `LICENSE` file in this repository for the full text of the MIT License.
