Code - R7

Nature of Code 之 7 - CA

Game of Life

O_o

module main

import rand
import gg
import gx

pub struct Cell {
mut:
	x          int
	y          int
	state      int
	prev_state int
}

pub fn new_cell(x_ int, y_ int) Cell {
	st := rand.intn(2)
	return Cell{
		x: x_
		y: y_
		state: st
		prev_state: st
	}
}

pub fn (mut c Cell) save_prev_state() {
	c.prev_state = c.state
}

pub fn (mut c Cell) new_state(s int) {
	c.state = s
}

pub struct Gol {
mut:
	w       int
	columns int
	rows    int
	board   [][]Cell
}

pub fn new_gol(width int, height int, w_ int) &Gol {
	col := height / w_
	row := width / w_
	mut bo := [][]Cell{len: col, init: []Cell{len: row}}
	for i := 0; i < col; i++ {
		for j := 0; j < row; j++ {
			bo[i][j] = new_cell(j, i)
		}
	}
	return &Gol{
		w: w_
		columns: col
		rows: row
		board: bo
	}
}

pub fn (mut g Gol) generate() {
	for i := 0; i < g.columns; i++ {
		for j := 0; j < g.rows; j++ {
			g.board[i][j].save_prev_state()
		}
	}
	// Loop through every spot in our 2D array and check spots neighbors
	for y := 0; y < g.columns; y++ {
		for x := 0; x < g.rows; x++ {
			// Add up all the states in a 3x3 surrounding grid
			mut neighbors := 0
			for i := -1; i <= 1; i++ {
				for j := -1; j <= 1; j++ {
					neighbors += g.board[(y + i + g.columns) % g.columns][(x + j + g.rows) % g.rows].prev_state
				}
			}
			neighbors -= g.board[y][x].prev_state
			if g.board[y][x].state == 1 && neighbors < 2 {
				g.board[y][x].new_state(0)
			} else if g.board[y][x].state == 1 && neighbors > 3 {
				g.board[y][x].new_state(0)
			} else if g.board[y][x].state == 0 && neighbors == 3 {
				g.board[y][x].new_state(1)
			}
		}
	}
}

struct App {
mut:	
	gg  &gg.Context
	gol &Gol
}

fn main() {
	mut app := &App{
		gg: 0
		gol: 0
	}
	app.gg = gg.new_context(
		bg_color: gx.black
		width: 640
		height: 480
		create_window: true
		window_title: 'Game of Life'
		frame_fn: frame
		user_data: app
	)
	app.gol = new_gol(640, 480, 8)
	app.gg.run()
}

fn frame(mut app &App) {
	app.gg.begin()
	app.gol.generate()
	app.draw()
	app.gg.end()
}

fn (app &App) draw() {
	w := app.gol.w
	for i := 0; i < app.gol.columns; i++ {
		for j := 0; j < app.gol.rows; j++ {
			if app.gol.board[i][j].state == 1 {
				app.gg.draw_rect_filled(j * w, i * w,w,w,gx.yellow)
			} else {
				app.gg.draw_rect_filled(j * w, i * w,w,w,gx.black)
			}
		}
	}
}

See also