diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..c813079 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,26 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug executable 'mill_game'", + "cargo": { + "args": [ + "build", + "--bin=mill_game", + "--package=mill_game" + ], + "filter": { + "name": "mill_game", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/src/board.rs b/src/board.rs index 07a56d6..d4f7896 100644 --- a/src/board.rs +++ b/src/board.rs @@ -14,7 +14,7 @@ pub struct BoardSlot { pub y: usize, pub z: usize, - pub state: Mutex, + state: Mutex, pub position: Vector2, pub slot_marker: Option, } @@ -100,10 +100,22 @@ impl BoardSlot { Ok(mesh) } + pub fn state(&self) -> BoardSlotState { + *self.state.lock().unwrap() + } + + pub fn set_state(&self, state: BoardSlotState) { + *self.state.lock().unwrap() = state; + } + pub fn valid(&self) -> bool { *self.state.lock().unwrap() != BoardSlotState::Invalid } + pub fn is_empty(&self) -> bool { + *self.state.lock().unwrap() == BoardSlotState::Empty + } + pub fn white(&self) -> bool { match *self.state.lock().unwrap() { BoardSlotState::White(_) => true, @@ -290,6 +302,75 @@ impl Board { None } + + pub fn get_neighbours<'a>( + slot: &BoardSlot, + board: &'a [[[BoardSlot; 3]; 3]; 3], + ) -> Vec<&'a BoardSlot> { + let mut neighbours = Vec::new(); + + for i in 0..6 { + // find free neighbour field + if let Some(neighbour) = match i { + 0 => { + if slot.x > 0 { + Some(&board[slot.x - 1][slot.y][slot.z]) + } else { + None + } + } + 1 => { + if slot.x < 2 { + Some(&board[slot.x + 1][slot.y][slot.z]) + } else { + None + } + } + 2 => { + if slot.y > 0 { + Some(&board[slot.x][slot.y - 1][slot.z]) + } else { + None + } + } + 3 => { + if slot.y < 2 { + Some(&board[slot.x][slot.y + 1][slot.z]) + } else { + None + } + } + 4 => { + if slot.z > 0 { + Some(&board[slot.x][slot.y][slot.z - 1]) + } else { + None + } + } + 5 => { + if slot.z < 2 { + Some(&board[slot.x][slot.y][slot.z + 1]) + } else { + None + } + } + + _ => unreachable!(), + } { + let neighbour_state = neighbour.state.lock().unwrap(); + + match *neighbour_state { + BoardSlotState::Empty => { + neighbours.push(neighbour); + } + + _ => (), + } + } + } + + neighbours + } } impl Board { diff --git a/src/game.rs b/src/game.rs index a846979..86475e7 100644 --- a/src/game.rs +++ b/src/game.rs @@ -27,6 +27,7 @@ pub struct Stone { #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] pub enum GameState { + Waiting, Placing, Removing, Main, @@ -60,6 +61,13 @@ impl PlayerColor { } } } + + pub fn other(&self) -> Self { + match self { + PlayerColor::White => PlayerColor::Black, + PlayerColor::Black => PlayerColor::White, + } + } } pub struct MillGame { @@ -78,6 +86,8 @@ pub struct MillGame { turn_finished: AtomicBool, + selected_field: Mutex>, + simple_ai: SimpleAI, white_player_label: Arc