metrogym 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- metrogym-0.1.0/.gitignore +11 -0
- metrogym-0.1.0/LICENSE +21 -0
- metrogym-0.1.0/PKG-INFO +144 -0
- metrogym-0.1.0/README.md +114 -0
- metrogym-0.1.0/pyproject.toml +60 -0
- metrogym-0.1.0/src/metrogym/__init__.py +113 -0
- metrogym-0.1.0/src/metrogym/assets/fonts/Roobert/Roobert-Bold.otf +0 -0
- metrogym-0.1.0/src/metrogym/assets/fonts/Roobert/Roobert-Medium.otf +0 -0
- metrogym-0.1.0/src/metrogym/assets/fonts/Roobert/Roobert-Regular.otf +0 -0
- metrogym-0.1.0/src/metrogym/assets/fonts/Roobert/Roobert-SemiBold.otf +0 -0
- metrogym-0.1.0/src/metrogym/assets/signals/go_signal_16x40.svg +16 -0
- metrogym-0.1.0/src/metrogym/assets/signals/go_signal_31x80.svg +16 -0
- metrogym-0.1.0/src/metrogym/assets/signals/go_signal_47x120.svg +16 -0
- metrogym-0.1.0/src/metrogym/assets/signals/go_signal_63x160.svg +16 -0
- metrogym-0.1.0/src/metrogym/assets/signals/stop_signal_16x40.svg +16 -0
- metrogym-0.1.0/src/metrogym/assets/signals/stop_signal_31x80.svg +16 -0
- metrogym-0.1.0/src/metrogym/assets/signals/stop_signal_47x120.svg +16 -0
- metrogym-0.1.0/src/metrogym/assets/signals/stop_signal_63x160.svg +16 -0
- metrogym-0.1.0/src/metrogym/assets/trains/beijing_line_1_128x72.svg +21 -0
- metrogym-0.1.0/src/metrogym/assets/trains/beijing_line_1_192x108.svg +21 -0
- metrogym-0.1.0/src/metrogym/assets/trains/beijing_line_1_256x144.svg +21 -0
- metrogym-0.1.0/src/metrogym/assets/trains/beijing_line_1_64x36.svg +21 -0
- metrogym-0.1.0/src/metrogym/assets/trains/beijing_line_2_128x72.svg +27 -0
- metrogym-0.1.0/src/metrogym/assets/trains/beijing_line_2_192x108.svg +27 -0
- metrogym-0.1.0/src/metrogym/assets/trains/beijing_line_2_256x144.svg +27 -0
- metrogym-0.1.0/src/metrogym/assets/trains/beijing_line_2_64x36.svg +27 -0
- metrogym-0.1.0/src/metrogym/assets/trains/beijing_line_3_128x72.svg +19 -0
- metrogym-0.1.0/src/metrogym/assets/trains/beijing_line_3_192x108.svg +19 -0
- metrogym-0.1.0/src/metrogym/assets/trains/beijing_line_3_256x144.svg +19 -0
- metrogym-0.1.0/src/metrogym/assets/trains/beijing_line_3_64x36.svg +19 -0
- metrogym-0.1.0/src/metrogym/assets/trains/beijing_line_4_128x72.svg +25 -0
- metrogym-0.1.0/src/metrogym/assets/trains/beijing_line_4_192x108.svg +25 -0
- metrogym-0.1.0/src/metrogym/assets/trains/beijing_line_4_256x144.svg +25 -0
- metrogym-0.1.0/src/metrogym/assets/trains/beijing_line_4_64x36.svg +25 -0
- metrogym-0.1.0/src/metrogym/assets/trains/beijing_line_5_128x72.svg +25 -0
- metrogym-0.1.0/src/metrogym/assets/trains/beijing_line_5_192x108.svg +25 -0
- metrogym-0.1.0/src/metrogym/assets/trains/beijing_line_5_256x144.svg +25 -0
- metrogym-0.1.0/src/metrogym/assets/trains/beijing_line_5_64x36.svg +25 -0
- metrogym-0.1.0/src/metrogym/assets/trains/bullet_metro_128x80.svg +12 -0
- metrogym-0.1.0/src/metrogym/assets/trains/bullet_metro_192x120.svg +12 -0
- metrogym-0.1.0/src/metrogym/assets/trains/bullet_metro_256x160.svg +12 -0
- metrogym-0.1.0/src/metrogym/assets/trains/bullet_metro_64x40.svg +12 -0
- metrogym-0.1.0/src/metrogym/assets/trains/city_tram_128x80.svg +13 -0
- metrogym-0.1.0/src/metrogym/assets/trains/city_tram_192x120.svg +13 -0
- metrogym-0.1.0/src/metrogym/assets/trains/city_tram_256x160.svg +13 -0
- metrogym-0.1.0/src/metrogym/assets/trains/city_tram_64x40.svg +13 -0
- metrogym-0.1.0/src/metrogym/assets/trains/maintenance_128x80.svg +14 -0
- metrogym-0.1.0/src/metrogym/assets/trains/maintenance_192x120.svg +14 -0
- metrogym-0.1.0/src/metrogym/assets/trains/maintenance_256x160.svg +14 -0
- metrogym-0.1.0/src/metrogym/assets/trains/maintenance_64x40.svg +14 -0
- metrogym-0.1.0/src/metrogym/assets/trains/metro_nose_128x80.svg +3 -0
- metrogym-0.1.0/src/metrogym/assets/trains/metro_nose_192x120.svg +3 -0
- metrogym-0.1.0/src/metrogym/assets/trains/metro_nose_256x160.svg +3 -0
- metrogym-0.1.0/src/metrogym/assets/trains/metro_nose_64x40.svg +3 -0
- metrogym-0.1.0/src/metrogym/context.py +46 -0
- metrogym-0.1.0/src/metrogym/controls.py +182 -0
- metrogym-0.1.0/src/metrogym/core/__init__.py +97 -0
- metrogym-0.1.0/src/metrogym/core/colors.py +214 -0
- metrogym-0.1.0/src/metrogym/core/constants.py +37 -0
- metrogym-0.1.0/src/metrogym/core/coordinates.py +146 -0
- metrogym-0.1.0/src/metrogym/core/signal_assets.py +146 -0
- metrogym-0.1.0/src/metrogym/core/train_assets.py +174 -0
- metrogym-0.1.0/src/metrogym/core/ui_modes.py +71 -0
- metrogym-0.1.0/src/metrogym/events.py +32 -0
- metrogym-0.1.0/src/metrogym/primitives/__init__.py +15 -0
- metrogym-0.1.0/src/metrogym/primitives/line/__init__.py +9 -0
- metrogym-0.1.0/src/metrogym/primitives/line/control.py +1 -0
- metrogym-0.1.0/src/metrogym/primitives/line/extras/__init__.py +7 -0
- metrogym-0.1.0/src/metrogym/primitives/line/extras/path.py +57 -0
- metrogym-0.1.0/src/metrogym/primitives/line/line.py +89 -0
- metrogym-0.1.0/src/metrogym/primitives/line/runtime.py +25 -0
- metrogym-0.1.0/src/metrogym/primitives/network.py +80 -0
- metrogym-0.1.0/src/metrogym/primitives/signal/__init__.py +19 -0
- metrogym-0.1.0/src/metrogym/primitives/signal/control.py +34 -0
- metrogym-0.1.0/src/metrogym/primitives/signal/extras/__init__.py +8 -0
- metrogym-0.1.0/src/metrogym/primitives/signal/extras/control_rule.py +34 -0
- metrogym-0.1.0/src/metrogym/primitives/signal/extras/llm_signal_queue_providers/__init__.py +5 -0
- metrogym-0.1.0/src/metrogym/primitives/signal/extras/llm_signal_queue_providers/openai.py +86 -0
- metrogym-0.1.0/src/metrogym/primitives/signal/llm_signal_queue_handler.py +339 -0
- metrogym-0.1.0/src/metrogym/primitives/signal/runtime.py +72 -0
- metrogym-0.1.0/src/metrogym/primitives/signal/signal.py +160 -0
- metrogym-0.1.0/src/metrogym/primitives/station/__init__.py +7 -0
- metrogym-0.1.0/src/metrogym/primitives/station/control.py +1 -0
- metrogym-0.1.0/src/metrogym/primitives/station/runtime.py +21 -0
- metrogym-0.1.0/src/metrogym/primitives/station/station.py +89 -0
- metrogym-0.1.0/src/metrogym/primitives/train/__init__.py +7 -0
- metrogym-0.1.0/src/metrogym/primitives/train/control.py +1 -0
- metrogym-0.1.0/src/metrogym/primitives/train/runtime.py +195 -0
- metrogym-0.1.0/src/metrogym/primitives/train/train.py +131 -0
- metrogym-0.1.0/src/metrogym/rendering/__init__.py +10 -0
- metrogym-0.1.0/src/metrogym/rendering/_utils/__init__.py +5 -0
- metrogym-0.1.0/src/metrogym/rendering/_utils/gfx.py +114 -0
- metrogym-0.1.0/src/metrogym/rendering/_utils/keyboard.py +34 -0
- metrogym-0.1.0/src/metrogym/rendering/panel.py +200 -0
- metrogym-0.1.0/src/metrogym/rendering/primitives/__init__.py +5 -0
- metrogym-0.1.0/src/metrogym/rendering/primitives/metrogym_renderer/__init__.py +7 -0
- metrogym-0.1.0/src/metrogym/rendering/primitives/metrogym_renderer/metrogym_renderer.py +72 -0
- metrogym-0.1.0/src/metrogym/rendering/primitives/metrogym_renderer/runtime.py +254 -0
- metrogym-0.1.0/src/metrogym/rules/validation.yaml +76 -0
- metrogym-0.1.0/src/metrogym/runtimes.py +399 -0
- metrogym-0.1.0/src/metrogym/solvers.py +1097 -0
- metrogym-0.1.0/src/metrogym/system.py +425 -0
- metrogym-0.1.0/src/metrogym/templates/__init__.py +5 -0
- metrogym-0.1.0/src/metrogym/templates/primitive.py +40 -0
- metrogym-0.1.0/src/metrogym/validation.py +118 -0
metrogym-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Larry Lin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
metrogym-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: metrogym
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Build and control metro simulations with explicit, typed pipelines.
|
|
5
|
+
Project-URL: Documentation, https://metrogym.readthedocs.io/en/latest/
|
|
6
|
+
Project-URL: Source, https://github.com/larrywhizz767-png/MetroGYM
|
|
7
|
+
Project-URL: Issues, https://github.com/larrywhizz767-png/MetroGYM/issues
|
|
8
|
+
Project-URL: Releases, https://github.com/larrywhizz767-png/MetroGYM/releases
|
|
9
|
+
Author: Larry Lin
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: education,metro,pygame,simulation,transport
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Education
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Education
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering
|
|
24
|
+
Requires-Python: <3.14,>=3.10
|
|
25
|
+
Requires-Dist: beartype>=0.22.9
|
|
26
|
+
Requires-Dist: pygame>=2.6.1
|
|
27
|
+
Provides-Extra: llm
|
|
28
|
+
Requires-Dist: ell-ai[all]>=0.0.16; extra == 'llm'
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
<!--suppress HtmlDeprecatedAttribute -->
|
|
32
|
+
<div align="center">
|
|
33
|
+
<p align="center">
|
|
34
|
+
<br>
|
|
35
|
+
<a href="docs/assets/images/branding/metrogym-homepage-cover.jpg">
|
|
36
|
+
<img src="docs/assets/images/branding/metrogym-homepage-cover.jpg" alt="MetroGYM banner">
|
|
37
|
+
</a>
|
|
38
|
+
</p>
|
|
39
|
+
<h4 align="center">
|
|
40
|
+
A pure Python pygame MetroGYM teaching library for metro-network simulation and control logic —
|
|
41
|
+
<a href="https://metrogym.readthedocs.io/">Documentation</a> ·
|
|
42
|
+
<a href="https://github.com/larrywhizz767-png/MetroGYM">GitHub</a> ·
|
|
43
|
+
<a href="https://pypi.org/project/metrogym/">PyPi Index</a>
|
|
44
|
+
</h4>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<div align="center">
|
|
48
|
+
|
|
49
|
+
<a href="https://github.com/larrywhizz767-png/MetroGYM">
|
|
50
|
+
<img alt="pytest" src="https://img.shields.io/static/v1?label=Pytest&message=passing&color=472727&labelColor=FD706B&style=for-the-badge&logo=pytest&logoColor=white">
|
|
51
|
+
</a>
|
|
52
|
+
|
|
53
|
+
<img src="https://img.shields.io/static/v1?label=Ruff&message=compliant&color=472727&labelColor=FD706B&style=for-the-badge&logo=ruff&logoColor=white" alt="Ruff compliant">
|
|
54
|
+
|
|
55
|
+
<img src="https://img.shields.io/static/v1?label=UV&message=managed&color=472727&labelColor=FD706B&style=for-the-badge&logo=uv&logoColor=white" alt="UV Managed">
|
|
56
|
+
|
|
57
|
+
<img src="https://img.shields.io/static/v1?label=Python&message=3.10%E2%80%933.13&color=472727&labelColor=FD706B&style=for-the-badge&logo=python&logoColor=white" alt="Python 3.10–3.13">
|
|
58
|
+
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
## <a id="about-the-project"></a><img src="docs/assets/icons/lucide/github.svg" width="32" alt="" /> About The Project
|
|
62
|
+
|
|
63
|
+
`MetroGYM` is a pure Python, pygame-powered teaching library for metro-network simulation, signalling, and control logic. It is intentionally small and inspectable: you build a network from primitives, attach train and signal agents, then run it visually or headlessly.
|
|
64
|
+
|
|
65
|
+
MetroGYM allows you to build complex metro systems from explicit primitives, then drive those worlds with typed train and signal solvers. It's designed for educational purposes, providing a clear and interactive way to understand transport network dynamics and algorithmic control.
|
|
66
|
+
|
|
67
|
+
[See more in the documentation.](https://metrogym.readthedocs.io/)
|
|
68
|
+
|
|
69
|
+
## <a id="installation"></a><img src="docs/assets/icons/lucide/terminal.svg" width="32" alt="" /> Installation
|
|
70
|
+
|
|
71
|
+
> [!WARNING]
|
|
72
|
+
> **Pip is incoming!** MetroGYM is currently in early development and not yet available on PyPi.
|
|
73
|
+
|
|
74
|
+
### Prerequisites
|
|
75
|
+
|
|
76
|
+
Before you begin, ensure you have the following installed on your system:
|
|
77
|
+
|
|
78
|
+
- **Git**: For cloning the repository.
|
|
79
|
+
- **uv**: The recommended Python package and project manager. Install it via [astral.sh/uv](https://astral.sh/uv).
|
|
80
|
+
|
|
81
|
+
### Install From Source
|
|
82
|
+
|
|
83
|
+
1. **Clone the repository:**
|
|
84
|
+
```bash
|
|
85
|
+
git clone https://github.com/larrywhizz767-png/MetroGYM.git
|
|
86
|
+
cd MetroGYM
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
2. **Sync the environment:**
|
|
90
|
+
`uv` will automatically create a virtual environment, install the correct Python version, and fetch all dependencies (including `pygame` and `beartype`).
|
|
91
|
+
```bash
|
|
92
|
+
uv sync
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
3. **Verify the installation:**
|
|
96
|
+
Run a quick check to ensure everything is set up correctly:
|
|
97
|
+
```bash
|
|
98
|
+
uv run python -m compileall src
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## <a id="getting-started"></a><img src="docs/assets/icons/lucide/square-code.svg" width="32" alt="" /> Getting Started
|
|
102
|
+
|
|
103
|
+
To build your first simulation, you define the world through a pipeline of explicit primitives:
|
|
104
|
+
|
|
105
|
+
1. **Initialise the System**: Create a `MetroSystem` to manage the lifecycle and rendering.
|
|
106
|
+
2. **Define the Infrastructure**: Use a `Network` to group your `Line` paths and `Station` locations.
|
|
107
|
+
3. **Attach Agents**: Add a `Train` with a specific `solver` (the agent's brain) and a `Signal` that controls access to specific track segments.
|
|
108
|
+
4. **Build and Run**: Call `.fit()` to validate the topology and `.run()` to start the interactive simulation.
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
from metrogym import Color, MetroSystem, signal, train
|
|
112
|
+
from metrogym.primitives import ControlRule, Line, Network, Signal, Station, Train
|
|
113
|
+
|
|
114
|
+
system = MetroSystem(name="Quick Start", render_scale=2).pipeline([
|
|
115
|
+
Network([
|
|
116
|
+
Line("Loop", Color.BLUE, [(120, 120), (560, 120), (560, 360), (120, 360), (120, 120)]),
|
|
117
|
+
Station("West", (120, 120)),
|
|
118
|
+
Station("North", (560, 120)),
|
|
119
|
+
Station("South", (560, 360)),
|
|
120
|
+
]),
|
|
121
|
+
Train("A", line="Loop", solver=train.always_proceed(), asset="metro_nose"),
|
|
122
|
+
Signal(
|
|
123
|
+
"North Gate",
|
|
124
|
+
(560, 85),
|
|
125
|
+
controls=ControlRule("Loop", (560, 120), (560, 360)),
|
|
126
|
+
solver=signal.pulse(green_ticks=5, red_ticks=3),
|
|
127
|
+
),
|
|
128
|
+
])
|
|
129
|
+
|
|
130
|
+
system.fit().run()
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## <a id="local-documentation"></a><img src="docs/assets/icons/lucide/file-stack.svg" width="32" alt="" /> Local Documentation
|
|
134
|
+
|
|
135
|
+
To run the documentation locally, ensure you have the `docs` dependencies installed and run:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
uv sync --group docs
|
|
139
|
+
uv run zensical serve
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## <a id="license"></a><img src="docs/assets/icons/lucide/fingerprint-pattern.svg" width="32" alt="" /> License
|
|
143
|
+
|
|
144
|
+
MetroGYM is licensed under the [MIT License](https://opensource.org/licenses/MIT).
|
metrogym-0.1.0/README.md
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
<!--suppress HtmlDeprecatedAttribute -->
|
|
2
|
+
<div align="center">
|
|
3
|
+
<p align="center">
|
|
4
|
+
<br>
|
|
5
|
+
<a href="docs/assets/images/branding/metrogym-homepage-cover.jpg">
|
|
6
|
+
<img src="docs/assets/images/branding/metrogym-homepage-cover.jpg" alt="MetroGYM banner">
|
|
7
|
+
</a>
|
|
8
|
+
</p>
|
|
9
|
+
<h4 align="center">
|
|
10
|
+
A pure Python pygame MetroGYM teaching library for metro-network simulation and control logic —
|
|
11
|
+
<a href="https://metrogym.readthedocs.io/">Documentation</a> ·
|
|
12
|
+
<a href="https://github.com/larrywhizz767-png/MetroGYM">GitHub</a> ·
|
|
13
|
+
<a href="https://pypi.org/project/metrogym/">PyPi Index</a>
|
|
14
|
+
</h4>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<div align="center">
|
|
18
|
+
|
|
19
|
+
<a href="https://github.com/larrywhizz767-png/MetroGYM">
|
|
20
|
+
<img alt="pytest" src="https://img.shields.io/static/v1?label=Pytest&message=passing&color=472727&labelColor=FD706B&style=for-the-badge&logo=pytest&logoColor=white">
|
|
21
|
+
</a>
|
|
22
|
+
|
|
23
|
+
<img src="https://img.shields.io/static/v1?label=Ruff&message=compliant&color=472727&labelColor=FD706B&style=for-the-badge&logo=ruff&logoColor=white" alt="Ruff compliant">
|
|
24
|
+
|
|
25
|
+
<img src="https://img.shields.io/static/v1?label=UV&message=managed&color=472727&labelColor=FD706B&style=for-the-badge&logo=uv&logoColor=white" alt="UV Managed">
|
|
26
|
+
|
|
27
|
+
<img src="https://img.shields.io/static/v1?label=Python&message=3.10%E2%80%933.13&color=472727&labelColor=FD706B&style=for-the-badge&logo=python&logoColor=white" alt="Python 3.10–3.13">
|
|
28
|
+
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
## <a id="about-the-project"></a><img src="docs/assets/icons/lucide/github.svg" width="32" alt="" /> About The Project
|
|
32
|
+
|
|
33
|
+
`MetroGYM` is a pure Python, pygame-powered teaching library for metro-network simulation, signalling, and control logic. It is intentionally small and inspectable: you build a network from primitives, attach train and signal agents, then run it visually or headlessly.
|
|
34
|
+
|
|
35
|
+
MetroGYM allows you to build complex metro systems from explicit primitives, then drive those worlds with typed train and signal solvers. It's designed for educational purposes, providing a clear and interactive way to understand transport network dynamics and algorithmic control.
|
|
36
|
+
|
|
37
|
+
[See more in the documentation.](https://metrogym.readthedocs.io/)
|
|
38
|
+
|
|
39
|
+
## <a id="installation"></a><img src="docs/assets/icons/lucide/terminal.svg" width="32" alt="" /> Installation
|
|
40
|
+
|
|
41
|
+
> [!WARNING]
|
|
42
|
+
> **Pip is incoming!** MetroGYM is currently in early development and not yet available on PyPi.
|
|
43
|
+
|
|
44
|
+
### Prerequisites
|
|
45
|
+
|
|
46
|
+
Before you begin, ensure you have the following installed on your system:
|
|
47
|
+
|
|
48
|
+
- **Git**: For cloning the repository.
|
|
49
|
+
- **uv**: The recommended Python package and project manager. Install it via [astral.sh/uv](https://astral.sh/uv).
|
|
50
|
+
|
|
51
|
+
### Install From Source
|
|
52
|
+
|
|
53
|
+
1. **Clone the repository:**
|
|
54
|
+
```bash
|
|
55
|
+
git clone https://github.com/larrywhizz767-png/MetroGYM.git
|
|
56
|
+
cd MetroGYM
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
2. **Sync the environment:**
|
|
60
|
+
`uv` will automatically create a virtual environment, install the correct Python version, and fetch all dependencies (including `pygame` and `beartype`).
|
|
61
|
+
```bash
|
|
62
|
+
uv sync
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
3. **Verify the installation:**
|
|
66
|
+
Run a quick check to ensure everything is set up correctly:
|
|
67
|
+
```bash
|
|
68
|
+
uv run python -m compileall src
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## <a id="getting-started"></a><img src="docs/assets/icons/lucide/square-code.svg" width="32" alt="" /> Getting Started
|
|
72
|
+
|
|
73
|
+
To build your first simulation, you define the world through a pipeline of explicit primitives:
|
|
74
|
+
|
|
75
|
+
1. **Initialise the System**: Create a `MetroSystem` to manage the lifecycle and rendering.
|
|
76
|
+
2. **Define the Infrastructure**: Use a `Network` to group your `Line` paths and `Station` locations.
|
|
77
|
+
3. **Attach Agents**: Add a `Train` with a specific `solver` (the agent's brain) and a `Signal` that controls access to specific track segments.
|
|
78
|
+
4. **Build and Run**: Call `.fit()` to validate the topology and `.run()` to start the interactive simulation.
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
from metrogym import Color, MetroSystem, signal, train
|
|
82
|
+
from metrogym.primitives import ControlRule, Line, Network, Signal, Station, Train
|
|
83
|
+
|
|
84
|
+
system = MetroSystem(name="Quick Start", render_scale=2).pipeline([
|
|
85
|
+
Network([
|
|
86
|
+
Line("Loop", Color.BLUE, [(120, 120), (560, 120), (560, 360), (120, 360), (120, 120)]),
|
|
87
|
+
Station("West", (120, 120)),
|
|
88
|
+
Station("North", (560, 120)),
|
|
89
|
+
Station("South", (560, 360)),
|
|
90
|
+
]),
|
|
91
|
+
Train("A", line="Loop", solver=train.always_proceed(), asset="metro_nose"),
|
|
92
|
+
Signal(
|
|
93
|
+
"North Gate",
|
|
94
|
+
(560, 85),
|
|
95
|
+
controls=ControlRule("Loop", (560, 120), (560, 360)),
|
|
96
|
+
solver=signal.pulse(green_ticks=5, red_ticks=3),
|
|
97
|
+
),
|
|
98
|
+
])
|
|
99
|
+
|
|
100
|
+
system.fit().run()
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## <a id="local-documentation"></a><img src="docs/assets/icons/lucide/file-stack.svg" width="32" alt="" /> Local Documentation
|
|
104
|
+
|
|
105
|
+
To run the documentation locally, ensure you have the `docs` dependencies installed and run:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
uv sync --group docs
|
|
109
|
+
uv run zensical serve
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## <a id="license"></a><img src="docs/assets/icons/lucide/fingerprint-pattern.svg" width="32" alt="" /> License
|
|
113
|
+
|
|
114
|
+
MetroGYM is licensed under the [MIT License](https://opensource.org/licenses/MIT).
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "metrogym"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Build and control metro simulations with explicit, typed pipelines."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10,<3.14"
|
|
7
|
+
authors = [{ name = "Larry Lin" }]
|
|
8
|
+
license = "MIT"
|
|
9
|
+
license-files = ["LICENSE"]
|
|
10
|
+
keywords = ["metro", "simulation", "education", "pygame", "transport"]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 3 - Alpha",
|
|
13
|
+
"Intended Audience :: Education",
|
|
14
|
+
"Intended Audience :: Science/Research",
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
17
|
+
"Programming Language :: Python :: 3.10",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
21
|
+
"Topic :: Education",
|
|
22
|
+
"Topic :: Scientific/Engineering",
|
|
23
|
+
]
|
|
24
|
+
dependencies = [
|
|
25
|
+
"beartype>=0.22.9",
|
|
26
|
+
"pygame>=2.6.1",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.urls]
|
|
30
|
+
Documentation = "https://metrogym.readthedocs.io/en/latest/"
|
|
31
|
+
Source = "https://github.com/larrywhizz767-png/MetroGYM"
|
|
32
|
+
Issues = "https://github.com/larrywhizz767-png/MetroGYM/issues"
|
|
33
|
+
Releases = "https://github.com/larrywhizz767-png/MetroGYM/releases"
|
|
34
|
+
|
|
35
|
+
[project.optional-dependencies]
|
|
36
|
+
llm = [
|
|
37
|
+
"ell-ai[all]>=0.0.16",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[build-system]
|
|
41
|
+
requires = ["hatchling>=1.27"]
|
|
42
|
+
build-backend = "hatchling.build"
|
|
43
|
+
|
|
44
|
+
[tool.hatch.build.targets.sdist]
|
|
45
|
+
only-include = ["src/metrogym", "pyproject.toml", "README.md", "LICENSE"]
|
|
46
|
+
|
|
47
|
+
[tool.hatch.build.targets.wheel]
|
|
48
|
+
packages = ["src/metrogym"]
|
|
49
|
+
|
|
50
|
+
[dependency-groups]
|
|
51
|
+
docs = [
|
|
52
|
+
"mkdocs>=1.6.1",
|
|
53
|
+
"mkdocstrings[python]>=0.25",
|
|
54
|
+
"mkdocstrings-python>=1.16.10",
|
|
55
|
+
"pymdown-extensions>=10.14.3",
|
|
56
|
+
"zensical>=0.0.33",
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
[tool.uv]
|
|
60
|
+
package = true
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"""MetroGYM public package exports.
|
|
2
|
+
|
|
3
|
+
Import from this module when writing user-facing MetroGYM code. It re-exports
|
|
4
|
+
core primitives, runtime-facing solver helpers, rendering entry points, and
|
|
5
|
+
asset utilities intended for the public API surface.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from metrogym.controls import ControlSystem, SignalRule
|
|
9
|
+
from metrogym.core import Color, ColorRGBA, Position
|
|
10
|
+
from metrogym.core.signal_assets import SignalAsset, SignalAssetState, load_signal_asset_surface, signal_asset
|
|
11
|
+
from metrogym.core.train_assets import TrainAsset, TrainAssetName, load_train_asset_surface, train_asset
|
|
12
|
+
from metrogym.events import CollisionEvent
|
|
13
|
+
from metrogym.primitives import ControlRule, LLMSignalQueueHandler, Line, Network, Signal, Station, Train
|
|
14
|
+
from metrogym.primitives.line import build_path
|
|
15
|
+
from metrogym.primitives.signal import BaseLLMProvider, BaseLLMQueueSignalAgent, OpenAIELLProvider, SignalQueueCandidate, SignalQueuePlan, TrafficLight
|
|
16
|
+
from metrogym.rendering import MetroGYMRenderer, SimulationPanel
|
|
17
|
+
from metrogym.solvers import (
|
|
18
|
+
AllOfTrainPolicies,
|
|
19
|
+
AlwaysRunSolver,
|
|
20
|
+
AlwaysStopSolver,
|
|
21
|
+
AnyOfTrainPolicies,
|
|
22
|
+
CollisionAwareSolver,
|
|
23
|
+
CompositeTrainSolver,
|
|
24
|
+
FixedSignalSolver,
|
|
25
|
+
PriorityQueueSignalSolver,
|
|
26
|
+
PulseSignalSolver,
|
|
27
|
+
PulseTrainSolver,
|
|
28
|
+
RedSignalStopSolver,
|
|
29
|
+
SignalAgent,
|
|
30
|
+
SignalDecision,
|
|
31
|
+
SignalObservation,
|
|
32
|
+
SignalQueueView,
|
|
33
|
+
SignalSnapshot,
|
|
34
|
+
SignalSolver,
|
|
35
|
+
SignalVerb,
|
|
36
|
+
SolverAction,
|
|
37
|
+
TrainAgent,
|
|
38
|
+
TrainDecision,
|
|
39
|
+
TrainObservation,
|
|
40
|
+
TrainSignalView,
|
|
41
|
+
TrainSnapshot,
|
|
42
|
+
TrainSolver,
|
|
43
|
+
TrainVerb,
|
|
44
|
+
WorldView,
|
|
45
|
+
distance_to_rule,
|
|
46
|
+
signal,
|
|
47
|
+
train,
|
|
48
|
+
)
|
|
49
|
+
from metrogym.system import MetroSystem
|
|
50
|
+
|
|
51
|
+
__all__ = [
|
|
52
|
+
"MetroSystem",
|
|
53
|
+
"SimulationPanel",
|
|
54
|
+
"Color",
|
|
55
|
+
"ColorRGBA",
|
|
56
|
+
"CollisionEvent",
|
|
57
|
+
"ControlRule",
|
|
58
|
+
"ControlSystem",
|
|
59
|
+
"MetroGYMRenderer",
|
|
60
|
+
"Network",
|
|
61
|
+
"Position",
|
|
62
|
+
"Signal",
|
|
63
|
+
"SignalRule",
|
|
64
|
+
"SignalAsset",
|
|
65
|
+
"SignalAssetState",
|
|
66
|
+
"Train",
|
|
67
|
+
"TrainAsset",
|
|
68
|
+
"TrainAssetName",
|
|
69
|
+
"TrafficLight",
|
|
70
|
+
"Station",
|
|
71
|
+
"Line",
|
|
72
|
+
"AllOfTrainPolicies",
|
|
73
|
+
"AlwaysRunSolver",
|
|
74
|
+
"AlwaysStopSolver",
|
|
75
|
+
"AnyOfTrainPolicies",
|
|
76
|
+
"BaseLLMProvider",
|
|
77
|
+
"BaseLLMQueueSignalAgent",
|
|
78
|
+
"CollisionAwareSolver",
|
|
79
|
+
"CompositeTrainSolver",
|
|
80
|
+
"FixedSignalSolver",
|
|
81
|
+
"LLMSignalQueueHandler",
|
|
82
|
+
"OpenAIELLProvider",
|
|
83
|
+
"PriorityQueueSignalSolver",
|
|
84
|
+
"PulseSignalSolver",
|
|
85
|
+
"PulseTrainSolver",
|
|
86
|
+
"RedSignalStopSolver",
|
|
87
|
+
"SignalAgent",
|
|
88
|
+
"SignalDecision",
|
|
89
|
+
"SignalObservation",
|
|
90
|
+
"SignalQueueCandidate",
|
|
91
|
+
"SignalQueuePlan",
|
|
92
|
+
"SignalQueueView",
|
|
93
|
+
"SignalSnapshot",
|
|
94
|
+
"SignalSolver",
|
|
95
|
+
"SignalVerb",
|
|
96
|
+
"SolverAction",
|
|
97
|
+
"TrainAgent",
|
|
98
|
+
"TrainDecision",
|
|
99
|
+
"TrainObservation",
|
|
100
|
+
"TrainSignalView",
|
|
101
|
+
"TrainSnapshot",
|
|
102
|
+
"TrainSolver",
|
|
103
|
+
"TrainVerb",
|
|
104
|
+
"WorldView",
|
|
105
|
+
"build_path",
|
|
106
|
+
"distance_to_rule",
|
|
107
|
+
"load_signal_asset_surface",
|
|
108
|
+
"load_train_asset_surface",
|
|
109
|
+
"signal",
|
|
110
|
+
"signal_asset",
|
|
111
|
+
"train",
|
|
112
|
+
"train_asset",
|
|
113
|
+
]
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="40" viewBox="0 0 24 61" shape-rendering="crispEdges" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">MetroGYM GO signal sprite 16x40</title>
|
|
3
|
+
<desc id="desc">Full-size B concept signal with green lamp lit and red lamp muted.</desc>
|
|
4
|
+
<rect x="6" y="48" width="12" height="4" rx="1.5" fill="#17131D"/>
|
|
5
|
+
<rect x="10" y="48" width="4" height="11" rx="1" fill="#3A3242" stroke="#7B1B83" stroke-width="0.5"/>
|
|
6
|
+
<polygon points="4,0 20,0 24,6 22,44 18,50 6,50 2,44 0,6" fill="#F05CFF"/>
|
|
7
|
+
<polygon points="5,3 19,3 21,7 19,45 5,45 3,7" fill="#2A2430" stroke="#7B1B83" stroke-width="0.6"/>
|
|
8
|
+
<rect x="7" y="7" width="10" height="14" rx="3" fill="#3A3242"/>
|
|
9
|
+
<rect x="7" y="29" width="10" height="14" rx="3" fill="#3A3242"/>
|
|
10
|
+
<circle cx="12" cy="14" r="5" fill="#6E1D2A" stroke="#7B1B83" stroke-width="0.75"/>
|
|
11
|
+
<circle cx="10.6" cy="12.4" r="1" fill="#F5EAFE" opacity="0.18"/>
|
|
12
|
+
<circle cx="12" cy="36" r="7.75" fill="#2DFF9A" opacity="0.42"/>
|
|
13
|
+
<circle cx="12" cy="36" r="5" fill="#2DFF9A" stroke="#7B1B83" stroke-width="0.75"/>
|
|
14
|
+
<circle cx="10.6" cy="34.4" r="1" fill="#F5EAFE" opacity="0.88"/>
|
|
15
|
+
<rect x="8" y="24" width="8" height="2" rx="1" fill="#8A8194" opacity="0.55"/>
|
|
16
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="31" height="80" viewBox="0 0 24 61" shape-rendering="crispEdges" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">MetroGYM GO signal sprite 31x80</title>
|
|
3
|
+
<desc id="desc">Full-size B concept signal with green lamp lit and red lamp muted.</desc>
|
|
4
|
+
<rect x="6" y="48" width="12" height="4" rx="1.5" fill="#17131D"/>
|
|
5
|
+
<rect x="10" y="48" width="4" height="11" rx="1" fill="#3A3242" stroke="#7B1B83" stroke-width="0.5"/>
|
|
6
|
+
<polygon points="4,0 20,0 24,6 22,44 18,50 6,50 2,44 0,6" fill="#F05CFF"/>
|
|
7
|
+
<polygon points="5,3 19,3 21,7 19,45 5,45 3,7" fill="#2A2430" stroke="#7B1B83" stroke-width="0.6"/>
|
|
8
|
+
<rect x="7" y="7" width="10" height="14" rx="3" fill="#3A3242"/>
|
|
9
|
+
<rect x="7" y="29" width="10" height="14" rx="3" fill="#3A3242"/>
|
|
10
|
+
<circle cx="12" cy="14" r="5" fill="#6E1D2A" stroke="#7B1B83" stroke-width="0.75"/>
|
|
11
|
+
<circle cx="10.6" cy="12.4" r="1" fill="#F5EAFE" opacity="0.18"/>
|
|
12
|
+
<circle cx="12" cy="36" r="7.75" fill="#2DFF9A" opacity="0.42"/>
|
|
13
|
+
<circle cx="12" cy="36" r="5" fill="#2DFF9A" stroke="#7B1B83" stroke-width="0.75"/>
|
|
14
|
+
<circle cx="10.6" cy="34.4" r="1" fill="#F5EAFE" opacity="0.88"/>
|
|
15
|
+
<rect x="8" y="24" width="8" height="2" rx="1" fill="#8A8194" opacity="0.55"/>
|
|
16
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="47" height="120" viewBox="0 0 24 61" shape-rendering="crispEdges" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">MetroGYM GO signal sprite 47x120</title>
|
|
3
|
+
<desc id="desc">Full-size B concept signal with green lamp lit and red lamp muted.</desc>
|
|
4
|
+
<rect x="6" y="48" width="12" height="4" rx="1.5" fill="#17131D"/>
|
|
5
|
+
<rect x="10" y="48" width="4" height="11" rx="1" fill="#3A3242" stroke="#7B1B83" stroke-width="0.5"/>
|
|
6
|
+
<polygon points="4,0 20,0 24,6 22,44 18,50 6,50 2,44 0,6" fill="#F05CFF"/>
|
|
7
|
+
<polygon points="5,3 19,3 21,7 19,45 5,45 3,7" fill="#2A2430" stroke="#7B1B83" stroke-width="0.6"/>
|
|
8
|
+
<rect x="7" y="7" width="10" height="14" rx="3" fill="#3A3242"/>
|
|
9
|
+
<rect x="7" y="29" width="10" height="14" rx="3" fill="#3A3242"/>
|
|
10
|
+
<circle cx="12" cy="14" r="5" fill="#6E1D2A" stroke="#7B1B83" stroke-width="0.75"/>
|
|
11
|
+
<circle cx="10.6" cy="12.4" r="1" fill="#F5EAFE" opacity="0.18"/>
|
|
12
|
+
<circle cx="12" cy="36" r="7.75" fill="#2DFF9A" opacity="0.42"/>
|
|
13
|
+
<circle cx="12" cy="36" r="5" fill="#2DFF9A" stroke="#7B1B83" stroke-width="0.75"/>
|
|
14
|
+
<circle cx="10.6" cy="34.4" r="1" fill="#F5EAFE" opacity="0.88"/>
|
|
15
|
+
<rect x="8" y="24" width="8" height="2" rx="1" fill="#8A8194" opacity="0.55"/>
|
|
16
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="63" height="160" viewBox="0 0 24 61" shape-rendering="crispEdges" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">MetroGYM GO signal sprite 63x160</title>
|
|
3
|
+
<desc id="desc">Full-size B concept signal with green lamp lit and red lamp muted.</desc>
|
|
4
|
+
<rect x="6" y="48" width="12" height="4" rx="1.5" fill="#17131D"/>
|
|
5
|
+
<rect x="10" y="48" width="4" height="11" rx="1" fill="#3A3242" stroke="#7B1B83" stroke-width="0.5"/>
|
|
6
|
+
<polygon points="4,0 20,0 24,6 22,44 18,50 6,50 2,44 0,6" fill="#F05CFF"/>
|
|
7
|
+
<polygon points="5,3 19,3 21,7 19,45 5,45 3,7" fill="#2A2430" stroke="#7B1B83" stroke-width="0.6"/>
|
|
8
|
+
<rect x="7" y="7" width="10" height="14" rx="3" fill="#3A3242"/>
|
|
9
|
+
<rect x="7" y="29" width="10" height="14" rx="3" fill="#3A3242"/>
|
|
10
|
+
<circle cx="12" cy="14" r="5" fill="#6E1D2A" stroke="#7B1B83" stroke-width="0.75"/>
|
|
11
|
+
<circle cx="10.6" cy="12.4" r="1" fill="#F5EAFE" opacity="0.18"/>
|
|
12
|
+
<circle cx="12" cy="36" r="7.75" fill="#2DFF9A" opacity="0.42"/>
|
|
13
|
+
<circle cx="12" cy="36" r="5" fill="#2DFF9A" stroke="#7B1B83" stroke-width="0.75"/>
|
|
14
|
+
<circle cx="10.6" cy="34.4" r="1" fill="#F5EAFE" opacity="0.88"/>
|
|
15
|
+
<rect x="8" y="24" width="8" height="2" rx="1" fill="#8A8194" opacity="0.55"/>
|
|
16
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="40" viewBox="0 0 24 61" shape-rendering="crispEdges" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">MetroGYM STOP signal sprite 16x40</title>
|
|
3
|
+
<desc id="desc">Full-size A concept signal with red lamp lit and green lamp muted.</desc>
|
|
4
|
+
<rect x="6" y="48" width="12" height="4" rx="1.5" fill="#17131D"/>
|
|
5
|
+
<rect x="10" y="48" width="4" height="11" rx="1" fill="#3A3242" stroke="#7B1B83" stroke-width="0.5"/>
|
|
6
|
+
<polygon points="4,0 20,0 24,6 22,44 18,50 6,50 2,44 0,6" fill="#F05CFF"/>
|
|
7
|
+
<polygon points="5,3 19,3 21,7 19,45 5,45 3,7" fill="#2A2430" stroke="#7B1B83" stroke-width="0.6"/>
|
|
8
|
+
<rect x="7" y="7" width="10" height="14" rx="3" fill="#3A3242"/>
|
|
9
|
+
<rect x="7" y="29" width="10" height="14" rx="3" fill="#3A3242"/>
|
|
10
|
+
<circle cx="12" cy="14" r="7.75" fill="#FF3F55" opacity="0.42"/>
|
|
11
|
+
<circle cx="12" cy="14" r="5" fill="#FF3F55" stroke="#7B1B83" stroke-width="0.75"/>
|
|
12
|
+
<circle cx="10.6" cy="12.4" r="1" fill="#F5EAFE" opacity="0.88"/>
|
|
13
|
+
<circle cx="12" cy="36" r="5" fill="#1C5F45" stroke="#7B1B83" stroke-width="0.75"/>
|
|
14
|
+
<circle cx="10.6" cy="34.4" r="1" fill="#F5EAFE" opacity="0.18"/>
|
|
15
|
+
<rect x="8" y="24" width="8" height="2" rx="1" fill="#8A8194" opacity="0.55"/>
|
|
16
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="31" height="80" viewBox="0 0 24 61" shape-rendering="crispEdges" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">MetroGYM STOP signal sprite 31x80</title>
|
|
3
|
+
<desc id="desc">Full-size A concept signal with red lamp lit and green lamp muted.</desc>
|
|
4
|
+
<rect x="6" y="48" width="12" height="4" rx="1.5" fill="#17131D"/>
|
|
5
|
+
<rect x="10" y="48" width="4" height="11" rx="1" fill="#3A3242" stroke="#7B1B83" stroke-width="0.5"/>
|
|
6
|
+
<polygon points="4,0 20,0 24,6 22,44 18,50 6,50 2,44 0,6" fill="#F05CFF"/>
|
|
7
|
+
<polygon points="5,3 19,3 21,7 19,45 5,45 3,7" fill="#2A2430" stroke="#7B1B83" stroke-width="0.6"/>
|
|
8
|
+
<rect x="7" y="7" width="10" height="14" rx="3" fill="#3A3242"/>
|
|
9
|
+
<rect x="7" y="29" width="10" height="14" rx="3" fill="#3A3242"/>
|
|
10
|
+
<circle cx="12" cy="14" r="7.75" fill="#FF3F55" opacity="0.42"/>
|
|
11
|
+
<circle cx="12" cy="14" r="5" fill="#FF3F55" stroke="#7B1B83" stroke-width="0.75"/>
|
|
12
|
+
<circle cx="10.6" cy="12.4" r="1" fill="#F5EAFE" opacity="0.88"/>
|
|
13
|
+
<circle cx="12" cy="36" r="5" fill="#1C5F45" stroke="#7B1B83" stroke-width="0.75"/>
|
|
14
|
+
<circle cx="10.6" cy="34.4" r="1" fill="#F5EAFE" opacity="0.18"/>
|
|
15
|
+
<rect x="8" y="24" width="8" height="2" rx="1" fill="#8A8194" opacity="0.55"/>
|
|
16
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="47" height="120" viewBox="0 0 24 61" shape-rendering="crispEdges" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">MetroGYM STOP signal sprite 47x120</title>
|
|
3
|
+
<desc id="desc">Full-size A concept signal with red lamp lit and green lamp muted.</desc>
|
|
4
|
+
<rect x="6" y="48" width="12" height="4" rx="1.5" fill="#17131D"/>
|
|
5
|
+
<rect x="10" y="48" width="4" height="11" rx="1" fill="#3A3242" stroke="#7B1B83" stroke-width="0.5"/>
|
|
6
|
+
<polygon points="4,0 20,0 24,6 22,44 18,50 6,50 2,44 0,6" fill="#F05CFF"/>
|
|
7
|
+
<polygon points="5,3 19,3 21,7 19,45 5,45 3,7" fill="#2A2430" stroke="#7B1B83" stroke-width="0.6"/>
|
|
8
|
+
<rect x="7" y="7" width="10" height="14" rx="3" fill="#3A3242"/>
|
|
9
|
+
<rect x="7" y="29" width="10" height="14" rx="3" fill="#3A3242"/>
|
|
10
|
+
<circle cx="12" cy="14" r="7.75" fill="#FF3F55" opacity="0.42"/>
|
|
11
|
+
<circle cx="12" cy="14" r="5" fill="#FF3F55" stroke="#7B1B83" stroke-width="0.75"/>
|
|
12
|
+
<circle cx="10.6" cy="12.4" r="1" fill="#F5EAFE" opacity="0.88"/>
|
|
13
|
+
<circle cx="12" cy="36" r="5" fill="#1C5F45" stroke="#7B1B83" stroke-width="0.75"/>
|
|
14
|
+
<circle cx="10.6" cy="34.4" r="1" fill="#F5EAFE" opacity="0.18"/>
|
|
15
|
+
<rect x="8" y="24" width="8" height="2" rx="1" fill="#8A8194" opacity="0.55"/>
|
|
16
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="63" height="160" viewBox="0 0 24 61" shape-rendering="crispEdges" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">MetroGYM STOP signal sprite 63x160</title>
|
|
3
|
+
<desc id="desc">Full-size A concept signal with red lamp lit and green lamp muted.</desc>
|
|
4
|
+
<rect x="6" y="48" width="12" height="4" rx="1.5" fill="#17131D"/>
|
|
5
|
+
<rect x="10" y="48" width="4" height="11" rx="1" fill="#3A3242" stroke="#7B1B83" stroke-width="0.5"/>
|
|
6
|
+
<polygon points="4,0 20,0 24,6 22,44 18,50 6,50 2,44 0,6" fill="#F05CFF"/>
|
|
7
|
+
<polygon points="5,3 19,3 21,7 19,45 5,45 3,7" fill="#2A2430" stroke="#7B1B83" stroke-width="0.6"/>
|
|
8
|
+
<rect x="7" y="7" width="10" height="14" rx="3" fill="#3A3242"/>
|
|
9
|
+
<rect x="7" y="29" width="10" height="14" rx="3" fill="#3A3242"/>
|
|
10
|
+
<circle cx="12" cy="14" r="7.75" fill="#FF3F55" opacity="0.42"/>
|
|
11
|
+
<circle cx="12" cy="14" r="5" fill="#FF3F55" stroke="#7B1B83" stroke-width="0.75"/>
|
|
12
|
+
<circle cx="10.6" cy="12.4" r="1" fill="#F5EAFE" opacity="0.88"/>
|
|
13
|
+
<circle cx="12" cy="36" r="5" fill="#1C5F45" stroke="#7B1B83" stroke-width="0.75"/>
|
|
14
|
+
<circle cx="10.6" cy="34.4" r="1" fill="#F5EAFE" opacity="0.18"/>
|
|
15
|
+
<rect x="8" y="24" width="8" height="2" rx="1" fill="#8A8194" opacity="0.55"/>
|
|
16
|
+
</svg>
|