Skip to content

Conversation

@GboyeStack-Robotics-ML-Engineer
Copy link
Contributor

Add Connect4 Environment and Supporting Models to OpenEnv

Summary

This pull request introduces a new Connect4 Environment to the OpenEnv framework, expanding its suite of interactive learning environments.
The Connect4 environment follows OpenEnv’s modular design and integrates seamlessly with the existing Environment, Action, and Observation interfaces.


🔑 Key Features

  • 🧠 New Environment

    • Implements full Connect4 game logic: move validation, piece placement, win/draw detection.
    • Compatible with OpenEnv’s standard reset and step lifecycle.
    • Supports unique episode management with uuid.
  • ⚙️ Model Additions

    • Connect4Action – Defines valid column selections as agent actions.
    • Connect4State – Represents board state, active player, and step count.
    • Connect4Observation – Encapsulates board view, legal actions, reward signal, and done status.
  • 🎮 Gameplay Logic

    • Detects 4-in-a-row in four directions (vertical, horizontal, diagonal-down, diagonal-up).
    • Prevents invalid moves (full columns or out-of-range actions).
    • Alternates between players automatically.
    • Tracks rewards and termination conditions for RL agents.
  • 🧩 Visualization Support

    • Optional rendering enhancements to display step count and reward during play.
    • Board updates compatible with existing OpenEnv visualization tools.

Testing out the env
To test out the environment, open two terminals

On terminal 1:
Run the following from root dir (OpenEnv/)

  • cd src
    Then start the server:
    - python -m envs.connect4_env.server.app

On the terminal 2:
Run python examples/connect4.py from root directory (OpenEnv/)

This is an example of the output:
image

image

@meta-cla
Copy link

meta-cla bot commented Oct 27, 2025

Hi @GboyeStack-Robotics-ML-Engineer!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at [email protected]. Thanks!

@meta-cla
Copy link

meta-cla bot commented Oct 27, 2025

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@meta-cla meta-cla bot added the CLA Signed This label is managed by the Meta Open Source bot. label Oct 27, 2025
import numpy as np
from envs.atari_env import AtariEnv, AtariAction

# import envs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove debug code?

print("\nResetting environment...")
result = env.reset()
print(f"Screen shape: {result.observation.screen_shape}")

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

newlines?

@Darktex Darktex requested a review from Copilot October 31, 2025 00:27
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds a new Connect4 environment integration to the OpenEnv framework, implementing a two-player Connect 4 game that can be accessed via HTTP server. This follows the OpenEnv pattern of server-side environment implementation with client-side HTTP access.

  • Implements Connect4Environment server with game logic for a 6x7 board
  • Provides type-safe client wrapper (Connect4Env) for HTTP communication
  • Adds Docker support and GitHub Actions workflow integration
  • Includes example script with visualization using matplotlib

Reviewed Changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
src/envs/connect4_env/server/connect4_environment.py Implements core Connect4 game logic with win detection and state management
src/envs/connect4_env/server/app.py Creates FastAPI app wrapper for the Connect4 environment server
src/envs/connect4_env/server/init.py Exports Connect4Environment for server module
src/envs/connect4_env/server/Dockerfile Defines Docker image for running Connect4 server
src/envs/connect4_env/models.py Defines type-safe Action, Observation, and State models
src/envs/connect4_env/client.py HTTP client for communicating with Connect4 server
src/envs/connect4_env/init.py Main module exports for Connect4 environment
examples/connect4.py Example script demonstrating Connect4 environment usage with visualization
examples/atari_simple.py Modified to use localhost URL instead of Docker image
examples/OpenEnv_Tutorial.ipynb Updated with execution outputs and kernel version
.github/workflows/docker-build.yml Adds Connect4 environment to Docker build workflow

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

CMD curl -f http://localhost:8000/health || exit 1

# Run server
CMD ["uvicorn", "envs.my_env.server.app:app", "--host", "0.0.0.0", "--port", "8000"] No newline at end of file
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CMD directive references 'envs.my_env.server.app:app' but should reference 'envs.connect4_env.server.app:app' to match the actual module path. This will cause the server to fail to start.

