135 lines
3.3 KiB
V
135 lines
3.3 KiB
V
module automaton
|
|
|
|
// ///////////////////////////////////////////////////////////
|
|
pub struct A2D {
|
|
pub mut:
|
|
maxx int
|
|
maxy int
|
|
data &int
|
|
}
|
|
|
|
fn new_a2d(maxx int, maxy int) &A2D {
|
|
size := int(sizeof(int)) * (maxx * maxy)
|
|
return &A2D{
|
|
maxx: maxx
|
|
maxy: maxy
|
|
data: &int(vcalloc(size))
|
|
}
|
|
}
|
|
|
|
[inline]
|
|
pub fn (a &A2D) set(x int, y int, newval int) {
|
|
unsafe {
|
|
mut e := &int(0)
|
|
e = a.data + y * a.maxx + x
|
|
*e = newval
|
|
}
|
|
}
|
|
|
|
[inline]
|
|
pub fn (a &A2D) get(x int, y int) int {
|
|
unsafe {
|
|
mut e := &int(0)
|
|
e = a.data + y * a.maxx + x
|
|
return *e
|
|
}
|
|
}
|
|
|
|
[inline]
|
|
pub fn (a &A2D) clear() {
|
|
for y := 0; y < a.maxy; y++ {
|
|
for x := 0; x < a.maxx; x++ {
|
|
a.set(x, y, 0)
|
|
}
|
|
}
|
|
}
|
|
|
|
// ///////////////////////////////////////////////////////////
|
|
pub struct Automaton {
|
|
pub mut:
|
|
field &A2D
|
|
new_field &A2D
|
|
}
|
|
|
|
fn new_automaton(ftext string) Automaton {
|
|
f := ftext.split('\n').map(it.trim_space()).filter(it.len > 0)
|
|
maxy := f.len
|
|
mut maxx := 0
|
|
for y := 0; y < f.len; y++ {
|
|
if maxx < f[y].len {
|
|
maxx = f[y].len
|
|
}
|
|
}
|
|
field := new_a2d(maxx, maxy)
|
|
new_field := new_a2d(maxx, maxy)
|
|
for y in 0 .. field.maxy {
|
|
for x in 0 .. field.maxx {
|
|
val := if x < f[y].len && f[y][x] == `#` { 1 } else { 0 }
|
|
field.set(x, y, val)
|
|
}
|
|
}
|
|
return Automaton{
|
|
field: field
|
|
new_field: new_field
|
|
}
|
|
}
|
|
|
|
pub fn (mut aa Automaton) update() {
|
|
aa.new_field.clear()
|
|
for y := 1; y < aa.field.maxy; y++ {
|
|
for x := 1; x < aa.field.maxx; x++ {
|
|
moore_sum := (0 + aa.field.get(x - 1, y - 1) + aa.field.get(x, y - 1) + aa.field.get(x +
|
|
1, y - 1) + aa.field.get(x - 1, y) + 0 + aa.field.get(x + 1, y) + aa.field.get(x - 1, y + 1) +
|
|
aa.field.get(x, y + 1) + aa.field.get(x + 1, y + 1))
|
|
cell := aa.field.get(x, y)
|
|
v := if cell == 1 { moore_sum in [2, 3] } else { moore_sum == 3 }
|
|
aa.new_field.set(x, y, if v {
|
|
1
|
|
} else {
|
|
0
|
|
})
|
|
}
|
|
}
|
|
tmp := aa.field
|
|
aa.field = aa.new_field
|
|
aa.new_field = tmp
|
|
}
|
|
|
|
pub fn gun() Automaton {
|
|
field := '
|
|
*******************************************
|
|
* *
|
|
* A shooting gun: *
|
|
* # *
|
|
* # # *
|
|
* ## ## ## *
|
|
* # # ## ## *
|
|
* ## # # ## *
|
|
* ## # # ## # # *
|
|
* # # # *
|
|
* # # *
|
|
* ## *
|
|
* *
|
|
* Tetris Life: *
|
|
* *
|
|
* ## #### *
|
|
* ## *
|
|
* *
|
|
* *
|
|
* *
|
|
* # ## *
|
|
* ### ## *
|
|
* *
|
|
* *
|
|
* *
|
|
* # *
|
|
* ### *
|
|
* *
|
|
* *
|
|
* *
|
|
* *
|
|
*******************************************
|
|
'
|
|
return new_automaton(field)
|
|
}
|