use rand::Rng; const COLUMNS: usize = 4; const ROWS: usize = 4; pub enum Directions { Down, Up, Right, Left, } pub struct TaquinGame { empty_coord: [usize; 2], grid: [[u8; COLUMNS]; ROWS], rng: rand::rngs::ThreadRng, score: usize, high_score: usize, } impl TaquinGame { pub fn new() -> Self { return TaquinGame { empty_coord: [COLUMNS - 1, ROWS - 1], grid: [[0; COLUMNS]; ROWS], rng: rand::rng(), score: 0, high_score: 0, }; } pub fn score(&self) -> usize { return self.score; } pub fn grid(&self) -> [[u8; COLUMNS]; ROWS] { return self.grid; } pub fn high_score(&self) -> usize { return self.high_score; } pub fn move_to(&mut self, direction: Directions) -> bool { let (mut row, mut column) = (self.empty_coord[0], self.empty_coord[1]); let mut valid_direction = false; match direction { Directions::Up => { if row + 1 < ROWS { row += 1; valid_direction = true; } } Directions::Down => { if row > 0 { row -= 1; valid_direction = true; } } Directions::Left => { if column + 1 < COLUMNS { column += 1; valid_direction = true; } } Directions::Right => { if column > 0 { column -= 1; valid_direction = true; } } } if valid_direction { self.exchange(self.empty_coord[1], self.empty_coord[0], column, row); self.score += 1; } return valid_direction; } pub fn is_grid_done(&mut self) -> bool { let mut error_found = false; let mut value = 1; for i in 0..ROWS { if !error_found { for j in 0..COLUMNS { if !error_found { if self.grid[i][j] != value { error_found = true; } value += 1; } else { break; } } } else { break; } } if !error_found { if self.score > 0 && (self.high_score == 0 || self.score > self.high_score) { self.high_score = self.score; } } return error_found; } pub fn init_grid(&mut self) { let move_nmbr = self.rng.random_range(400..500); let mut rnd_nmbr = [0u8, 0, 0, 0]; self.resolve(); for _ in 0..move_nmbr { loop { rnd_nmbr[3] = self.rng.random_range(0..4); if rnd_nmbr[0] != rnd_nmbr[3] { break; } } rnd_nmbr = [rnd_nmbr[1], rnd_nmbr[2], rnd_nmbr[3], rnd_nmbr[3]]; self.move_to(match rnd_nmbr[3] { 0 => Directions::Up, 1 => Directions::Down, 2 => Directions::Left, 3 => Directions::Right, _ => Directions::Up, }); } self.score = 0; } fn exchange(&mut self, ax: usize, ay: usize, bx: usize, by: usize) {} pub fn resolve(&mut self) { let mut value = 1; self.score = 0; self.empty_coord = [ROWS - 1, COLUMNS - 1]; for i in 0..ROWS { for j in 0..COLUMNS { self.grid[i][j] = value; value += 1; } } } }