Suggested change
CMD ["uvicorn", "envs.my_env.server.app:app", "--host", "0.0.0.0", "--port", "8000"]
CMD ["uvicorn", "envs.connect4_env.server.app:app", "--host", "0.0.0.0", "--port", "8000"]

Copilot uses AI. Check for mistakes.
Comment on lines 10 to 12
This module provides OpenEnv integration for Connect4 2600 games via the
Arcade Learning Environment (ALE).
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation incorrectly refers to 'Connect4 2600 games via the Arcade Learning Environment (ALE)'. Connect4 is a board game, not an Atari 2600 game. This appears to be copied from the Atari environment template and should be updated to describe Connect4 specifically.

Suggested change
This module provides OpenEnv integration for Connect4 2600 games via the
Arcade Learning Environment (ALE).
This module provides OpenEnv integration for the classic Connect4 board game.

Copilot uses AI. Check for mistakes.
>>> print(result.observation.board)
>>>
>>> # Take an action
>>> result = client.step(Connect4Action(action_id=3))
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example uses 'action_id=3' but Connect4Action expects 'column' as the parameter name according to the model definition. This should be 'Connect4Action(column=3)'.

Suggested change
>>> result = client.step(Connect4Action(action_id=3))
>>> result = client.step(Connect4Action(column=3))

Copilot uses AI. Check for mistakes.
break

action_id = int(np.random.choice(result.observation.legal_actions))
result = env.step(Connect4Action(action_id))
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Connect4Action expects a 'column' parameter, not a positional argument. This should be 'Connect4Action(column=action_id)' to match the dataclass definition.

Suggested change
result = env.step(Connect4Action(action_id))
result = env.step(Connect4Action(column=action_id))

Copilot uses AI. Check for mistakes.
return ax.patches

# Create animation
ani = FuncAnimation(fig, animate_frame, frames=len(frames),
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable ani is not used.

Copilot uses AI. Check for mistakes.

def step(self, action: Connect4Action):
col = action.column
reward = 0.0
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assignment to 'reward' is unnecessary as it is redefined before this value is used.
This assignment to 'reward' is unnecessary as it is redefined before this value is used.

Suggested change
reward = 0.0

Copilot uses AI. Check for mistakes.
from envs.connect4_env import Connect4Action, Connect4Env


def render_connect4_board(board, ax, player_colors={1: "red", 2: "yellow", -1: "yellow"}, show=True):
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mixing implicit and explicit returns may indicate an error, as implicit returns always return None.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,12 @@
from core.env_server import create_fastapi_app
from ..models import Connect4Action, Connect4Observation, Connect4State
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Import of 'Connect4State' is not used.

Suggested change
from ..models import Connect4Action, Connect4Observation, Connect4State
from ..models import Connect4Action, Connect4Observation

Copilot uses AI. Check for mistakes.
from .models import Connect4Action, Connect4Observation, Connect4State

if TYPE_CHECKING:
from core.containers.runtime import ContainerProvider
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Import of 'ContainerProvider' is not used.

Suggested change
from core.containers.runtime import ContainerProvider

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,90 @@
import uuid
import numpy as np
from core.env_server import Action, Environment, Observation
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Import of 'Action' is not used.
Import of 'Observation' is not used.

Suggested change
from core.env_server import Action, Environment, Observation
from core.env_server import Environment

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@Darktex Darktex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks really good. Just a couple of changes :)

  1. Can you ask your favorite LLM to write tests for the connect4 logic? I love that we don't have to use a library for it, but I'm always worried that we may have some off-by-one errors here and there...
  2. Can you address the minor nits that Copilot found?

That's it!!

@GboyeStack-Robotics-ML-Engineer
Copy link
Contributor Author

@Darktex I already addressed the minor issues that copilot raised. I have commited this. As for the tests I have included a unittest file under the test folder

@Darktex
Copy link
Contributor

Darktex commented Nov 3, 2025

Thank you so much!!

@Darktex Darktex merged commit fca4d4a into meta-pytorch:main Nov 3, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants