gol_lib/
lib.rs

1// Copyright Damien Lejosne 2021. See LICENSE for more informations
2//! This crate allow you tu create an play the famous "game of life" of John Conway.\
3//! ***But what is game of life ?***\
4//! It is an automata invented by John Conway in the 70s.\
5//! It is composed of an infinite grid (in practice it is finite), of which cell can be in two state : dead or alive.\
6//! The neigbourhood of a cell is the 8 cells which around it (e.g bottom, top, left, right and diagonals).\
7//! If an alive cell has two or three neighboors who are alive, it becomes alive. Else, it dies.\
8//! If a dead cell has three neighboors who are alive, it becomes alive. Else, it stays dead.\
9//! So what you have to do is just create an automata, set some cells (to meke them alive) and to see how it evoluates !\
10//! ***Have fun !***
11mod ansi_rust;
12pub use ansi_rust::*;
13
14///Class of game of life.\
15///To create a new game of life with a grid of 25 collumns wide and 45 lines height, use :\
16///```rust
17///fn main(){
18///    let mut game = GameOfLife::new(25, 45);
19///}
20///```
21pub struct GameOfLife{
22	nb_col:usize,
23	nb_lig:usize,
24
25	grid: Vec<Vec<bool>>,
26}
27impl GameOfLife{
28	pub fn new(nb_col:usize, nb_lig:usize) -> GameOfLife{
29		let mut new_g = GameOfLife{
30							nb_col:nb_col,
31							nb_lig:nb_lig,
32							grid: Vec::with_capacity(nb_lig)
33						 };
34		for i in 0..nb_lig{
35			new_g.grid.push(Vec::with_capacity(nb_col));
36			for _ in 0..nb_col {
37				new_g.grid[i].push(false);
38			}
39		}
40		new_g
41	}
42	///Function to set the value of an element.\
43	///For exemple, to set the element at position 5, 5 (e.g. to make the cell alive), do :\
44	/// /!\ Pay attention ! : It is the collumn first, and **after** the line.\
45	///```rust
46	///fn main(){
47	///    let mut game = GameOfLife::new(25, 45);
48	///    game.set_element(5,5);
49	///}
50	///```
51	pub fn set_element(&mut self, i_col:usize, i_lig:usize){
52		self.grid[i_lig][i_col] = true;
53	}
54	///Function to reset the value of an element.\
55	///For exemple, to reset the element at position 5, 5 (e.g. to kill the cell), do :\
56	/// /!\ Pay attention ! : It is the collumn first, and **after** the line.\
57	///```rust
58	///fn main(){
59	///    let mut game = GameOfLife::new(25, 45);
60	///    game.unset_element(5,5);
61	///}
62	///```
63	pub fn unset_element(&mut self, i_col:usize, i_lig:usize){
64		self.grid[i_lig][i_col] = false;
65	}
66	///Function to show the actual state of the game.\
67	///For exemple :\
68	///```rust
69	///fn main(){
70	///    let mut game = GameOfLife::new(25, 45);
71	///    game.show();
72	///}
73	///```
74	pub fn show(&self){
75		for i in 0..self.nb_lig{
76			for j in 0..self.nb_col{
77				if self.grid[i as usize][j as usize] {
78					show('#', j, i);
79				}else{
80					show(' ', j, i);
81				}
82			}
83		}
84	}
85	///Function which update the game (e.g. pass to the next state)\
86	///For exemple :\
87	///```rust
88	///fn main(){
89	///    let mut game = GameOfLife::new(25, 45);
90	///    game.update();
91	///}
92	///```
93	pub fn update(&mut self){
94		let nb_col:usize = self.nb_col;
95		let nb_lig:usize = self.nb_lig;
96
97		//Init the future value of the grid
98		let mut new_grid:Vec<Vec<bool>> = Vec::with_capacity(nb_lig);
99		for i in 0..nb_lig{
100			new_grid.push(Vec::with_capacity(nb_col));
101			for _ in 0..nb_col {
102				new_grid[i].push(false);
103			}
104		}
105
106		//Compute
107		for ilig in 1..nb_lig-1{
108			for icol in 1..nb_col-1{
109				let mut nb_vies = 0;
110				for i in 0..3{
111					for j in 0..3{
112						if !(i==1 && j==1) && self.grid[(ilig+j-1) as usize][(icol+i-1) as usize] {
113							nb_vies+=1;
114						}
115					}
116				}
117				if nb_vies == 3 || (nb_vies == 2 && self.grid[ilig as usize][icol as usize]) {
118					new_grid[ilig as usize][icol as usize] = true;
119				}
120			}
121		}
122
123		//Copy the future value of the grid onto the grid
124		for ilig in 1..nb_lig-1{
125			for icol in 1..nb_col-1{
126				self.grid[ilig as usize][icol as usize] = new_grid[ilig as usize][icol as usize];
127			}
128		}
129	}
130	///Funtion to get the grid of the automata
131	pub fn get_grid(&self) -> &Vec<Vec<bool>> {
132		&self.grid
133	}
134}