/**
* Name: Pong Teleportation
* Author: Nicolas Marilleau
* Description: This model show how to send complex data (as an agent) by using list or map. In this multi-simulation, the space is distributed
* on 3 (nb_simul) simulation running in parallel. Each simulation manage local space and agent moving in this local space. When an agent go inside a
* buffer zone, it is teleported to the next simulation (remove from the first and created inside the next one).
* Tags: Network, TCP, multi-simulation
*/
model PongTeleportation
global {
int numberOfSimulation <- 3;
int simulation_id <- 0;
string prefixName <- "SIMULATION_";
geometry shape <- rectangle(200, 100);
init {
name <- prefixName + simulation_id;
create Pong number: 10 {
myColor <- rnd_color(255);
}
create Buffer with: [zone::0];
create Buffer with: [zone::1];
}
}
species Buffer skills: [network] {
int zone;
string next_agent;
init {
name <- "buffer_" + world.name + string(zone);
next_agent <- "buffer_" + (world.prefixName + ((1 + simulation_id) mod numberOfSimulation)) + string((zone + 1) mod 2);
shape <- rectangle(10, 100);
if (zone = 0) {
location <- point(5, 50);
} else {
location <- point(195, 50);
}
if (simulation_id = 0) {
do connect to: "localhost" with_name: name protocol: "tcp_server" port: 3001;
do join_group with_name: "server_group";
} else {
do connect to: "localhost" with_name: name protocol: "tcp_client" port: 3001;
do join_group with_name: "buffer";
write "my name " + name + " " + next_agent;
}
}
reflex teleport {
list to_move <- Pong where (each.last_zone = -1 and each overlaps shape);
loop ping over: to_move {
write "send agent";
map msg <- map(["name"::ping.name, "mcolor"::ping.myColor, "location"::(ping.location - {self.location.x, 0})]);
string smsg <- serialize(msg);
do send to: next_agent contents: msg;
ask ping {
do die;
}
}
}
reflex enable_teleport {
list internal <- Pong where (each.last_zone = self.zone and !(self.shape overlaps each.location));
ask internal {
last_zone <- -1;
}
}
reflex retrieve_agent when: has_more_message() {
loop while: has_more_message() {
message msg <- fetch_message();
map details <- map(msg.contents);
create Pong with: [name:: details["name"], myColor::details["mcolor"], location::details["location"]] {
write "received agent";
location <- {myself.location.x, location.y};
last_zone <- myself.zone;
}
}
}
aspect default {
draw shape color: #pink;
}
}
species Pong {
rgb myColor;
int last_zone <- -1;
reflex pongMove {
location <- location + {1, 0};
}
aspect default {
draw circle(2) color: myColor;
}
}
experiment start {
//definition of a minimal duration for each cycle. As the model is very simple, it can run too fast to observe the results, so we slow it down.
float minimum_cycle_duration <- 0.05;
init {
int nb_simul <- 3;
simulation_id <- 0;
seed <- 1.0;
loop i from: 1 to: nb_simul - 1 {
create simulation with: [simulation_id::i, seed::1 + i, numberOfSimulation::nb_simul];
}
}
output {
layout horizontal([0::5000, 1::5000, 2::5000]) tabs: true editors: false;
display map {
species Pong;
species Buffer transparency: 0.5;
}
}
}