use std::thread::sleep;
use std::time::Duration;
#[derive(Clone, Copy, PartialEq)]
struct Cellule {
etat: u8,
}
struct Grille {
cellules: Vec<Vec<Cellule>>,
largeur: usize,
hauteur: usize,
}
struct Fourmi {
x: usize,
y: usize,
direction: Direction,
}
#[derive(Clone, Copy, PartialEq)]
enum Direction {
Haut,
Droite,
Bas,
Gauche,
}
impl Grille {
fn nouvelle(largeur: usize, hauteur: usize) -> Grille {
let mut cellules = Vec::with_capacity(hauteur);
for _ in 0..hauteur {
let mut ligne = Vec::with_capacity(largeur);
for _ in 0..largeur {
ligne.push(Cellule { etat: 0 });
}
cellules.push(ligne);
}
let x = largeur / 2;
let y = hauteur / 2;
cellules[y][x] = Cellule { etat: 1 };
Grille {
cellules,
largeur,
hauteur,
}
}
fn afficher(&self) {
for ligne in &self.cellules {
for cellule in ligne {
let caractere = if cellule.etat == 0 { '.' } else { '#' };
print!("{}", caractere);
}
println!();
}
}
fn deplacer_fourmi(&mut self, fourmi: &mut Fourmi) {
let (x, y) = (fourmi.x, fourmi.y);
let cellule = &mut self.cellules[y][x];
match cellule.etat {
0 => {
cellule.etat = 1;
fourmi.direction = match fourmi.direction {
Direction::Haut => Direction::Droite,
Direction::Droite => Direction::Bas,
Direction::Bas => Direction::Gauche,
Direction::Gauche => Direction::Haut,
};
}
1 => {
cellule.etat = 0;
fourmi.direction = match fourmi.direction {
Direction::Haut => Direction::Gauche,
Direction::Droite => Direction::Haut,
Direction::Bas => Direction::Droite,
Direction::Gauche => Direction::Bas,
};
}
_ => unreachable!(),
}
match fourmi.direction {
Direction::Haut => fourmi.y = fourmi.y.wrapping_sub(1) % self.hauteur,
Direction::Droite => fourmi.x = (fourmi.x + 1) % self.largeur,
Direction::Bas => fourmi.y = (fourmi.y + 1) % self.hauteur,
Direction::Gauche => fourmi.x = fourmi.x.wrapping_sub(1) % self.largeur,
}
}
}
fn main() {
let mut grille = Grille::nouvelle(12, 12);
let mut fourmi = Fourmi {
x: grille.largeur / 2,
y: grille.hauteur / 2,
direction: Direction::Haut,
};
for _ in 0..20 {
grille.deplacer_fourmi(&mut fourmi);
grille.afficher();
println!();
sleep(Duration::from_secs(1));
}
}