diff --git a/src/game.rs b/src/game.rs index 4ca663a..903fe7d 100644 --- a/src/game.rs +++ b/src/game.rs @@ -407,14 +407,12 @@ impl MillGame { *self.last_turn_timing.lock().unwrap() = self.engine.time(); self.turn_finished.store(true, SeqCst); + *self.selected_field.lock().unwrap() = None; } fn print_game_state(&self, severity: LogSeverity, log_state: bool) -> Result<()> { let current_turn_state = TurnState::new(self)?; - // verity that last turn actually something happened - debug_assert!(!current_turn_state.is_empty()); - if log_state { current_turn_state.log(severity); } @@ -424,6 +422,10 @@ impl MillGame { if !turn_states.is_empty() { let (new_diff, old_diff) = current_turn_state.diff(turn_states.last().unwrap()); + // verity that last turn actually something happened + debug_assert!(!new_diff.is_empty()); + debug_assert!(!old_diff.is_empty()); + Self::log(" ===== OLD DIFF =====", severity); old_diff.log(severity); Self::log(" ===== NEW DIFF =====", severity); @@ -520,14 +522,14 @@ impl MillGame { if player == self.simple_ai.player_color { Self::log("current player is AI", LogSeverity::Debug); - if !self.simple_ai.step( + self.simple_ai.step( &mut self.stones(self.simple_ai.player_color), self.board.lock().unwrap().slots(), &mut *self.scene.lock().unwrap(), &mut *self.state.lock().unwrap(), - )? { - self.finish_turn(); - } + )?; + + self.finish_turn(); } Self::log("leave next_game_step", LogSeverity::Debug); @@ -875,7 +877,7 @@ impl MillGame { pub fn log(s: &str, log_severity: LogSeverity) { match (LOG_SEVERITY, log_severity) { (LogSeverity::Basic, LogSeverity::Basic) => Self::write(s), - (LogSeverity::Basic, LogSeverity::Debug) => (), + (LogSeverity::Basic, LogSeverity::Debug) => Self::write_extra(s), (LogSeverity::Debug, LogSeverity::Basic) => Self::write(s), (LogSeverity::Debug, LogSeverity::Debug) => Self::write(s), } @@ -886,6 +888,16 @@ impl MillGame { if let Err(_) = file.write_all(format!("{}\n", s.to_string()).as_bytes()) {} } } + + fn write_extra(s: &str) { + if let Ok(mut file) = OpenOptions::new() + .append(true) + .create(true) + .open("millgame_extra.log") + { + if let Err(_) = file.write_all(format!("{}\n", s.to_string()).as_bytes()) {} + } + } } impl EngineObject for MillGame { @@ -1015,6 +1027,8 @@ impl EngineObject for MillGame { = Self::move_stone((x,y,z), (tx,ty,tz), scene, board, &mut state)? { if let MillState::None = millstate { *selected_slot = None; + drop(selected_slot); + self.finish_turn(); } } diff --git a/src/simple_ai.rs b/src/simple_ai.rs index 12aee9c..cdd84a7 100644 --- a/src/simple_ai.rs +++ b/src/simple_ai.rs @@ -21,7 +21,7 @@ impl SimpleAI { board: &mut [[[BoardSlot; 3]; 3]; 3], scene: &mut SceneHandle, state: &mut GameState, - ) -> Result { + ) -> Result<()> { MillGame::log(&format!("AI at state {:?}", *state), LogSeverity::Debug); let mut found_a_mill = false; @@ -93,6 +93,8 @@ impl SimpleAI { }) .unwrap(); + MillGame::log("[AI] remove stone", LogSeverity::Debug); + scene.on_scene(|scene| { MillGame::remove_stone(stone, slot, scene)?; @@ -100,35 +102,39 @@ impl SimpleAI { })?; } GameState::Main => { - let same_color: Vec<&BoardSlot> = board - .iter() - .flatten() - .flatten() - .filter(|slot| match (slot.state(), self.player_color) { - (BoardSlotState::White(_), PlayerColor::White) => true, - (BoardSlotState::Black(_), PlayerColor::Black) => true, - _ => false, - }) - .collect(); + scene.on_scene(|scene| { + loop { + let same_color: Vec<&BoardSlot> = board + .iter() + .flatten() + .flatten() + .filter(|slot| match (slot.state(), self.player_color) { + (BoardSlotState::White(_), PlayerColor::White) => true, + (BoardSlotState::Black(_), PlayerColor::Black) => true, + _ => false, + }) + .collect(); - loop { - let len = same_color.len(); - let slot = &same_color[Random::range(0, len as u32) as usize]; - let n = Board::get_neighbours(slot, board); - let neighbours: Vec<&&BoardSlot> = n - .iter() - .filter(|n| n.state() == BoardSlotState::Empty) - .collect(); + let len = same_color.len(); + let slot = &same_color[Random::range(0, len as u32) as usize]; + let n = Board::get_neighbours(slot, board); + let neighbours: Vec<&&BoardSlot> = n + .iter() + .filter(|n| n.state() == BoardSlotState::Empty) + .collect(); - if !neighbours.is_empty() { - let neighbour = - &neighbours[Random::range(0, neighbours.len() as u32) as usize]; + if !neighbours.is_empty() { + let neighbour = + &neighbours[Random::range(0, neighbours.len() as u32) as usize]; - if neighbour.state() == BoardSlotState::Empty { - let (x, y, z) = (slot.x, slot.y, slot.z); - let (tx, ty, tz) = (neighbour.x, neighbour.y, neighbour.z); + if neighbour.state() == BoardSlotState::Empty { + let (x, y, z) = (slot.x, slot.y, slot.z); + let (tx, ty, tz) = (neighbour.x, neighbour.y, neighbour.z); + + let mut successful_move = false; + + MillGame::log("[AI] going to make a move", LogSeverity::Debug); - scene.on_scene(|scene| { if let Some(millstate) = MillGame::move_stone( (x, y, z), (tx, ty, tz), @@ -136,24 +142,38 @@ impl SimpleAI { board, state, )? { + MillGame::log("[AI] successful move", LogSeverity::Debug); + if MillState::None != millstate { + MillGame::log("[AI] found a mill", LogSeverity::Debug); + found_a_mill = true; } + + successful_move = true; + } else { + MillGame::log("[AI] move failed", LogSeverity::Debug); } - Ok(()) - })?; - - break; + if successful_move { + break; + } + } } } - } + + Ok(()) + })?; } GameState::Waiting => unreachable!(), } + if found_a_mill { + self.step(stones, board, scene, state)?; + } + MillGame::log("finish AI", LogSeverity::Debug); - Ok(found_a_mill) + Ok(()) } }