diff options
Diffstat (limited to 'v_windows/v/examples/game_of_life/modules')
| -rw-r--r-- | v_windows/v/examples/game_of_life/modules/automaton/automaton.v | 132 | 
1 files changed, 132 insertions, 0 deletions
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) +}  | 
