|
| 1 | +# Agent Abstractions |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +Agents in the Predator-Prey GridWorld are entities that can observe, decide, |
| 6 | +and act within the environment. Each agent has a type, team, and unique name. |
| 7 | + |
| 8 | +This page explains the concepts. For method details, see the |
| 9 | +[API Reference](api/agents.md). |
| 10 | + |
| 11 | +--- |
| 12 | + |
| 13 | +## Agent Roles |
| 14 | + |
| 15 | +The environment supports three agent types with different behaviors: |
| 16 | + |
| 17 | +| Role | Speed | Color | Objective | |
| 18 | +|------|-------|-------|-----------| |
| 19 | +| **Predator** | 1 | Red | Capture prey by occupying the same cell | |
| 20 | +| **Prey** | 3 | Green | Survive by evading predators | |
| 21 | +| **Other** | 1 | Blue | Custom behavior (user-defined) | |
| 22 | + |
| 23 | +!!! note "Speed Asymmetry" |
| 24 | + Prey move 3x faster than predators. This asymmetry means predators |
| 25 | + must **coordinate** to corner and capture prey, rather than simply |
| 26 | + chasing them. |
| 27 | + |
| 28 | +--- |
| 29 | + |
| 30 | +## Creating Agents |
| 31 | + |
| 32 | +### Basic Example |
| 33 | + |
| 34 | +```python |
| 35 | +from multi_agent_package.agents import Agent |
| 36 | + |
| 37 | +# Create a predator |
| 38 | +predator = Agent( |
| 39 | + agent_type="predator", |
| 40 | + agent_team="predator_1", |
| 41 | + agent_name="Hunter" |
| 42 | +) |
| 43 | + |
| 44 | +# Create a prey |
| 45 | +prey = Agent( |
| 46 | + agent_type="prey", |
| 47 | + agent_team="prey_1", |
| 48 | + agent_name="Runner" |
| 49 | +) |
| 50 | + |
| 51 | +# Check properties |
| 52 | +print(predator.agent_speed) # Output: 1 |
| 53 | +print(prey.agent_speed) # Output: 3 |
| 54 | +``` |
| 55 | + |
| 56 | +## Team Identifier Formats |
| 57 | +The agent_team parameter accepts multiple formats: |
| 58 | +```python |
| 59 | +# Integer format |
| 60 | +agent1 = Agent("predator", 1, "P1") |
| 61 | + |
| 62 | +# String with underscore: "type_subteamID" |
| 63 | +agent2 = Agent("predator", "predator_2", "P2") |
| 64 | + |
| 65 | +# Numeric string |
| 66 | +agent3 = Agent("prey", "3", "R3") |
| 67 | +``` |
| 68 | + |
| 69 | +| Format | Example | Parsed As | |
| 70 | +|--------|---------|-----------| |
| 71 | +| Integer | `3` | Subteam 3 | |
| 72 | +| String | `"predator_2"` | Type: predator, Subteam: 2 | |
| 73 | +| Numeric string | `"2"` | Subteam 2 | |
| 74 | + |
| 75 | +## Action Space |
| 76 | + |
| 77 | +Each agent can perform 5 discrete actions: |
| 78 | + |
| 79 | +| Action | Code | Direction Vector | |
| 80 | +| :--- | :--- | :--- | |
| 81 | +| Right | 0 | [1, 0] | |
| 82 | +| Up | 1 | [0, 1] | |
| 83 | +| Left | 2 | [-1, 0] | |
| 84 | +| Down | 3 | [0, -1] | |
| 85 | +| Noop | 4 | [0, 0] | |
| 86 | + |
| 87 | +```python |
| 88 | +# Access action space |
| 89 | +print(agent.action_space) # Discrete(5) |
| 90 | + |
| 91 | +# Get direction for an action |
| 92 | +direction = agent._actions_to_directions[0] # array([1, 0]) = Right |
| 93 | +``` |
| 94 | + |
| 95 | +### Action Diagram |
| 96 | + |
| 97 | +```text |
| 98 | + Up (1) |
| 99 | + ^ |
| 100 | + | |
| 101 | +Left (2) <---> Right (0) |
| 102 | + | |
| 103 | + v |
| 104 | + Down (3) |
| 105 | +
|
| 106 | +Noop (4) = Stay in place |
| 107 | +``` |
| 108 | + |
| 109 | + |
| 110 | +## Agent Properties |
| 111 | + |
| 112 | +### Identity Properties |
| 113 | + |
| 114 | +| Property | Type | Description | Example | |
| 115 | +| :--- | :--- | :--- | :--- | |
| 116 | +| `agent_type` | `str` | Role of the agent | `"predator"` | |
| 117 | +| `agent_team` | `str` or `int` | Team/subteam identifier | `"predator_1"` | |
| 118 | +| `agent_name` | `str` | Unique display name | `"Hunter"` | |
| 119 | + |
| 120 | +### Gameplay properties |
| 121 | + |
| 122 | +| Property | Type | Description | Default | |
| 123 | +| :--- | :--- | :--- | :--- | |
| 124 | +| `agent_speed` | `int` | Movement multiplier | 1 or 3 | |
| 125 | +| `stamina` | `int` | Energy resource | 10 | |
| 126 | +| `_agent_location` | `np.ndarray` | Current `[x, y]` position | `[0, 0]` | |
| 127 | + |
| 128 | +## Getting Agent information |
| 129 | + |
| 130 | +```python |
| 131 | +# Get current observation |
| 132 | +obs = agent._get_obs() |
| 133 | +print(obs["local"]) # array([x, y]) |
| 134 | + |
| 135 | +# Get agent metadata |
| 136 | +info = agent._get_info() |
| 137 | +print(info) |
| 138 | +# { |
| 139 | +# "name": "Hunter", |
| 140 | +# "type": "predator", |
| 141 | +# "team": "predator_1", |
| 142 | +# "speed": 1, |
| 143 | +# "stamina": 10 |
| 144 | +# } |
| 145 | +``` |
| 146 | + |
| 147 | +### Rendering |
| 148 | +Agents are rendered with distinct colors and shapes for visual identification. |
| 149 | + |
| 150 | +### Colors by Type |
| 151 | +| Agent Type | Base Hue | Color Family | |
| 152 | +| :--- | :--- | :--- | |
| 153 | +| Predator | 0° | Reds | |
| 154 | +| Prey | 120° | Greens | |
| 155 | +| Other | 240° | Blues | |
| 156 | + |
| 157 | +Subteams within the same type get different saturation/brightness levels. |
| 158 | + |
| 159 | +```python |
| 160 | +# Get agent's RGB color |
| 161 | +r, g, b = agent.get_agent_color() |
| 162 | +print(f"RGB: ({r}, {g}, {b})") |
| 163 | +``` |
| 164 | + |
| 165 | +### Shapes by Subteam |
| 166 | + |
| 167 | +Shapes cycle based on subteam ID: |
| 168 | +| Subteam ID | Shape | |
| 169 | +| :--- | :--- | |
| 170 | +| 1 | Circle | |
| 171 | +| 2 | Square | |
| 172 | +| 3 | Triangle | |
| 173 | +| 4 | Star | |
| 174 | +| 5 | Diamond | |
| 175 | +| 6+ | Cycles back to Circle | |
| 176 | + |
| 177 | +## Multi-Agent Setup |
| 178 | +### Creating Multiple Agents |
| 179 | +```python |
| 180 | +from multi_agent_package.agents import Agent |
| 181 | + |
| 182 | +# Create predator team |
| 183 | +predators = [ |
| 184 | + Agent("predator", "predator_1", "Hunter1"), |
| 185 | + Agent("predator", "predator_2", "Hunter2"), |
| 186 | +] |
| 187 | + |
| 188 | +# Create prey team |
| 189 | +prey = [ |
| 190 | + Agent("prey", "prey_1", "Runner1"), |
| 191 | + Agent("prey", "prey_2", "Runner2"), |
| 192 | +] |
| 193 | + |
| 194 | +# Combine for environment |
| 195 | +all_agents = predators + prey |
| 196 | +``` |
| 197 | + |
| 198 | +### 2v2 Configuration example |
| 199 | +```python |
| 200 | +from multi_agent_package.agents import Agent |
| 201 | +from multi_agent_package.gridworld import GridWorldEnv |
| 202 | + |
| 203 | +# Create agents |
| 204 | +agents = [ |
| 205 | + Agent("predator", "predator_1", "P1"), |
| 206 | + Agent("predator", "predator_2", "P2"), |
| 207 | + Agent("prey", "prey_1", "R1"), |
| 208 | + Agent("prey", "prey_2", "R2"), |
| 209 | +] |
| 210 | + |
| 211 | +# Create environment |
| 212 | +env = GridWorldEnv(agents=agents, size=10, render_mode="human") |
| 213 | + |
| 214 | +# Run simulation |
| 215 | +obs, info = env.reset() |
| 216 | +for _ in range(100): |
| 217 | + actions = {agent.agent_name: agent.action_space.sample() for agent in agents} |
| 218 | + obs, rewards, done, truncated, info = env.step(actions) |
| 219 | + if done: |
| 220 | + break |
| 221 | +``` |
| 222 | + |
| 223 | +--- |
| 224 | + |
| 225 | +## Summary |
| 226 | + |
| 227 | +| Concept | Key Points | |
| 228 | +|---------|------------| |
| 229 | +| **Types** | predator (slow), prey (fast), other (custom) | |
| 230 | +| **Teams** | Used for color/shape differentiation | |
| 231 | +| **Actions** | 5 discrete: Right, Up, Left, Down, Noop | |
| 232 | +| **Observations** | Local position + optional global state | |
| 233 | +| **Rendering** | Color by type, shape by subteam | |
| 234 | + |
| 235 | +--- |
| 236 | + |
| 237 | +## API Reference |
| 238 | + |
| 239 | +For complete method documentation, see [Agent API Reference](api/agents.md). |
0 commit comments