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}