#[derive(Clone, Copy, PartialEq)] pub struct Cell(u8); pub const CELL_EMPTY: Cell = Cell(0); pub const CELL_X: Cell = Cell(1); pub const CELL_O: Cell = Cell(2); impl std::fmt::Display for Cell { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { let mut s: &str = " "; if *self == CELL_X { s = "X"; } else if *self == CELL_O { s = "O"; } write!(f, "{}", s) } } pub struct Move { pub x: usize, pub y: usize, pub c: Cell, } pub struct Board { cells: Vec, next: Cell, } impl Board { pub fn new() -> Board { return Board { cells: vec![CELL_EMPTY; 9], next: CELL_X, }; } pub fn reset(&mut self) { self.cells = vec![CELL_EMPTY; 9]; self.next = CELL_X; } pub fn put(&mut self, m: Move) -> bool { let i = m.x * 1 + m.y * 3; if self.cells[i] != CELL_EMPTY { return false; } self.cells[i] = m.c; return true; } pub fn has_winner(&self) -> Cell { // rows and cols for i in 0..3 { if self.cells[i] == self.cells[i + 3] && self.cells[i] == self.cells[i + 6] { return self.cells[i]; } else if self.cells[i * 3] == self.cells[i * 3 + 1] && self.cells[i * 3] == self.cells[i * 3 + 2] { return self.cells[i * 3]; } } // diagonals if self.cells[0] == self.cells[4] && self.cells[0] == self.cells[8] { return self.cells[0]; } if self.cells[2] == self.cells[4] && self.cells[2] == self.cells[6] { return self.cells[2]; } // no winner return CELL_EMPTY; } } impl std::fmt::Display for Board { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { let mut s = String::new(); s.push_str("┌─┬─┬─┐\n"); for i in 0..3 { s.push_str(&format!( "│{}│{}│{}│\n", self.cells[i * 3], self.cells[i * 3 + 1], self.cells[i * 3 + 2] )); if i < 2 { s.push_str("├─┼─┼─┤\n"); } } s.push_str("└─┴─┴─┘\n"); let w = self.has_winner(); if w != CELL_EMPTY { s.push_str(&format!("The winner is {w}")); } else { s.push_str(&format!("Next: {}", self.next)); } write!(f, "{s}") } }