v2 / examples / game_of_life / modules / automaton / automaton.v
131 lines · 122 sloc · 3.37 KB · e2e5cf8db56f3562c7baa735061690be936bdf3e
Raw
1module automaton
2
3// ///////////////////////////////////////////////////////////
4pub struct A2D {
5pub mut:
6 maxx int
7 maxy int
8 data &int
9}
10
11fn new_a2d(maxx int, maxy int) &A2D {
12 size := int(sizeof(int)) * (maxx * maxy)
13 return &A2D{
14 maxx: maxx
15 maxy: maxy
16 data: unsafe { &int(vcalloc(size)) }
17 }
18}
19
20@[inline]
21pub fn (a &A2D) set(x int, y int, newval int) {
22 unsafe {
23 mut e := &int(0)
24 e = a.data + y * a.maxx + x
25 *e = newval
26 }
27}
28
29@[inline]
30pub fn (a &A2D) get(x int, y int) int {
31 unsafe {
32 mut e := &int(0)
33 e = a.data + y * a.maxx + x
34 _ = e
35 return *e
36 }
37}
38
39@[inline]
40pub fn (a &A2D) clear() {
41 for y := 0; y < a.maxy; y++ {
42 for x := 0; x < a.maxx; x++ {
43 a.set(x, y, 0)
44 }
45 }
46}
47
48// ///////////////////////////////////////////////////////////
49pub struct Automaton {
50pub mut:
51 field &A2D = unsafe { nil }
52 new_field &A2D = unsafe { nil }
53}
54
55fn new_automaton(ftext string) Automaton {
56 f := ftext.split('\n').map(it.trim_space()).filter(it.len > 0)
57 maxy := f.len
58 mut maxx := 0
59 for y := 0; y < f.len; y++ {
60 if maxx < f[y].len {
61 maxx = f[y].len
62 }
63 }
64 field := new_a2d(maxx, maxy)
65 new_field := new_a2d(maxx, maxy)
66 for y in 0 .. field.maxy {
67 for x in 0 .. field.maxx {
68 val := if x < f[y].len && f[y][x] == `#` { 1 } else { 0 }
69 field.set(x, y, val)
70 }
71 }
72 return Automaton{
73 field: field
74 new_field: new_field
75 }
76}
77
78pub fn (mut aa Automaton) update() {
79 aa.new_field.clear()
80 for y := 1; y < aa.field.maxy; y++ {
81 for x := 1; x < aa.field.maxx; x++ {
82 moore_sum := (0 + aa.field.get(x - 1, y - 1) + aa.field.get(x, y - 1) + aa.field.get(x +
83 1, y - 1) + aa.field.get(x - 1, y) + 0 + aa.field.get(x + 1, y) + aa.field.get(x -
84 1, y + 1) + aa.field.get(x, y + 1) + aa.field.get(x + 1, y + 1))
85 cell := aa.field.get(x, y)
86 v := if cell == 1 { moore_sum in [2, 3] } else { moore_sum == 3 }
87 aa.new_field.set(x, y, if v { 1 } else { 0 })
88 }
89 }
90 tmp := aa.field
91 aa.field = aa.new_field
92 aa.new_field = tmp
93}
94
95pub fn gun() Automaton {
96 field := '
97*******************************************
98* *
99* A shooting gun: *
100* # *
101* # # *
102* ## ## ## *
103* # # ## ## *
104* ## # # ## *
105* ## # # ## # # *
106* # # # *
107* # # *
108* ## *
109* *
110* Tetris Life: *
111* *
112* ## #### *
113* ## *
114* *
115* *
116* *
117* # ## *
118* ### ## *
119* *
120* *
121* *
122* # *
123* ### *
124* *
125* *
126* *
127* *
128*******************************************
129'
130 return new_automaton(field)
131}
132