Skip to content

Commit

Permalink
Docu for compontents
Browse files Browse the repository at this point in the history
  • Loading branch information
Maximilian Weichart committed May 8, 2024
1 parent 8d9897a commit 041bd96
Show file tree
Hide file tree
Showing 15 changed files with 186 additions and 35 deletions.
Binary file added docs/_static/components/holder.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/components/queue.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/components/tetromino.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions docs/components/holder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Holder

![Queue](../_static/components/holder.png)

```{eval-rst}
.. autoclass:: tetris_gymnasium.components.tetromino_holder.TetrominoHolder
```

## Methods
```{eval-rst}
.. automethod:: tetris_gymnasium.components.tetromino_holder.TetrominoHolder.swap
.. automethod:: tetris_gymnasium.components.tetromino_holder.TetrominoHolder.reset
.. automethod:: tetris_gymnasium.components.tetromino_holder.TetrominoHolder.get_tetrominoes
```
14 changes: 14 additions & 0 deletions docs/components/queue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Queue

![Queue](../_static/components/queue.png)

```{eval-rst}
.. autoclass:: tetris_gymnasium.components.tetromino_queue.TetrominoQueue
```

## Methods
```{eval-rst}
.. automethod:: tetris_gymnasium.components.tetromino_queue.TetrominoQueue.reset
.. automethod:: tetris_gymnasium.components.tetromino_queue.TetrominoQueue.get_next_tetromino
.. automethod:: tetris_gymnasium.components.tetromino_queue.TetrominoQueue.get_queue
```
35 changes: 35 additions & 0 deletions docs/components/randomizer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Randomizer

```{eval-rst}
.. autoclass:: tetris_gymnasium.components.tetromino_randomizer.Randomizer
```

## Methods
```{eval-rst}
.. automethod:: tetris_gymnasium.components.tetromino_randomizer.Randomizer.get_next_tetromino
.. automethod:: tetris_gymnasium.components.tetromino_randomizer.Randomizer.reset
```

## Implementations

In Tetris Gymnasium, there are different randomizers available by default. The default randomizer is the `BagRandomizer`,
which is the same as the one used in the most Tetris games. The `TrueRandomizer` is a randomizer that generates
tetrominoes with a uniform distribution.

If these randomizers do not fit your needs, you can easily implement your own randomizer by subclassing the `Randomizer`.

```{eval-rst}
.. autoclass:: tetris_gymnasium.components.tetromino_randomizer.BagRandomizer
```

```{eval-rst}
.. automethod:: tetris_gymnasium.components.tetromino_randomizer.BagRandomizer.get_next_tetromino
```

```{eval-rst}
.. autoclass:: tetris_gymnasium.components.tetromino_randomizer.TrueRandomizer
```

```{eval-rst}
.. automethod:: tetris_gymnasium.components.tetromino_randomizer.TrueRandomizer.get_next_tetromino
```
8 changes: 8 additions & 0 deletions docs/components/tetromino.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Tetromino

![Tetromino](../_static/components/tetromino.png)

```{eval-rst}
.. autoclass:: tetris_gymnasium.components.tetromino.Pixel
.. autoclass:: tetris_gymnasium.components.tetromino.Tetromino
```
22 changes: 21 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,25 @@
"source_repository": "https://github.com/Max-We/Tetris-Gymnasium",
"source_branch": "main",
"source_directory": "docs/",
"announcement": "Tetris Gymnasium is under early development!",
# "announcement": "Tetris Gymnasium is under early development!",
}

# Autodoc
autoclass_content = "both"
autodoc_preserve_defaults = True


# This function removes the content before the parameters in the __init__ function.
# This content is often not useful for the website documentation as it replicates
# the class docstring.
def remove_lines_before_parameters(app, what, name, obj, options, lines):
if what == "class":
# ":param" represents args values
first_idx_to_keep = next(
(i for i, line in enumerate(lines) if line.startswith(":param")), 0
)
lines[:] = lines[first_idx_to_keep:]


