agentscape
TypeScript icon, indicating that this package has built-in type declarations

0.16.1 • Public • Published

Agentscape

Agentscape is a library for creating agent-based simulations. It provides a simple API for defining agents and their behavior, and for defining the environment in which the agents interact. Agentscape is designed to be flexible and extensible, allowing users to create a wide variety of simulations.

Examples

Installation

npm i agentscape

Quick Start - Random Walk

We will create a simple simulation where agents move randomly around a grid. We start by defining an agent.

An agent is a class that extends Entities.Agent. The agent must implement an act method that defines the agent's behavior for each step of the simulation.

import { Entities } from 'agentscape'
import { CellGrid } from 'agentscape/structures'

export default class Agent extends Entities.Agent {
    constructor(opts: Entities.AgentConstructor) {
        super(opts)
    }

    // agent moves to a random cell in its field of view
    act(grid: CellGrid<Entities.Cell>) {
        const potentialMoves = this.getCellsWithinCone(grid, 90, 5)

        // if there are no cells in view (ie. agent is facing world boundary),
        // then face a random cell and try again
        if (potentialMoves.length == 0 ) {
            this.faceCell(grid.random(this.rng))
            return this.act(grid)
        }

        const destination = this.rng.pickRandom(potentialMoves)
        this.faceCell(destination)
        this.move(1, grid)
    }
}

Next, we define a model that contains the agents and the grid. A model consists of zero or more agents and one grid of cells.

Agents are grouped into an AgentSet and a Cell is grouped into a CellGrid. The Model must implement methods to initialize agent sets and a cell grid, and an update method that defines the behavior of the model for each step of the simulation.

import { Model, ModelConstructor} from 'agentscape'
import { Cell } from 'agentscape/entities'
import { CellGrid, AgentSet } from 'agentscape/structures'
import Agent from './Agent'
import { Render2D } from 'agentscape/ui'

export default class RandomWalk extends Model<Agent, CellGrid<Cell>> {
    constructor(opts: ModelConstructor) {
        super(opts)
    }

    initAgents() {
        const _default = AgentSet.fromFactory(100, () => new Agent({
            // init position is the center of the 100x100 grid
            initialPosition: [50, 50]
        }))

        return {_default}
    }

    initGrid() {
        // create a 100x100 grid
        // the default grid of cells is sufficient for this example
        return CellGrid.default(100)
    }

    update(): (renderer: Render2D) => void {
        return (renderer: Render2D) => {
            renderer.clear()
            this.agents._default.step(this.grid)
            renderer.drawAgentSet(this.agents._default)
        }
    }
}

Finally, we create an instance of the model and run the simulation.

import RandomWalkModel from './Model'

const documentRoot = document.getElementById('root') as HTMLDivElement

const model = new RandomWalkModel({
    documentRoot,
    renderWidth: 800,
    id: 'random-walk',
    autoPlay: false,
    frameRate: 10,
})

model.start()

random-walk-example

Adding Parameters

We can add parameters to the model that can be controlled by the user. Parameters are defined as an array of ControlVariable objects and passed to the model constructor.

import { ControlVariable } from 'agentscape/ui'

const parameters: ControlVariable[] = [
    {
        label: 'Grid Size',
        name: 'gridSize',
        type: 'number',
        default: 100
    },
    {
        label: 'Number of Agents',
        name: 'agentCount',
        type: 'number',
        default: 100
    },
    {
        label: 'Random Seed',
        name: 'randomSeed',
        type: 'number',
        default: 0
    }
]

const model = new RandomWalkModel({
    documentRoot,
    renderWidth: 800,
    title: 'Random Walk',
    id: 'random-walk',
    parameters,
    autoPlay: false,
    frameRate: 10,
})

The parameters can be accessed in the scope of the model class as properties by using the @ControlVariable decorator.

export default class RandomWalk extends Model<Agent, CellGrid<Cell>> {
    @ControlVariable('gridSize')
        gridSize: number

    @ControlVariable('agentCount')
        agentCount: number

    @ControlVariable('randomSeed')
        randomSeed: number

    constructor(opts: ModelConstructor) {
        super(opts)
        this.setRandomSeed(this.randomSeed)
    }

    initAgents() {
        const _default = AgentSet.fromFactory(this.agentCount, () => new Agent({
            // init position is the center of the 100x100 grid
            initialPosition: [Math.floor(this.gridSize / 2), Math.floor(this.gridSize / 2)],
        }))

        return {_default}
    }

    initGrid() {
        return CellGrid.default(this.gridSize)
    }

    update(): (renderer: Render2D) => void {
        return (renderer: Render2D) => {
            renderer.clear()
            this.agents._default.step(this.grid)
            renderer.drawAgentSet(this.agents._default)
        }
    }
}

Package Sidebar

Install

npm i agentscape

Weekly Downloads

174

Version

0.16.1

License

none

Unpacked Size

427 kB

Total Files

145

Last publish

Collaborators

  • bgoodman