diff --git a/src/board.rs b/src/board.rs index 884b39e..07a56d6 100644 --- a/src/board.rs +++ b/src/board.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use anyhow::Result; use engine::prelude::{ @@ -8,13 +8,13 @@ use engine::prelude::{ use crate::{game::MillGame, objects::Objects}; -#[derive(Debug, PartialEq, Clone, Copy)] +#[derive(Debug)] pub struct BoardSlot { pub x: usize, pub y: usize, pub z: usize, - pub state: BoardSlotState, + pub state: Mutex, pub position: Vector2, pub slot_marker: Option, } @@ -45,7 +45,7 @@ impl BoardSlot { y, z, - state: BoardSlotState::default(), + state: Mutex::new(BoardSlotState::default()), position, slot_marker: Some(scene.add_entity(marker)?), }) @@ -57,7 +57,7 @@ impl BoardSlot { y, z, - state: BoardSlotState::Invalid, + state: Mutex::new(BoardSlotState::Invalid), position: vec2(0.0, 0.0), slot_marker: None, } @@ -101,18 +101,18 @@ impl BoardSlot { } pub fn valid(&self) -> bool { - self.state != BoardSlotState::Invalid + *self.state.lock().unwrap() != BoardSlotState::Invalid } pub fn white(&self) -> bool { - match self.state { + match *self.state.lock().unwrap() { BoardSlotState::White(_) => true, _ => false, } } pub fn black(&self) -> bool { - match self.state { + match *self.state.lock().unwrap() { BoardSlotState::Black(_) => true, _ => false, } @@ -279,7 +279,7 @@ impl Board { for outer in self.slots.iter_mut() { for inner in outer.iter_mut() { for slot in inner.iter_mut() { - if slot.state != BoardSlotState::Invalid { + if *slot.state.lock().unwrap() != BoardSlotState::Invalid { if (slot.position - position).magnitude() <= DISTANCE { return Some(slot); } diff --git a/src/game.rs b/src/game.rs index a001139..a846979 100644 --- a/src/game.rs +++ b/src/game.rs @@ -404,12 +404,12 @@ impl MillGame { PlayerColor::White => { Self::log(&format!("place white stone")); - slot.state = BoardSlotState::White(stone.stone); + *slot.state.lock().unwrap() = BoardSlotState::White(stone.stone); } PlayerColor::Black => { Self::log(&format!("place black stone")); - slot.state = BoardSlotState::Black(stone.stone); + *slot.state.lock().unwrap() = BoardSlotState::Black(stone.stone); } } @@ -426,7 +426,7 @@ impl MillGame { pub fn remove_stone(slot: &mut BoardSlot, scene: &mut Scene) -> Result<()> { Self::log("remove_stone"); - let entity = match slot.state { + let entity = match *slot.state.lock().unwrap() { BoardSlotState::Black(e) => { Self::log(&format!("\tremove black stone")); @@ -441,8 +441,9 @@ impl MillGame { }; scene.remove_entity(entity)?; + Self::log("\t -> TODO: set stone state to Dead"); - slot.state = BoardSlotState::Empty; + *slot.state.lock().unwrap() = BoardSlotState::Empty; Ok(()) } @@ -613,7 +614,10 @@ impl EngineObject for MillGame { *self.current_player.lock().unwrap() )); - if match (slot.state, *self.current_player.lock().unwrap()) { + if match ( + *slot.state.lock().unwrap(), + *self.current_player.lock().unwrap(), + ) { (BoardSlotState::Black(_), PlayerColor::White) => true, (BoardSlotState::White(_), PlayerColor::Black) => true, _ => false, diff --git a/src/simple_ai.rs b/src/simple_ai.rs index b2e9935..5abd32d 100644 --- a/src/simple_ai.rs +++ b/src/simple_ai.rs @@ -34,7 +34,7 @@ impl SimpleAI { .iter_mut() .flatten() .flatten() - .filter(|slot| slot.state == BoardSlotState::Empty) + .filter(|slot| *slot.state.lock().unwrap() == BoardSlotState::Empty) .collect(); let len = free_slots.len(); @@ -53,11 +53,13 @@ impl SimpleAI { .iter_mut() .flatten() .flatten() - .filter(|slot| match (slot.state, self.player_color) { - (BoardSlotState::Black(_), PlayerColor::White) => true, - (BoardSlotState::White(_), PlayerColor::Black) => true, - _ => false, - }) + .filter( + |slot| match (*slot.state.lock().unwrap(), self.player_color) { + (BoardSlotState::Black(_), PlayerColor::White) => true, + (BoardSlotState::White(_), PlayerColor::Black) => true, + _ => false, + }, + ) .collect(); let len = other_color.len(); @@ -70,7 +72,92 @@ impl SimpleAI { Ok(()) })?; } - GameState::Main => todo!(), + GameState::Main => { + let mut same_color: Vec<&BoardSlot> = board + .iter() + .flatten() + .flatten() + .filter( + |slot| match (*slot.state.lock().unwrap(), self.player_color) { + (BoardSlotState::White(_), PlayerColor::White) => true, + (BoardSlotState::Black(_), PlayerColor::Black) => true, + _ => false, + }, + ) + .collect(); + + loop { + let len = same_color.len(); + let slot = &mut same_color[Random::range(0, len as u32) as usize]; + + // find free neighbour field + if let Some(neighbour) = match Random::range(0, 6) as usize { + 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 + } + } + // 6 => , + // 7 => , + // 8 => , + // 9 => , + _ => unreachable!(), + } { + let mut neighbour_state = neighbour.state.lock().unwrap(); + let mut slot_state = slot.state.lock().unwrap(); + + match (*neighbour_state, *slot_state) { + (BoardSlotState::Empty, BoardSlotState::Black(e)) => { + *neighbour_state = BoardSlotState::Black(e); + *slot_state = BoardSlotState::Empty; + } + (BoardSlotState::Empty, BoardSlotState::White(e)) => { + *neighbour_state = BoardSlotState::White(e); + *slot_state = BoardSlotState::Empty; + } + + _ => (), + } + } + } + } } MillGame::log("finish AI");