sadhana33/openenv-project
๐ OpenEnv - Grid World Environment
A complete, real-world OpenEnv environment that AI agents can learn from through the standard step() / reset() / state() API.
Overview
OpenEnv provides a Grid World environment - a classic reinforcement learning problem where an agent navigates a grid to reach a goal while avoiding obstacles and pits. This implementation follows the standard RL environment interface pattern used by popular frameworks like OpenAI Gym.
Features
- โ
Standard RL API:
reset(),step(),state() - โ RESTful HTTP API for language-agnostic access
- โ Interactive web interface with real-time visualization
- โ Keyboard controls (WASD / Arrow keys)
- โ Multiple environment instance support
- โ Configurable grid size
- โ Q-Learning agent example included
- โ Comprehensive documentation
Quick Start
# Install dependencies
npm install
# Start the server
npm start
# Open browser to http://localhost:3000Run Agent Demo
# Run the Q-Learning agent demonstration
npm run demoEnvironment Details
Grid World (GridWorld-v0)
Rewards
Actions
Grid Layout
y
4 ยท ยท ยท ยท ยท
3 ยท ยท ๐งฑ ยท ยท
2 ยท ๐ณ๏ธ ๐งฑ ๐ณ๏ธ ยท
1 ยท ยท ๐งฑ ยท ยท
0 ๐ค ยท ยท ยท ๐ฏ
-------------
0 1 2 3 4 x- ๐ค Agent starts at (0, 0)
- ๐ฏ Goal is at (4, 4)
- ๐งฑ Obstacles block movement
- ๐ณ๏ธ Pits end the episode with penalty
API Reference
Environment Info
GET /api/env/infoReturns metadata about the environment including action space, observation space, and reward ranges.
Response:
{
"name": "GridWorld-v0",
"description": "A classic grid world reinforcement learning environment...",
"version": "1.0.0",
"action_space": {
"type": "discrete",
"n": 4,
"labels": ["UP", "RIGHT", "DOWN", "LEFT"]
},
"observation_space": {
"type": "grid",
"shape": [5, 5],
"cellTypes": ["empty", "agent", "goal", "obstacle", "pit"]
},
"reward_range": { "min": -1, "max": 10 },
"max_steps": 100,
"rewards": {
"goal": 10, "obstacle": -0.5, "pit": -1,
"boundary": -0.1, "step": -0.01
}
}Reset Environment
POST /api/resetResets the environment to its initial state. The agent starts at position (0, 0).
Query Parameters:
env_id(optional): Unique identifier for the environment instancegrid_size(optional): Size of the grid (default: 5)
Response:
{
"env_id": "default",
"state": {
"agent_position": { "x": 0, "y": 0 },
"goal_position": { "x": 4, "y": 4 },
"grid_size": 5,
"steps": 0,
"done": false,
"total_reward": 0,
"grid": [["agent", "empty", ...], ...]
},
"info": { ... }
}Take Action (Step)
POST /api/step
Content-Type: application/json
{
"action": 1,
"env_id": "default"
}Executes an action in the environment and returns the new state, reward, and done flag.
Body:
action(required): Integer 0-3 representing the directionenv_id(optional): Environment instance ID (default: "default")
Response:
{
"env_id": "default",
"state": {
"agent_position": { "x": 1, "y": 0 },
"goal_position": { "x": 4, "y": 4 },
"grid_size": 5,
"steps": 1,
"done": false,
"total_reward": -0.01,
"grid": [...]
},
"reward": -0.01,
"done": false,
"info": {
"message": "Moved successfully",
"success": true,
"action_taken": 1,
"steps": 1
}
}Get Current State
GET /api/state?env_id=defaultReturns the current state without taking any action.
List Environments
GET /api/envsLists all active environment instances.
Delete Environment
DELETE /api/env/:env_idDeletes a specific environment instance.
Usage Examples
JavaScript/Node.js
const fetch = require('node-fetch');
const BASE_URL = 'http://localhost:3000';
// Reset the environment
async function reset() {
const response = await fetch(`${BASE_URL}/api/reset`, { method: 'POST' });
return response.json();
}
// Take an action
async function step(action) {
const response = await fetch(`${BASE_URL}/api/step`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action })
});
return response.json();
}
// Get current state
async function getState() {
const response = await fetch(`${BASE_URL}/api/state`);
return response.json();
}
// Training loop example
async function train() {
const actions = { UP: 0, RIGHT: 1, DOWN: 2, LEFT: 3 };
await reset();
let done = false;
let totalReward = 0;
while (!done) {
// Your RL agent selects an action
const action = selectAction();
const result = await step(action);
totalReward += result.reward;
done = result.done;
// Learn from the experience
learn(result.state, action, result.reward);
}
console.log('Episode complete! Total reward:', totalReward);
}Using the Environment Directly (No Server)
const { GridWorldEnv } = require('./index');
const { QLearningAgent } = require('./agent');
// Create environment
const env = new GridWorldEnv(5, 'my-env');
// Create agent
const agent = new QLearningAgent({
learningRate: 0.1,
discountFactor: 0.95,
epsilon: 0.1
});
// Training loop
for (let episode = 0; episode < 100; episode++) {
let state = env.reset();
let done = false;
while (!done) {
const action = agent.selectAction(state);
const result = env.step(action);
agent.learn(state, action, result.reward, result.state, result.done);
state = result.state;
done = result.done;
}
agent.decayEpsilon();
}Python
import requests
import json
BASE_URL = "http://localhost:3000"
def reset():
response = requests.post(f"{BASE_URL}/api/reset")
return response.json()
def step(action):
response = requests.post(
f"{BASE_URL}/api/step",
headers={"Content-Type": "application/json"},
data=json.dumps({"action": action})
)
return response.json()
def get_state():
response = requests.get(f"{BASE_URL}/api/state")
return response.json()
# Training loop
def train():
actions = {"UP": 0, "RIGHT": 1, "DOWN": 2, "LEFT": 3}
reset()
done = False
total_reward = 0
while not done:
action = select_action() # Your RL agent
result = step(action)
total_reward += result["reward"]
done = result["done"]
learn(result["state"], action, result["reward"])
print(f"Episode complete! Total reward: {total_reward}")cURL
# Reset
curl -X POST http://localhost:3000/api/reset
# Step (move right)
curl -X POST http://localhost:3000/api/step \
-H "Content-Type: application/json" \
-d '{"action": 1}'
# Get state
curl http://localhost:3000/api/state
# Get environment info
curl http://localhost:3000/api/env/infoQ-Learning Agent
The included agent.js file contains a complete Q-Learning implementation:
const { QLearningAgent } = require('./agent');
const agent = new QLearningAgent({
learningRate: 0.2, // How much to learn from new info
discountFactor: 0.95, // Importance of future rewards
epsilon: 1.0, // Initial exploration rate
epsilonDecay: 0.995, // How fast to reduce exploration
minEpsilon: 0.01 // Minimum exploration rate
});
// Select action (training mode with exploration)
const action = agent.selectAction(state, true);
// Learn from experience
agent.learn(state, action, reward, nextState, done);
// Reduce exploration after each episode
agent.decayEpsilon();Project Structure
openenv-project/
โโโ index.js # Main server with GridWorldEnv class
โโโ agent.js # Q-Learning and Random agents
โโโ package.json # Dependencies and scripts
โโโ README.md # This file
โโโ public/
โโโ index.html # Main interactive interface
โโโ home.html # Home page (redirects to index)
โโโ about.html # About/documentation page
โโโ css/
โโโ style.css # All stylesBuilding Your Own Agent
Q-Learning Example
class QLearningAgent {
constructor(actions, learningRate = 0.1, discountFactor = 0.95, epsilon = 0.1) {
this.actions = actions;
this.lr = learningRate;
this.gamma = discountFactor;
this.epsilon = epsilon;
this.qTable = {};
}
getStateKey(state) {
return `${state.agent_position.x},${state.agent_position.y}`;
}
getQValues(state) {
const key = this.getStateKey(state);
if (!this.qTable[key]) {
this.qTable[key] = new Array(this.actions).fill(0);
}
return this.qTable[key];
}
selectAction(state) {
if (Math.random() < this.epsilon) {
return Math.floor(Math.random() * this.actions); // Explore
}
const qValues = this.getQValues(state);
return qValues.indexOf(Math.max(...qValues)); // Exploit
}
learn(state, action, reward, nextState, done) {
const key = this.getStateKey(state);
const nextKey = this.getStateKey(nextState);
if (!this.qTable[key]) {
this.qTable[key] = new Array(this.actions).fill(0);
}
const maxNextQ = done ? 0 : Math.max(...this.getQValues(nextState));
this.qTable[key][action] += this.lr * (
reward + this.gamma * maxNextQ - this.qTable[key][action]
);
}
}Use Cases
- Reinforcement Learning Research: Test and compare RL algorithms
- Education: Teach RL concepts with a visual, interactive environment
- Algorithm Testing: Validate pathfinding algorithms (A*, Dijkstra)
- Prototyping: Quick iteration before scaling to complex environments
- API Testing: Language-agnostic RL environment via REST API
Contributing
Feel free to submit issues and enhancement requests!
License
ISC =======
openenv-project
OpenEnv is a custom reinforcement learning environment built with Node.js. It provides a standard API (reset, step, state) for training AI agents, along with a simple grid-based interface for interaction and visualization.
>>>>>> 36ee0a5f5953cae6c162a55faaf906ed88003f59
