Skip to content
Open
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
e3cda7d
Add Minesweeper environment core implementation
acharyaanusha Dec 5, 2025
9730c27
Add Docker support and example for Minesweeper environment
acharyaanusha Dec 5, 2025
e147894
Add tests and CI/CD integration for Minesweeper environment
acharyaanusha Dec 5, 2025
1469cc8
Update minesweeper environment to align with OpenEnv standards
acharyaanusha Jan 16, 2026
98bf1d4
Refactor Minesweeper environment tests and Dockerfile CMD for improve…
acharyaanusha Jan 21, 2026
2b38813
Merge branch 'main' into feature/minesweeper_env
acharyaanusha Jan 31, 2026
100833d
Merge branch 'main' into feature/minesweeper_env
burtenshaw Feb 5, 2026
ab02918
Merge branch 'main' into feature/minesweeper_env
acharyaanusha Feb 5, 2026
d54657e
Merge branch 'main' into feature/minesweeper_env
acharyaanusha Feb 5, 2026
fe25387
Merge branch 'main' into feature/minesweeper_env
acharyaanusha Feb 11, 2026
0601bab
Fix minesweeper tests: close WebSocket clients to prevent session cap…
acharyaanusha Feb 11, 2026
f94968f
Convert minesweeper tests to async to work with async EnvClient
acharyaanusha Feb 23, 2026
ae12c52
Merge branch 'main' into feature/minesweeper_env
acharyaanusha Feb 23, 2026
1dde181
Fix IndexError: auto-reset environment in __init__ so board is playab…
acharyaanusha Feb 23, 2026
67eda74
Merge branch 'main' into feature/minesweeper_env
acharyaanusha Feb 24, 2026
a9a0d6f
Merge branch 'main' into feature/minesweeper_env
acharyaanusha Feb 28, 2026
2a06cd1
Merge branch 'main' into feature/minesweeper_env
acharyaanusha Mar 8, 2026
58e1b68
Merge branch 'main' into feature/minesweeper_env
acharyaanusha Mar 28, 2026
f90158e
Merge branch 'main' into feature/minesweeper_env
acharyaanusha Apr 8, 2026
7ed5ac3
Merge branch 'main' into feature/minesweeper_env
acharyaanusha Apr 16, 2026
faf4e51
Merge branch 'main' into feature/minesweeper_env
acharyaanusha May 13, 2026
fa03d71
Address PR review: remove no-op try/except shims and tidy Tier 1 issues
acharyaanusha May 13, 2026
84a565d
Move minesweeper env to envs/, align with project conventions
acharyaanusha May 13, 2026
41836c9
Fix win-condition bug and address PR review follow-ups
acharyaanusha May 14, 2026
0b9b3d5
Merge branch 'main' into feature/minesweeper_env
acharyaanusha May 25, 2026
09e31e2
Merge branch 'main' into feature/minesweeper_env
acharyaanusha Jun 3, 2026
e4697e4
fix(minesweeper): support seeded reset with session-local RNG
burtenshaw Oct 26, 2026
546769c
Merge remote-tracking branch 'origin/main' into t3/pr236-r2
burtenshaw Oct 26, 2026
16783a1
fix(minesweeper): repair runtime entry points and validate board conf…
burtenshaw Oct 26, 2026
c53c2c6
Merge remote-tracking branch 'origin/main' into t3/pr236-r2
burtenshaw Oct 26, 2026
cf53636
fix(minesweeper): bound flag rewards and sync package documentation
burtenshaw Oct 26, 2026
e80510f
Fix Minesweeper flood fill stack overflow
burtenshaw Oct 26, 2026
0ab38b5
test(minesweeper): wait for server readiness and surface startup fail…
burtenshaw Oct 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/docker-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ jobs:
- name: connect4_env
dockerfile: envs/connect4_env/server/Dockerfile
context: envs/connect4_env
- name: minesweeper-env
dockerfile: envs/minesweeper_env/server/Dockerfile
context: envs/minesweeper_env
Comment thread
cursor[bot] marked this conversation as resolved.
- name: chess-env
dockerfile: envs/chess_env/server/Dockerfile
context: envs/chess_env
Expand Down
2 changes: 2 additions & 0 deletions docs/source/_toctree.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@
title: CARLA
- local: environments/chess
title: Chess
- local: environments/minesweeper
title: Minesweeper
- local: environments/connect4
title: Connect4
- local: environments/dm_control
Expand Down
7 changes: 7 additions & 0 deletions docs/source/environments.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ The OpenEnv community has built a catalog of ready-to-run environments that cove

<div class="mt-6">
<div class="w-full flex flex-col space-y-4 md:space-y-0 md:grid md:grid-cols-3 md:gap-4">
<div class="border dark:border-gray-700 p-5 rounded-lg shadow">
<div class="font-bold mb-2">Minesweeper</div>
<p class="text-sm">Reveal safe cells and flag suspected mines in a seeded grid puzzle.</p>
<div class="flex gap-2 mt-3">
<a href="environments/minesweeper" class="!no-underline border dark:border-gray-700 px-3 py-1 rounded text-sm hover:shadow">📄 Docs</a>
</div>
</div>
<div class="border dark:border-gray-700 p-5 rounded-lg shadow">
<div class="font-bold mb-2">Echo</div>
<p class="text-sm">Minimal observation/action loop for verifying client integrations, CI pipelines, and onboarding flows in seconds.</p>
Expand Down
144 changes: 144 additions & 0 deletions docs/source/environments/minesweeper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
<!-- openenv-source: minesweeper_env -->
# Minesweeper Environment

A Minesweeper game environment for reinforcement learning agents. The environment consists of a grid with hidden mines where the agent must reveal all non-mine cells without triggering any mines.

## Overview

The agent can perform two types of actions:
- Reveal cells to uncover numbers indicating adjacent mines
- Place or remove flags on suspected mine locations

The game ends when all non-mine cells are revealed (win) or a mine is revealed (loss).

## Quick Start

```python
from minesweeper_env import MinesweeperAction, MinesweeperEnv

# Create environment from Docker image
minesweeper_env = MinesweeperEnv.from_docker_image("minesweeper-env:latest").sync()

try:
# Reset the environment
result = minesweeper_env.reset()
print(f"Board size: {result.observation.board_height}x{result.observation.board_width}")
print(f"Number of mines: {result.observation.num_mines}")

# Reveal a cell
result = minesweeper_env.step(MinesweeperAction(row=2, col=2, action_type="reveal"))
print(f"Cells revealed: {result.observation.cells_revealed}")
print(f"Reward: {result.observation.reward}")

# Place a flag
result = minesweeper_env.step(MinesweeperAction(row=1, col=1, action_type="flag"))
print(f"Flags placed: {result.observation.flags_placed}")

finally:
minesweeper_env.close()
```

## Building the Docker Image

Build the Docker image from the project root:

```bash
docker build -t minesweeper-env:latest -f envs/minesweeper_env/server/Dockerfile envs/minesweeper_env
```

Or use the build script:

```bash
cd envs/minesweeper_env/server
./build_docker.sh latest
```

## Environment Details

### Action

**MinesweeperAction**: Specifies the cell and action type
- `row` (int) - Row index (0-indexed)
- `col` (int) - Column index (0-indexed)
- `action_type` (str) - Either "reveal" or "flag"

### Observation

**MinesweeperObservation**: Current board state and game information
- `board` (list[list]) - 2D grid showing the current state of each cell:
- `-1`: Unrevealed cell
- `0-8`: Number of adjacent mines (revealed cell)
- `'F'`: Flagged cell
- `'*'`: Mine (only shown when game is lost)
- `num_mines` (int) - Total number of mines on the board
- `flags_placed` (int) - Number of flags currently placed
- `cells_revealed` (int) - Number of cells that have been revealed
- `game_status` (GameStatus) - Current game status (ONGOING, WON, or LOST)
- `done` (bool) - Whether the game has ended
- `reward` (float) - Reward from the last action
- `metadata` (dict) - Additional information

### Rewards

- Revealing a safe cell: +1.0
- Placing a flag on a mine: +0.5 once per mine per episode. Removing or replacing a previously rewarded flag gives 0; reset restores bonus eligibility.
- Revealing a mine (game over): -10.0
- Revealing an already revealed cell: -0.05
- Invalid action: -0.1

### Game Status

- `GameStatus.ONGOING`: Game is still in progress
- `GameStatus.WON`: All non-mine cells have been revealed
- `GameStatus.LOST`: A mine was revealed

## Configuration

The default configuration is:
- Board height: 5
- Board width: 5
- Number of mines: 5

These can be configured when initializing the environment server.

## Connecting to an Existing Server

If you have a server already running:

```python
from minesweeper_env import MinesweeperEnv

# Connect to existing server
minesweeper_env = MinesweeperEnv(base_url="http://localhost:8000")

# Use as normal
result = minesweeper_env.reset()
```

Note: When connecting to an existing server, `close()` will not stop the server.

## Running Tests

Run the test suite:

```bash
python tests/envs/test_minesweeper_env.py
```

## Project Structure

```
minesweeper_env/
├── __init__.py # Module exports
├── README.md # This file
├── client.py # MinesweeperEnv client implementation
├── models.py # Action, Observation, and State models
├── openenv.yaml # Environment configuration
├── pyproject.toml # Package dependencies
└── server/
├── __init__.py # Server module exports
├── minesweeper_environment.py # Core game logic
├── app.py # FastAPI application
├── Dockerfile # Container image definition
└── build_docker.sh # Build script
```
143 changes: 143 additions & 0 deletions envs/minesweeper_env/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# Minesweeper Environment

A Minesweeper game environment for reinforcement learning agents. The environment consists of a grid with hidden mines where the agent must reveal all non-mine cells without triggering any mines.

## Overview

The agent can perform two types of actions:
- Reveal cells to uncover numbers indicating adjacent mines
- Place or remove flags on suspected mine locations

The game ends when all non-mine cells are revealed (win) or a mine is revealed (loss).

## Quick Start

```python
from minesweeper_env import MinesweeperAction, MinesweeperEnv

# Create environment from Docker image
minesweeper_env = MinesweeperEnv.from_docker_image("minesweeper-env:latest").sync()

try:
# Reset the environment
result = minesweeper_env.reset()
print(f"Board size: {result.observation.board_height}x{result.observation.board_width}")
print(f"Number of mines: {result.observation.num_mines}")

# Reveal a cell
result = minesweeper_env.step(MinesweeperAction(row=2, col=2, action_type="reveal"))
print(f"Cells revealed: {result.observation.cells_revealed}")
print(f"Reward: {result.observation.reward}")

# Place a flag
result = minesweeper_env.step(MinesweeperAction(row=1, col=1, action_type="flag"))
print(f"Flags placed: {result.observation.flags_placed}")

finally:
minesweeper_env.close()
```

## Building the Docker Image

Build the Docker image from the project root:

```bash
docker build -t minesweeper-env:latest -f envs/minesweeper_env/server/Dockerfile envs/minesweeper_env
```

Or use the build script:

```bash
cd envs/minesweeper_env/server
./build_docker.sh latest
```

## Environment Details

### Action

**MinesweeperAction**: Specifies the cell and action type
- `row` (int) - Row index (0-indexed)
- `col` (int) - Column index (0-indexed)
- `action_type` (str) - Either "reveal" or "flag"

### Observation

**MinesweeperObservation**: Current board state and game information
- `board` (list[list]) - 2D grid showing the current state of each cell:
- `-1`: Unrevealed cell
- `0-8`: Number of adjacent mines (revealed cell)
- `'F'`: Flagged cell
- `'*'`: Mine (only shown when game is lost)
- `num_mines` (int) - Total number of mines on the board
- `flags_placed` (int) - Number of flags currently placed
- `cells_revealed` (int) - Number of cells that have been revealed
- `game_status` (GameStatus) - Current game status (ONGOING, WON, or LOST)
- `done` (bool) - Whether the game has ended
- `reward` (float) - Reward from the last action
- `metadata` (dict) - Additional information

### Rewards

- Revealing a safe cell: +1.0
- Placing a flag on a mine: +0.5 once per mine per episode. Removing or replacing a previously rewarded flag gives 0; reset restores bonus eligibility.
- Revealing a mine (game over): -10.0
- Revealing an already revealed cell: -0.05
- Invalid action: -0.1

### Game Status

- `GameStatus.ONGOING`: Game is still in progress
- `GameStatus.WON`: All non-mine cells have been revealed
- `GameStatus.LOST`: A mine was revealed

## Configuration

The default configuration is:
- Board height: 5
- Board width: 5
- Number of mines: 5

These can be configured when initializing the environment server.

## Connecting to an Existing Server

If you have a server already running:

```python
from minesweeper_env import MinesweeperEnv

# Connect to existing server
minesweeper_env = MinesweeperEnv(base_url="http://localhost:8000")

# Use as normal
result = minesweeper_env.reset()
```

Note: When connecting to an existing server, `close()` will not stop the server.

## Running Tests

Run the test suite:

```bash
python tests/envs/test_minesweeper_env.py
```

## Project Structure

```
minesweeper_env/
├── __init__.py # Module exports
├── README.md # This file
├── client.py # MinesweeperEnv client implementation
├── models.py # Action, Observation, and State models
├── openenv.yaml # Environment configuration
├── pyproject.toml # Package dependencies
└── server/
├── __init__.py # Server module exports
├── minesweeper_environment.py # Core game logic
├── app.py # FastAPI application
├── Dockerfile # Container image definition
└── build_docker.sh # Build script
```
17 changes: 17 additions & 0 deletions envs/minesweeper_env/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.

"""Minesweeper Environment - a grid-based puzzle game for OpenEnv."""

from .client import MinesweeperEnv
from .models import GameStatus, MinesweeperAction, MinesweeperObservation

__all__ = [
"GameStatus",
"MinesweeperAction",
"MinesweeperEnv",
"MinesweeperObservation",
]
Loading
Loading