93 lines
2.4 KiB
Plaintext
93 lines
2.4 KiB
Plaintext
// complex data is passed and manipulated in structures
|
|
struct World {
|
|
// each member is defined by name and type
|
|
u32 xsize,
|
|
u32 ysize,
|
|
BitArray current,
|
|
u32 numdots,
|
|
BitArray next,
|
|
|
|
// TODO member default initialization
|
|
i32 xmin, // = 1'000'000,
|
|
i32 xmax, // = -1,
|
|
i32 ymin, // = 1'000'000,
|
|
i32 ymax, // = -1,
|
|
}
|
|
|
|
// non-associated function, operates in the scope of its arguments only
|
|
// `fn fn_name(args) return_value { body }`
|
|
fn count_neighbors(BitArray array, i32 i, i32 j) i32 {
|
|
// local variables are declared with `let`
|
|
let c1 = i - 1;
|
|
let c2 = i;
|
|
let c3 = i + 1;
|
|
|
|
let r1 = i - 1;
|
|
let r2 = i;
|
|
let c3 = i + 1;
|
|
|
|
// associated functions of a struct can be stored in a variable
|
|
// now `g(x, y)` is shorthand for `array.get(x, y)`
|
|
let g = array.get;
|
|
|
|
// return result with trailing expression at the end of function
|
|
g(c1, r1) + g(c1, r2) + g(c1, r3) +
|
|
g(c2, r1) + g(c2, r3) +
|
|
g(c3, r1) + g(c3, r2) + g(c3, r3)
|
|
}
|
|
|
|
// associated function for the World struct
|
|
World mut fn set_next(i32 i, i32 j) {
|
|
// members on this World struct can be accessed with `.`
|
|
let mut numdots = .numdots; // mutable variables are defined with `let mut`
|
|
let neighbors = count_neighbors(.current, i, j);
|
|
|
|
// `if` statements are expressions
|
|
let next = if .current.get(i, j) == 0 {
|
|
if neighbors != 3 {
|
|
0
|
|
} else {
|
|
// TODO binary operator assignment shorthand
|
|
numdots = numdots + 1;
|
|
1
|
|
}
|
|
} else {
|
|
// Python-like `or` operator
|
|
if neighbors == 2 or neighbors == 3 {
|
|
1
|
|
} else {
|
|
// TODO binary operator assignment shorthand
|
|
numdots = numdots - 1;
|
|
0
|
|
}
|
|
};
|
|
|
|
if next != 0 {
|
|
if i < .xmin { .xmin = i; }
|
|
if i > .xmax { .xmax = i; }
|
|
if j < .ymin { .ymin = j; }
|
|
if j > .ymax { .ymax = j; }
|
|
}
|
|
}
|
|
|
|
World fn next_cycle() {
|
|
let xlb = .xmin - 1;
|
|
let xub = .xmax + 1;
|
|
let ylb = .ymin - 1;
|
|
let yub = .ymax + 1;
|
|
|
|
// TODO: flesh out `for` semantics
|
|
for y in ylb..yub {
|
|
for x in xlb..xub {
|
|
.set_next(x, y);
|
|
}
|
|
}
|
|
|
|
// TODO: figure out better range definitions, or ditch them altogether
|
|
for y in 0..(.ysize) {
|
|
for x in 0..(.xsize) {
|
|
.current.set_bit(x, y, .next.get_bit(x, y));
|
|
}
|
|
}
|
|
}
|