Skip to main content

PieceState Alive


extern crate rand;

use rand::prelude::*;

const locations: [[i32; 2]; 8] = [
    [-1, -1],
    [0, -1],
    [1, -1],
    [1, 0],
    [1, 1],
    [0, 1],
    [-1, 1],
    [-1, -1],
];

#[derive(Clone)]
enum PieceState {
    Alive,
    Dead,
}

struct Piece {
    state: PieceState,
    change_to: PieceState,
}

impl Piece {
    fn update_state(&mut self) {
        self.state = self.change_to.clone();
    }

    fn randomize(&mut self) {
        self.state = if random() {
            PieceState::Alive
        } else {
            PieceState::Dead
        };
    }
}

struct Board {
    pieces: Vec<Vec<Piece>>,
}

impl Board {
    fn draw(&mut self) {
        for row in &self.pieces {
            let mut row_string = String::new();
            for piece in row {
                row_string += &String::from(match piece.state {
                    PieceState::Alive => "#",
                    PieceState::Dead => " ",
                })
            }
            println!("{}", row_string);
        }
    }

    fn init(&mut self, size: usize) {
        self.pieces = vec![];
        for y in 0..size {
            self.pieces.push(vec![]);
            for _ in 0..size {
                let p = Piece {
                    state: PieceState::Dead,
                    change_to: PieceState::Dead,
                };
                self.pieces[y].push(p);
            }
        }
    }

    fn randomize(&mut self) {
        for row in &mut self.pieces {
            for piece in row {
                piece.randomize();
            }
        }
    }

    fn update_pieces(&mut self) {
        for row in &mut self.pieces {
            for mut piece in row {
                piece.update_state();
            }
        }
    }

    fn run_cycle(&mut self) {
        for (y, row) in &mut self.pieces.iter().enumerate() {
            for (x, mut piece) in row.iter().enumerate() {
                let mut total = 0;
                for check in locations.iter() {
                    let yloc: i32 = (y as i32) + check[1] as i32;
                    let xloc: i32 = (x as i32) + check[0] as i32;
                    if yloc < 0 || xloc < 0 {
                        continue;
                    }
                    let max_index = row.len() as i32 - 1;
                    if yloc > max_index || xloc > max_index {
                        continue;
                    }
                    total += match self.pieces[yloc as usize][xloc as usize].state {
                        PieceState::Alive => 1,
                        PieceState::Dead => 0,
                    }
                }
                piece.change_to = match piece.state {
                    PieceState::Alive => {
                        if total < 2 {
                            PieceState::Dead
                        } else if total <= 3 {
                            PieceState::Alive
                        } else if total > 3 {
                            PieceState::Dead
                        } else {
                            PieceState::Dead
                        }
                    }
                    PieceState::Dead => {
                        if total == 3 {
                            PieceState::Alive
                        } else {
                            PieceState::Dead
                        }
                    }
                };
            }
        }
    }
}

fn main() {
    let mut b = Board { pieces: vec![] };
    b.init(10);
    b.randomize();
    b.draw();
    loop {
        b.run_cycle();
        b.draw();
    }
}