def setup(app):
app.connect("autodoc-process-docstring", remove_lines_before_parameters)
13 changes: 12 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,23 @@ introduction/quickstart

```{toctree}
:maxdepth: 2
:caption: API
:caption: Environment
:hidden:
environments/tetris
```

```{toctree}
:maxdepth: 2
:caption: Components
:hidden:
components/tetromino
components/queue
components/holder
components/randomizer
```

```{toctree}
:maxdepth: 2
:caption: Development
Expand Down
9 changes: 5 additions & 4 deletions examples/play_interactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
tetris_game = gym.make("tetris_gymnasium/Tetris", render_mode="rgb_array")
tetris_game.reset(seed=42)

cv2.namedWindow("Tetris", cv2.WINDOW_GUI_NORMAL)
cv2.resizeWindow("Tetris", 200, 400)
window_name = "Tetris Gymnasium"
cv2.namedWindow(window_name, cv2.WINDOW_GUI_NORMAL)
cv2.resizeWindow(window_name, 200, 400)

# Main game loop
terminated = False
Expand All @@ -22,7 +23,7 @@

# Render the current state of the game as an image using CV2q
# CV2 uses BGR color format, so we need to convert the RGB image to BGR
cv2.imshow("Tetris", cv2.cvtColor(rgb, cv2.COLOR_RGB2BGR))
cv2.imshow(window_name, cv2.cvtColor(rgb, cv2.COLOR_RGB2BGR))
cv2.waitKey(50)

# Pick an action from user input mapped to the keyboard
Expand All @@ -48,7 +49,7 @@
tetris_game.reset(seed=42)
break

if cv2.getWindowProperty("Tetris", cv2.WND_PROP_VISIBLE) == 0:
if cv2.getWindowProperty(window_name, cv2.WND_PROP_VISIBLE) == 0:
sys.exit()

# Perform the action
Expand Down
9 changes: 5 additions & 4 deletions examples/play_interactive_cnn.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
tetris_game.reset(seed=42)
tetris_game = CnnObservation(tetris_game)

cv2.namedWindow("Tetris", cv2.WINDOW_GUI_NORMAL)
cv2.resizeWindow("Tetris", 400, 250)
window_name = "Tetris Gymnasium"
cv2.namedWindow(window_name, cv2.WINDOW_GUI_NORMAL)
cv2.resizeWindow(window_name, 395, 250)

# Main game loop
terminated = False
Expand All @@ -23,7 +24,7 @@

# Render the current state of the game as an image using CV2
# CV2 uses BGR color format, so we need to convert the RGB image to BGR
cv2.imshow("Tetris", cv2.cvtColor(rgb, cv2.COLOR_RGB2BGR))
cv2.imshow(window_name, cv2.cvtColor(rgb, cv2.COLOR_RGB2BGR))
cv2.waitKey(50)

# Pick an action from user input mapped to the keyboard
Expand All @@ -49,7 +50,7 @@
tetris_game.reset(seed=42)
break

if cv2.getWindowProperty("Tetris", cv2.WND_PROP_VISIBLE) == 0:
if cv2.getWindowProperty(window_name, cv2.WND_PROP_VISIBLE) == 0:
sys.exit()

# Perform the action
Expand Down
27 changes: 23 additions & 4 deletions tetris_gymnasium/components/tetromino.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@

@dataclass
class Pixel:
"""A single pixel of a Tetris game.
"""A single pixel in a game of Tetris.
A pixel can be part of a tetromino or part of the game board (empty, bedrock).
A pixel is the basic building block of the game and has an id and a color.
The basic pixels are in the most cases the empty pixel (id=0) and the bedrock pixel (id=1).
Additionally, multiple pixels can be combined to form a tetromino.
"""

id: int
Expand All @@ -17,9 +20,25 @@ class Pixel:

@dataclass
class Tetromino(Pixel):
"""A Tetris piece.
"""A Tetris "piece" is called a Tetromino. Examples are the I, J, L, O, S, T, and Z pieces.
On a conceptual basis, a tetromino is a 2D-array composed of multiple pixels. All pixels that compose the tetromino
have the same id. And the ids of all the pixels are stored in the matrix.
An example for the matrix of the T-tetromino:
.. code-block:: python
[
[0, 1, 0],
[1, 1, 1],
[0, 0, 0]
]
In the matrix, the value `0` represents an empty pixel, and the value `1` represents a pixel of the T-tetromino.
A tetromino is a geometric shape composed of multiple pixels.
When initializing a `Tetromino` object on your own, you'll typically use binary values for the matrix, where `1`
represents a pixel of the tetromino and `0` represents an empty pixel.
"""

matrix: np.ndarray
14 changes: 9 additions & 5 deletions tetris_gymnasium/components/tetromino_holder.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@


class TetrominoHolder:
"""Class for one or more tetrominoes for later use in a game of Tetris."""
"""A holder can store one or more tetrominoes for later use in a game of Tetris.
Tetrominoes can be swapped in- and out during the game.
"""

def __init__(self, size=1):
"""Create a new holder with the given number of tetrominoes.
Expand All @@ -28,13 +31,14 @@ def _store_tetromino(self, tetromino: Tetromino):
def swap(self, tetromino: Tetromino) -> Optional[Tetromino]:
"""Swap the given tetromino with the one in the holder.
This implementation uses a queue to store the tetrominoes. Tetromioes are only returned once the queue is full.
This implementation uses a queue to store the tetrominoes. Tetrominoes are only returned once the queue is full.
If this is not the case, the provided tetromino is stored in the queue and None is returned.
Args:
tetromino: The tetromino to store in the holder.
Returns:
The tetromino that was in the holder before the swap.
The oldest tetromino that's stored in the queue, if the queue is full. Otherwise, None.
"""
if len(self.queue) < self.size:
self._store_tetromino(tetromino)
Expand All @@ -45,9 +49,9 @@ def swap(self, tetromino: Tetromino) -> Optional[Tetromino]:
return result

def reset(self):
"""Reset the holder to its initial state."""
"""Reset the holder to its initial state. This involves clearing the queue."""
self.queue.clear()

def get_tetrominoes(self):
"""Get the tetrominoes currently in the holder."""
"""Get all the tetrominoes currently in the holder."""
return list(self.queue)
18 changes: 14 additions & 4 deletions tetris_gymnasium/components/tetromino_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@


class TetrominoQueue:
"""Class for a queue of tetrominoes for use in a game of Tetris."""
"""The queue shows the incoming tetrominoes in a game of Tetris.
The sequence of pieces is generated by a :class:`Randomizer`, which can be customized by the user.
"""

def __init__(self, randomizer: Randomizer, size=4):
"""Create a new queue of tetrominoes with the given size.
Expand All @@ -19,18 +22,25 @@ def __init__(self, randomizer: Randomizer, size=4):
self.size = size

def reset(self, seed=None):
"""Reset the queue to its initial state."""
"""Reset the queue to its initial state.
Args:
seed: The seed to use for the randomizer. Defaults to None.
"""
self.randomizer.reset(seed)
self.queue.clear()
for _ in range(self.size):
self.queue.append(self.randomizer.get_next_tetromino())

def get_next_tetromino(self):
"""Get the next tetromino from the queue and generates a new one."""
"""Gets the next tetromino from the queue and generates a new one.
Generating a new Tetromino makes sure that the queue will always be full.
"""
tetromino = self.queue.popleft()
self.queue.append(self.randomizer.get_next_tetromino())
return tetromino

def get_queue(self):
"""Get the tetrominoes currently in the queue."""
"""Get all tetrominoes currently in the queue."""
return list(self.queue)
Loading

0 comments on commit 041bd96

Please sign in to comment.