Home

Awesome

wolves-and-rabbits-world-simulation

Description

This is an implementation of an assignment described by Francessco Cessarini here.

A textual description:

We had to implement a simulated world inhabited by carrots, rabbits, and wolves. Rabbits would roam this world eating carrots that grew in random patches. When they had eaten enough carrots, the rabbits would get fat and split in two. Wolves ran around eating up the rabbits; if they managed to catch and eat enough rabbits, they would also get fat and split. Rabbits and wolves within a certain distance of each other would broadcast information on food and predators. If a rabbit found a carrot patch, other rabbits would quickly join him. If a wolf found a rabbit, the pack would start chasing it.

How to build and run it?

  1. Grab rebar3 binaries from here.
  2. rebar3 compile
  3. erl -pa _build/default/lib/wolves_and_rabbits_world_simulation/ebin
  4. Invoke following commands in the Erlang shell:
  1. If you would like to run tests, invoke command: rebar3 ct.

Supported and tested on:

Architecture

Each carrot, rabbit and wolf on the board is represented as a separate process inside Erlang VM. All of them will be spawned underneath one of the entities supervisor. Process of starting and stopping the simulation can be observed below:

Starting and stopping the simulation

Massive amount of processes has been spawned during the simulation start. Amount can be defined in the application env configuration, but also sensible defaults are setup inside the code. Besides the entities, we can distinguish following modules in the application's architecture:

Here you can see how the structure of main supervision tree for this application looks like:

Main supervision tree for wolves_and_rabbits_world_simulation application

First two anonymous processes are related with the Erlang application behavior.

Regarding state changes which are occurring during the simulation - each movement, death, birth, bite etc. is reported as a separate event. By default Erlang application connects only the CLI handler, which prints all events to the console. But nothing stops you from adding your custom event handler, in order to react for the changes in your own way - simulation_event_stream:attach_handler/1 is designed to handle that requirement. Prepared event handler passed to aforementioned function must implement the gen_event behavior. On each handle_event/2 it will receive as a first argument tuple with three elements - first is an information which entity send an event (carrot, rabbit or wolf), second is an actual event name (e.g. eaten) and third will be an internal state of the entity (represented as a record).

Example event:

{carrot,eaten,{carrot,<0.297.0>,{world_parameters,50,20,10,20,20},{position,11,17},4}}