Class Definition and Instantiation
Declaring a Class​
A class block defines a pure data/logic type — not an agent, no population, no reflex.
class point2d {
/** Horizontal coordinate. Defaults to 0.0. */
float x <- 0.0;
/** Vertical coordinate. Defaults to 0.0. */
float y <- 0.0;
/**
* Returns the Euclidean distance from this point to another point.
* Returns a float.
*/
float distance_to(point2d other) {
return sqrt((x - other.x) ^ 2 + (y - other.y) ^ 2);
}
/**
* Returns a human-readable representation like "(3.0, 4.0)".
* Returns a string.
*/
string to_string() {
return "(" + x + ", " + y + ")";
}
}
Key Points​
- The
classkeyword introduces a new object type. - Attributes are declared exactly like species variables, with optional default values (
<- 0.0). - Actions are declared like species actions but operate on the object instance (
this). - The built-in root class
objectis the implicit parent of every class that does not declare an explicit parent.
Instantiating Objects​
The constructor syntax is a call to the class name with attributes as facets:
point2d p1 <- point2d(x: 3.0, y: 4.0);
// p1.x = 3.0, p1.y = 4.0
point2d p2 <- point2d(x: 6.0);
// p2.x = 6.0, p2.y = 0.0 (y keeps its default)
point2d origin <- point2d();
// origin.x = 0.0, origin.y = 0.0 (both use defaults)
Only the listed attributes are overridden — the rest keep their defaults.
Accessing Object Members​
Use the dot operator:
write p1.to_string(); // call action: (3.0, 4.0)
write p1.x; // read attribute: 3.0
p1.x <- 5.0; // write attribute
write p1.to_string(); // (5.0, 4.0)
Objects Are Values​
Objects are ordinary GAML values: they can be stored in variables, put in lists, passed as arguments, and returned from actions.
list<point2d> pts <- [
point2d(x: 1.0, y: 0.0),
point2d(x: 2.0, y: 0.0),
point2d(x: 4.0, y: 0.0),
point2d(x: 7.0, y: 0.0)
];
// Iterate over the list
loop p in: pts {
write p.to_string();
}
Nil Objects​
An uninitialized object variable is nil:
point2d maybe_nil;
if maybe_nil != nil {
write maybe_nil.to_string();
} else {
write "maybe_nil is nil — need to instantiate it.";
}
Object Composition​
Objects of one class can be attributes of another class:
class segment2d {
string label <- "seg";
point2d start <- point2d();
point2d end_pt <- point2d();
rgb color <- #gray;
float length() {
return start.distance_to(end_pt);
}
}
A segment2d has point2d objects as attributes — demonstrating that object composition works naturally in GAML.
Example: Full Model​
model ClassDefinitionAndInstantiation
class point2d {
float x <- 0.0;
float y <- 0.0;
float distance_to(point2d other) {
return sqrt((x - other.x) ^ 2 + (y - other.y) ^ 2);
}
string to_string() {
return "(" + x + ", " + y + ")";
}
}
global {
init {
// Constructor with all attributes
point2d p1 <- point2d(x: 3.0, y: 4.0);
write "p1 = " + p1.to_string(); // (3.0, 4.0)
// Constructor with partial attributes
point2d p2 <- point2d(x: 6.0);
write "p2 = " + p2.to_string(); // (6.0, 0.0)
// Distance between points
write "distance(p1, p2) = " + (p1.distance_to(p2) with_precision 3);
// Objects in a list
list<point2d> pts <- [ point2d(x:1.0,y:0.0), point2d(x:7.0,y:0.0) ];
write "First point: " + pts[0].to_string();
}
}
experiment Class_Definition_and_Instantiation title: "Class Definition and Instantiation" type: gui {}