// Provided by: Claude-3-Sonnet (2024)

use std::thread::sleep;
use std::time::Duration;

#[derive(Clone, Copy, PartialEq)]
struct Cellule {
    etat: u8, // 0 pour vide, 1 pour colonie
}

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));
    }
}