diff options
Diffstat (limited to 'v_windows/v/examples/game_of_life')
-rw-r--r-- | v_windows/v/examples/game_of_life/README.md | 10 | ||||
-rw-r--r-- | v_windows/v/examples/game_of_life/life.v | 25 | ||||
-rw-r--r-- | v_windows/v/examples/game_of_life/life_gg.v | 56 | ||||
-rw-r--r-- | v_windows/v/examples/game_of_life/modules/automaton/automaton.v | 132 |
4 files changed, 223 insertions, 0 deletions
diff --git a/v_windows/v/examples/game_of_life/README.md b/v_windows/v/examples/game_of_life/README.md new file mode 100644 index 0000000..02969ff --- /dev/null +++ b/v_windows/v/examples/game_of_life/README.md @@ -0,0 +1,10 @@ +# Conway's Game of Life + +![](https://github.com/fuyutarow/Conways-Game-of-Life-with-Vlang/raw/master/v-gun.gif) + + +``` +v run life.v +``` + +Created by fuyutarow: https://github.com/fuyutarow/Conways-Game-of-Life-with-Vlang diff --git a/v_windows/v/examples/game_of_life/life.v b/v_windows/v/examples/game_of_life/life.v new file mode 100644 index 0000000..0f3b7c7 --- /dev/null +++ b/v_windows/v/examples/game_of_life/life.v @@ -0,0 +1,25 @@ +module main + +import time +import automaton + +fn print_automaton(a &automaton.Automaton) { + for y := 1; y < a.field.maxy; y++ { + mut s := ' ' + for x := 1; x < a.field.maxx; x++ { + cell := a.field.get(x, y) + s += if cell == 1 { '@' } else { '.' } + } + println(s) + } + println('') +} + +fn main() { + mut a := automaton.gun() + for { + a.update() + print_automaton(a) + time.sleep(100 * time.millisecond) + } +} diff --git a/v_windows/v/examples/game_of_life/life_gg.v b/v_windows/v/examples/game_of_life/life_gg.v new file mode 100644 index 0000000..2f45017 --- /dev/null +++ b/v_windows/v/examples/game_of_life/life_gg.v @@ -0,0 +1,56 @@ +module main + +import gg +import gx +import automaton + +const ( + screen_width = 800 + screen_height = 600 + filled_color = gx.blue +) + +[live] +fn print_automaton(app &App) { + square_size := 18 + for y := 1; y < app.a.field.maxy; y++ { + for x := 1; x < app.a.field.maxx; x++ { + cell := app.a.field.get(x, y) + if cell == 1 { + app.gg.draw_rect(f32(square_size * x), f32(square_size * y), f32(square_size), + f32(square_size), filled_color) + } + } + } +} + +struct App { +mut: + gg &gg.Context + a automaton.Automaton +} + +fn frame(mut app App) { + app.gg.begin() + app.a.update() + print_automaton(app) + app.gg.end() +} + +fn main() { + mut app := App{ + gg: 0 + a: automaton.gun() + } + app.gg = gg.new_context( + bg_color: gx.white + frame_fn: frame + user_data: &app + width: screen_width + height: screen_height + create_window: true + resizable: false + window_title: 'v life (with gg, gx)' + ) + app.gg.run() +} diff --git a/v_windows/v/examples/game_of_life/modules/automaton/automaton.v b/v_windows/v/examples/game_of_life/modules/automaton/automaton.v new file mode 100644 index 0000000..5c0bf06 --- /dev/null +++ b/v_windows/v/examples/game_of_life/modules/automaton/automaton.v @@ -0,0 +1,132 @@ +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: unsafe { &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 + _ = e // TODO compiler bug, this is not necessary + } +} + +[inline] +pub fn (a &A2D) get(x int, y int) int { + unsafe { + mut e := &int(0) + e = a.data + y * a.maxx + x + _ = e + 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) +} |