rendering & simulation steps
commit
712bef2337
|
@ -0,0 +1 @@
|
|||
__pycache__
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Python: main.py",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
//"program": "${file}",
|
||||
"program": "main.py",
|
||||
"console": "integratedTerminal",
|
||||
"justMyCode": true
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
from sim import Environment, CAMSReverseAndSidestepAgent, Direction
|
||||
import time
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
STEPS = 1000
|
||||
FRAME_DELAY = 1/60
|
||||
|
||||
|
||||
# Fixing random state for reproducibility
|
||||
np.random.seed(12345)
|
||||
|
||||
env = Environment((40, 30))
|
||||
first_agent = CAMSReverseAndSidestepAgent(
|
||||
environment=env,
|
||||
position=(20,15),
|
||||
initial_direction=Direction.NORTH
|
||||
)
|
||||
|
||||
fig, ax = plt.subplots()
|
||||
im = ax.imshow(env.render(), aspect="equal", origin="lower")
|
||||
fig.show()
|
||||
|
||||
for i in range(1, STEPS+1):
|
||||
print(i)
|
||||
plt.pause(FRAME_DELAY)
|
||||
env.step()
|
||||
im.set_data(env.render())
|
||||
fig.canvas.draw()
|
|
@ -0,0 +1,143 @@
|
|||
import numpy as np
|
||||
from enum import Enum, auto
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
class Direction(Enum):
|
||||
NORTH = (0, 1)
|
||||
SOUTH = (0, -1)
|
||||
WEST = (-1, 0)
|
||||
EAST = (1, 0)
|
||||
|
||||
class CellState(Enum):
|
||||
OPEN = auto()
|
||||
WALL = auto()
|
||||
|
||||
class Colours(Enum):
|
||||
WALL = [30,30,30]
|
||||
STOCKED = [200,100,0]
|
||||
DEPLETED = [0,50,50]
|
||||
UNDEFINED = [255,0,255]
|
||||
AGENT = [0,255,0]
|
||||
|
||||
class Cell():
|
||||
def __init__(self, state, resources):
|
||||
self.state = state
|
||||
self.resources = resources
|
||||
|
||||
def get_colour(self):
|
||||
if self.state is CellState.WALL:
|
||||
return Colours.WALL
|
||||
elif self.state is CellState.OPEN:
|
||||
if self.resources > 0:
|
||||
return Colours.STOCKED
|
||||
elif self.resources == 0:
|
||||
return Colours.DEPLETED
|
||||
else:
|
||||
return Colours.UNDEFINED
|
||||
else:
|
||||
return Colours.UNDEFINED
|
||||
|
||||
class Environment:
|
||||
def __init__(self, shape):
|
||||
self.shape = shape
|
||||
self.agents = []
|
||||
|
||||
self.resource_map = np.round(
|
||||
np.random.normal(loc=50, scale=10, size=shape)
|
||||
)
|
||||
|
||||
cols, rows = shape
|
||||
self.cells = [[] for _ in range(rows)]
|
||||
for y in range(rows):
|
||||
for x in range(cols):
|
||||
if (x == 0 or y == 0 or x+1==cols or y+1==rows):
|
||||
self.cells[y].append(Cell(CellState.WALL, 0))
|
||||
else:
|
||||
self.cells[y].append(Cell(CellState.OPEN, self.resource_map[x,y]))
|
||||
|
||||
def step(self):
|
||||
for agent in self.agents:
|
||||
agent.step()
|
||||
|
||||
def render(self):
|
||||
cols, rows = self.shape
|
||||
pixel_data = [[] for _ in range(rows)]
|
||||
|
||||
for y in range(self.shape[1]):
|
||||
for x in range(self.shape[0]):
|
||||
#print((x, y, self.cell((x,y)).state, self.cell((x,y)).get_colour().value))
|
||||
pixel_data[y].append(self.cell((x,y)).get_colour().value)
|
||||
|
||||
for agent in self.agents:
|
||||
x, y = agent.position
|
||||
pixel_data[y][x] = Colours.AGENT.value
|
||||
|
||||
return np.array(pixel_data)
|
||||
|
||||
def cell(self, position):
|
||||
x, y = tuple(position)
|
||||
return self.cells[y][x]
|
||||
|
||||
def is_wall(self, position):
|
||||
x, y = tuple(position)
|
||||
return self.cells[y][x].state == CellState.WALL
|
||||
|
||||
def register_agent(self, agent):
|
||||
self.agents.append(agent)
|
||||
|
||||
def unregister_agent(self, agent):
|
||||
self.agents.remove(agent)
|
||||
|
||||
class Agent:
|
||||
def __init__(self, environment, position):
|
||||
self.position = np.array(position)
|
||||
self.environment = environment
|
||||
self.environment.register_agent(self)
|
||||
|
||||
def step(self):
|
||||
pass
|
||||
|
||||
def move(self, direction, respect_walls=True):
|
||||
new_position = self.position + direction.value
|
||||
if respect_walls and self.environment.is_wall(new_position):
|
||||
return False
|
||||
else:
|
||||
self.position = new_position
|
||||
return True
|
||||
|
||||
def die(self):
|
||||
self.environment.unregister_agent(self)
|
||||
|
||||
class DirectionalAgent(Agent):
|
||||
def __init__(self, environment, position, initial_direction):
|
||||
super().__init__(environment, position)
|
||||
self.direction = initial_direction
|
||||
|
||||
def get_cell_in_front(self):
|
||||
position_in_front = self.position + self.direction.value
|
||||
return self.environment.cell(position_in_front)
|
||||
|
||||
def wall_in_front(self):
|
||||
position_in_front = self.position + self.direction.value
|
||||
return self.environment.is_wall(position_in_front)
|
||||
|
||||
def turn_left(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def turn_right(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def reverse_direction(self):
|
||||
new_vector = np.array(self.direction.value) * -1
|
||||
self.direction = Direction(tuple(new_vector))
|
||||
|
||||
class CAMSReverseAndSidestepAgent(DirectionalAgent):
|
||||
def __init__(self, environment, position, initial_direction, required_resources = 100):
|
||||
super().__init__(environment, position, initial_direction)
|
||||
self.resources = 0
|
||||
self.required_resources = required_resources
|
||||
|
||||
def step(self):
|
||||
if self.wall_in_front():
|
||||
self.reverse_direction()
|
||||
self.move(self.direction)
|
Loading…
Reference in New Issue