Add log severity flag

This commit is contained in:
hodasemi 2023-05-11 17:00:42 +02:00
parent a83c3a4ab6
commit 27eb709c02
2 changed files with 151 additions and 82 deletions

View file

@ -1,6 +1,9 @@
use std::sync::{ use std::{
sync::{
atomic::{AtomicBool, AtomicU32, Ordering::SeqCst}, atomic::{AtomicBool, AtomicU32, Ordering::SeqCst},
Arc, Mutex, MutexGuard, Arc, Mutex, MutexGuard,
},
time::Duration,
}; };
use anyhow::Result; use anyhow::Result;
@ -46,16 +49,23 @@ pub enum MillState {
None, None,
} }
pub enum LogSeverity {
Basic,
Debug,
}
const LOG_SEVERITY: LogSeverity = LogSeverity::Basic;
impl PlayerColor { impl PlayerColor {
pub fn swap(&mut self) { pub fn swap(&mut self) {
*self = match *self { *self = match *self {
PlayerColor::White => { PlayerColor::White => {
MillGame::log("swapped to black player"); MillGame::log("swapped to black player", LogSeverity::Debug);
PlayerColor::Black PlayerColor::Black
} }
PlayerColor::Black => { PlayerColor::Black => {
MillGame::log("swapped to white player"); MillGame::log("swapped to white player", LogSeverity::Debug);
PlayerColor::White PlayerColor::White
} }
@ -71,6 +81,9 @@ impl PlayerColor {
} }
pub struct MillGame { pub struct MillGame {
engine: Arc<Engine>,
last_turn_timing: Mutex<Duration>,
board: Arc<Mutex<Board>>, board: Arc<Mutex<Board>>,
white_stones: Mutex<[Stone; 9]>, white_stones: Mutex<[Stone; 9]>,
black_stones: Mutex<[Stone; 9]>, black_stones: Mutex<[Stone; 9]>,
@ -100,6 +113,7 @@ pub struct MillGame {
impl MillGame { impl MillGame {
pub const OFFSET_TO_BOARD: f32 = 0.02; pub const OFFSET_TO_BOARD: f32 = 0.02;
pub const TURN_WAIT_TIME: Duration = Duration::from_millis(500);
pub fn new(engine: Arc<Engine>) -> Result<Arc<Self>> { pub fn new(engine: Arc<Engine>) -> Result<Arc<Self>> {
let mut scene = SceneHandle::new(&engine)?; let mut scene = SceneHandle::new(&engine)?;
@ -191,6 +205,9 @@ impl MillGame {
gui.enable()?; gui.enable()?;
let me = Arc::new(Self { let me = Arc::new(Self {
engine: engine.clone(),
last_turn_timing: Mutex::default(),
board: Arc::new(Mutex::new(board)), board: Arc::new(Mutex::new(board)),
white_stones: Mutex::new(white_stones.unwrap()), white_stones: Mutex::new(white_stones.unwrap()),
black_stones: Mutex::new(black_stones.unwrap()), black_stones: Mutex::new(black_stones.unwrap()),
@ -228,12 +245,13 @@ impl MillGame {
} }
if let Some(me) = weak_self.upgrade() { if let Some(me) = weak_self.upgrade() {
Self::log("start game"); Self::log("start game", LogSeverity::Debug);
*me.state.lock().unwrap() = GameState::Placing; *me.state.lock().unwrap() = GameState::Placing;
*me.current_player.lock().unwrap() = PlayerColor::Black; *me.current_player.lock().unwrap() = PlayerColor::Black;
me.turn_finished.store(true, SeqCst); me.finish_turn();
*me.last_turn_timing.lock().unwrap() = me.engine.time();
} }
Ok(()) Ok(())
@ -244,11 +262,12 @@ impl MillGame {
} }
pub fn finish_turn(&self) { pub fn finish_turn(&self) {
Self::log(&format!( Self::log(
"{:?} finished turn", &format!("{:?} finished turn", *self.current_player.lock().unwrap()),
*self.current_player.lock().unwrap() LogSeverity::Debug,
)); );
*self.last_turn_timing.lock().unwrap() = self.engine.time();
self.turn_finished.store(true, SeqCst); self.turn_finished.store(true, SeqCst);
} }
@ -256,7 +275,10 @@ impl MillGame {
{ {
let mut state = self.state.lock().unwrap(); let mut state = self.state.lock().unwrap();
Self::log(&format!(" ===== NEW TURN ({:?}) =====", state)); Self::log(
&format!(" ===== NEW TURN ({:?}) =====", state),
LogSeverity::Basic,
);
match *state { match *state {
GameState::Placing => { GameState::Placing => {
@ -273,7 +295,7 @@ impl MillGame {
.iter() .iter()
.any(|stones| stones.state == StoneState::ReadyToBePlaced) .any(|stones| stones.state == StoneState::ReadyToBePlaced)
{ {
Self::log("change state to Main"); Self::log("change state to Main", LogSeverity::Debug);
*state = GameState::Main; *state = GameState::Main;
} }
@ -293,10 +315,10 @@ impl MillGame {
.iter() .iter()
.any(|stones| stones.state == StoneState::ReadyToBePlaced) .any(|stones| stones.state == StoneState::ReadyToBePlaced)
{ {
Self::log("change state to Main"); Self::log("change state to Main", LogSeverity::Debug);
*state = GameState::Main; *state = GameState::Main;
} else { } else {
Self::log("change state to Placing"); Self::log("change state to Placing", LogSeverity::Debug);
*state = GameState::Placing; *state = GameState::Placing;
} }
@ -311,7 +333,7 @@ impl MillGame {
let player = *self.current_player.lock().unwrap(); let player = *self.current_player.lock().unwrap();
Self::log(&format!("current player {:?}", player)); Self::log(&format!("current player {:?}", player), LogSeverity::Debug);
match player { match player {
PlayerColor::White => { PlayerColor::White => {
@ -327,7 +349,7 @@ impl MillGame {
} }
if player == self.simple_ai.player_color { if player == self.simple_ai.player_color {
Self::log("current player is AI"); Self::log("current player is AI", LogSeverity::Debug);
if !self.simple_ai.step( if !self.simple_ai.step(
&mut self.stones(self.simple_ai.player_color), &mut self.stones(self.simple_ai.player_color),
@ -339,7 +361,7 @@ impl MillGame {
} }
} }
Self::log("leave next_game_step"); Self::log("leave next_game_step", LogSeverity::Debug);
Ok(()) Ok(())
} }
@ -411,18 +433,24 @@ impl MillGame {
scene: &mut Scene, scene: &mut Scene,
state: &mut GameState, state: &mut GameState,
) -> Result<MillState> { ) -> Result<MillState> {
Self::log("place_stone"); Self::log("place_stone", LogSeverity::Debug);
let slot = &board[x][y][z]; let slot = &board[x][y][z];
match player_color { match player_color {
PlayerColor::White => { PlayerColor::White => {
Self::log(&format!("place white stone")); Self::log(
&format!(" ==> white stone placed at {:?}", (x, y, z)),
LogSeverity::Basic,
);
slot.set_state(BoardSlotState::White(stone.stone)); slot.set_state(BoardSlotState::White(stone.stone));
} }
PlayerColor::Black => { PlayerColor::Black => {
Self::log(&format!("place black stone")); Self::log(
&format!(" ==> black stone placed at {:?}", (x, y, z)),
LogSeverity::Basic,
);
slot.set_state(BoardSlotState::Black(stone.stone)); slot.set_state(BoardSlotState::Black(stone.stone));
} }
@ -441,7 +469,10 @@ impl MillGame {
*state = GameState::Removing; *state = GameState::Removing;
} }
Self::log(&format!("return place stone with {:?}", millstate)); Self::log(
&format!("return place stone with {:?}", millstate),
LogSeverity::Debug,
);
Ok(millstate) Ok(millstate)
} }
@ -453,17 +484,16 @@ impl MillGame {
board: &mut [[[BoardSlot; 3]; 3]; 3], board: &mut [[[BoardSlot; 3]; 3]; 3],
state: &mut GameState, state: &mut GameState,
) -> Result<MillState> { ) -> Result<MillState> {
Self::log(&format!( Self::log(
"move stone ({:?}) to ({:?})", &format!("move stone ({:?}) to ({:?})", (x, y, z), (tx, ty, tz)),
(x, y, z), LogSeverity::Debug,
(tx, ty, tz) );
));
let slot = &board[x][y][z]; let slot = &board[x][y][z];
let neighbour = &board[tx][ty][tz]; let neighbour = &board[tx][ty][tz];
if neighbour.state() != BoardSlotState::Empty { if neighbour.state() != BoardSlotState::Empty {
Self::log("neighbour not empty"); Self::log("neighbour not empty", LogSeverity::Debug);
return Ok(MillState::None); return Ok(MillState::None);
} }
@ -472,8 +502,30 @@ impl MillGame {
scene scene
.entity_mut(match neighbour.state() { .entity_mut(match neighbour.state() {
BoardSlotState::Black(e) => e, BoardSlotState::Black(e) => {
BoardSlotState::White(e) => e, Self::log(
&format!(
" ==> black stone moved from {:?} to {:?}",
(x, y, z),
(tx, ty, tz)
),
LogSeverity::Basic,
);
e
}
BoardSlotState::White(e) => {
Self::log(
&format!(
" ==> white stone moved from {:?} to {:?}",
(x, y, z),
(tx, ty, tz)
),
LogSeverity::Basic,
);
e
}
_ => unreachable!(), _ => unreachable!(),
})? })?
@ -483,26 +535,41 @@ impl MillGame {
let millstate = Self::check_for_mill(&board[tx][ty][tz], board); let millstate = Self::check_for_mill(&board[tx][ty][tz], board);
if millstate != MillState::None { if millstate != MillState::None {
Self::log("mill found!"); Self::log("mill found!", LogSeverity::Debug);
*state = GameState::Removing; *state = GameState::Removing;
} }
Self::log(&format!("return move stone with {:?}", millstate)); Self::log(
&format!("return move stone with {:?}", millstate),
LogSeverity::Debug,
);
Ok(millstate) Ok(millstate)
} }
pub fn remove_stone(stone: &mut Stone, slot: &mut BoardSlot, scene: &mut Scene) -> Result<()> { pub fn remove_stone(stone: &mut Stone, slot: &mut BoardSlot, scene: &mut Scene) -> Result<()> {
Self::log("remove_stone"); Self::log("remove_stone", LogSeverity::Debug);
let entity = match slot.state() { let entity = match slot.state() {
BoardSlotState::Black(e) => { BoardSlotState::Black(e) => {
Self::log(&format!("\tremove black stone")); Self::log(
&format!(
" ==> white player removes black stone at {:?}",
(slot.x, slot.y, slot.z)
),
LogSeverity::Basic,
);
e e
} }
BoardSlotState::White(e) => { BoardSlotState::White(e) => {
Self::log(&format!("\tremove white stone")); Self::log(
&format!(
" ==> black player removes white stone at {:?}",
(slot.x, slot.y, slot.z)
),
LogSeverity::Basic,
);
e e
} }
@ -532,7 +599,7 @@ impl MillGame {
} }
pub fn check_for_mill(slot: &BoardSlot, board: &[[[BoardSlot; 3]; 3]; 3]) -> MillState { pub fn check_for_mill(slot: &BoardSlot, board: &[[[BoardSlot; 3]; 3]; 3]) -> MillState {
Self::log("check for mill"); Self::log("check for mill", LogSeverity::Debug);
if !(slot.x == 0 && slot.y == 0) if !(slot.x == 0 && slot.y == 0)
&& !(slot.x == 2 && slot.y == 0) && !(slot.x == 2 && slot.y == 0)
@ -546,7 +613,7 @@ impl MillGame {
); );
if state != MillState::None { if state != MillState::None {
Self::log(&format!("mill found {:?}", state)); Self::log(&format!("mill found {:?}", state), LogSeverity::Debug);
return state; return state;
} }
@ -559,7 +626,7 @@ impl MillGame {
); );
if state != MillState::None { if state != MillState::None {
Self::log(&format!("mill found {:?}", state)); Self::log(&format!("mill found {:?}", state), LogSeverity::Debug);
return state; return state;
} }
@ -571,7 +638,7 @@ impl MillGame {
); );
if state != MillState::None { if state != MillState::None {
Self::log(&format!("mill found {:?}", state)); Self::log(&format!("mill found {:?}", state), LogSeverity::Debug);
return state; return state;
} }
@ -588,7 +655,7 @@ impl MillGame {
&mut Scene, &mut Scene,
) -> Result<()>, ) -> Result<()>,
{ {
Self::log("check_mouse_click"); Self::log("check_mouse_click", LogSeverity::Debug);
self.scene.lock().unwrap().on_scene(|scene| { self.scene.lock().unwrap().on_scene(|scene| {
if let Some(world_space) = if let Some(world_space) =
@ -597,7 +664,7 @@ impl MillGame {
let mut board = self.board.lock().unwrap(); let mut board = self.board.lock().unwrap();
if let Some(slot) = board.close_to_marker(world_space.truncate()) { if let Some(slot) = board.close_to_marker(world_space.truncate()) {
Self::log("click is close to marker"); Self::log("click is close to marker", LogSeverity::Debug);
f(self, (slot.x, slot.y, slot.z), board.slots(), scene)?; f(self, (slot.x, slot.y, slot.z), board.slots(), scene)?;
} }
@ -622,8 +689,13 @@ impl MillGame {
|| (z as i32 - tz as i32).abs() == 1 || (z as i32 - tz as i32).abs() == 1
} }
pub fn log(s: &str) { pub fn log(s: &str, log_severity: LogSeverity) {
println!("{}", s); match (LOG_SEVERITY, log_severity) {
(LogSeverity::Basic, LogSeverity::Basic) => println!("{}", s),
(LogSeverity::Basic, LogSeverity::Debug) => (),
(LogSeverity::Debug, LogSeverity::Basic) => println!("{}", s),
(LogSeverity::Debug, LogSeverity::Debug) => println!("{}", s),
}
} }
} }
@ -634,9 +706,12 @@ impl EngineObject for MillGame {
fn update(&self) -> Result<()> { fn update(&self) -> Result<()> {
if self.turn_finished.load(SeqCst) { if self.turn_finished.load(SeqCst) {
if (*self.last_turn_timing.lock().unwrap() + Self::TURN_WAIT_TIME) < self.engine.time()
{
self.turn_finished.store(false, SeqCst); self.turn_finished.store(false, SeqCst);
self.next_game_step()?; self.next_game_step()?;
} }
}
Ok(()) Ok(())
} }
@ -657,17 +732,17 @@ impl EngineObject for MillGame {
match button { match button {
MouseButton::Left => { MouseButton::Left => {
let mut state = self.state.lock().unwrap(); let mut state = self.state.lock().unwrap();
Self::log(&format!("User click at state {:?}", state)); Self::log(
&format!("User click at state {:?}", state),
LogSeverity::Debug,
);
match *state { match *state {
GameState::Placing => { GameState::Placing => {
let mut placed = false;
let mut mill_found = false;
self.check_mouse_click(|me, (x, y, z), board, scene| { self.check_mouse_click(|me, (x, y, z), board, scene| {
let current_player = *self.current_player.lock().unwrap(); let current_player = *me.current_player.lock().unwrap();
if let Some(placable) = self if let Some(placable) = me
.stones(current_player) .stones(current_player)
.iter_mut() .iter_mut()
.find(|stone| stone.state == StoneState::ReadyToBePlaced) .find(|stone| stone.state == StoneState::ReadyToBePlaced)
@ -680,47 +755,45 @@ impl EngineObject for MillGame {
current_player, current_player,
scene, scene,
&mut *state, &mut *state,
)? != MillState::None )? == MillState::None
{ {
mill_found = true; me.finish_turn();
} }
placed = true;
} else { } else {
Self::log(&format!( Self::log(
&format!(
"slot ({:?}), not empty ({:?})", "slot ({:?}), not empty ({:?})",
(x, y, z), (x, y, z),
board[x][y][z].state() board[x][y][z].state()
)); ),
LogSeverity::Debug,
);
} }
} }
Ok(()) Ok(())
})?; })?;
if placed && !mill_found {
self.finish_turn();
}
} }
GameState::Removing => { GameState::Removing => {
let mut removed = false;
self.check_mouse_click(|me, (x, y, z), board, scene| { self.check_mouse_click(|me, (x, y, z), board, scene| {
let slot = &mut board[x][y][z]; let slot = &mut board[x][y][z];
Self::log(&format!( Self::log(
&format!(
"state {:?} - player {:?}", "state {:?} - player {:?}",
slot.state(), slot.state(),
*self.current_player.lock().unwrap() *me.current_player.lock().unwrap()
)); ),
LogSeverity::Debug,
);
if match (slot.state(), *self.current_player.lock().unwrap()) { if match (slot.state(), *me.current_player.lock().unwrap()) {
(BoardSlotState::Black(_), PlayerColor::White) => true, (BoardSlotState::Black(_), PlayerColor::White) => true,
(BoardSlotState::White(_), PlayerColor::Black) => true, (BoardSlotState::White(_), PlayerColor::Black) => true,
_ => false, _ => false,
} { } {
let mut stones = self let mut stones =
.stones(self.current_player.lock().unwrap().other()); self.stones(me.current_player.lock().unwrap().other());
let stone = stones let stone = stones
.iter_mut() .iter_mut()
@ -736,15 +809,11 @@ impl EngineObject for MillGame {
Self::remove_stone(stone, slot, scene)?; Self::remove_stone(stone, slot, scene)?;
removed = true; me.finish_turn();
} }
Ok(()) Ok(())
})?; })?;
if removed {
self.finish_turn();
}
} }
GameState::Main => { GameState::Main => {
self.check_mouse_click(|me, (tx, ty, tz), board, scene| { self.check_mouse_click(|me, (tx, ty, tz), board, scene| {

View file

@ -1,6 +1,6 @@
use crate::{ use crate::{
board::{Board, BoardSlot, BoardSlotState}, board::{Board, BoardSlot, BoardSlotState},
game::{GameState, MillGame, MillState, PlayerColor, Stone, StoneState}, game::{GameState, LogSeverity, MillGame, MillState, PlayerColor, Stone, StoneState},
}; };
use anyhow::Result; use anyhow::Result;
@ -22,7 +22,7 @@ impl SimpleAI {
scene: &mut SceneHandle, scene: &mut SceneHandle,
state: &mut GameState, state: &mut GameState,
) -> Result<bool> { ) -> Result<bool> {
MillGame::log(&format!("AI at state {:?}", *state)); MillGame::log(&format!("AI at state {:?}", *state), LogSeverity::Debug);
let mut found_a_mill = false; let mut found_a_mill = false;
@ -151,7 +151,7 @@ impl SimpleAI {
GameState::Waiting => unreachable!(), GameState::Waiting => unreachable!(),
} }
MillGame::log("finish AI"); MillGame::log("finish AI", LogSeverity::Debug);
Ok(found_a_mill) Ok(found_a_mill)
} }