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)
 | 
						|
}
 |