From 4ad7a022dc3d5d88fb997a321a8f6ae7c495db12 Mon Sep 17 00:00:00 2001 From: hodasemi Date: Fri, 12 May 2023 14:53:01 +0200 Subject: [PATCH] Print game state differences to log --- .gitignore | 3 +- src/game.rs | 242 +++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 224 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index 869df07..185f8d5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target -Cargo.lock \ No newline at end of file +Cargo.lock +*.log \ No newline at end of file diff --git a/src/game.rs b/src/game.rs index a35a995..4ca663a 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,4 +1,6 @@ use std::{ + fs::OpenOptions, + io::Write, sync::{ atomic::{AtomicBool, AtomicU32, Ordering::SeqCst}, Arc, Mutex, MutexGuard, @@ -8,7 +10,10 @@ use std::{ use anyhow::Result; use assetpath::AssetPath; -use engine::prelude::{cgmath::vec3, *}; +use engine::prelude::{ + cgmath::{vec3, Vector2}, + *, +}; use crate::{ board::{Board, BoardSlot, BoardSlotState}, @@ -49,12 +54,14 @@ pub enum MillState { None, } +#[derive(Debug, Clone, Copy)] pub enum LogSeverity { Basic, Debug, } -const LOG_SEVERITY: LogSeverity = LogSeverity::Debug; +const LOG_SEVERITY: LogSeverity = LogSeverity::Basic; +const LOG_FILE: &str = "millgame.log"; impl PlayerColor { pub fn swap(&mut self) { @@ -80,6 +87,135 @@ impl PlayerColor { } } +#[derive(Default, Debug)] +struct TurnState { + white_infos: Vec<(StoneState, Entity, Option>)>, + black_infos: Vec<(StoneState, Entity, Option>)>, + board_infos: Vec<((usize, usize, usize), Vector2, BoardSlotState)>, +} + +impl TurnState { + pub fn new(game: &MillGame) -> Result { + let mut white_infos = Vec::new(); + let mut black_infos = Vec::new(); + + game.scene.lock().unwrap().on_scene(|scene| { + for white_stone in game.white_stones.lock().unwrap().iter() { + let pos = match white_stone.state { + StoneState::ReadyToBePlaced => None, + StoneState::Placed => Some( + scene + .entity(white_stone.stone)? + .get_component::()? + .position() + .truncate(), + ), + StoneState::Dead => None, + }; + + white_infos.push((white_stone.state, white_stone.stone, pos)); + } + + for black_stone in game.black_stones.lock().unwrap().iter() { + let pos = match black_stone.state { + StoneState::ReadyToBePlaced => None, + StoneState::Placed => Some( + scene + .entity(black_stone.stone)? + .get_component::()? + .position() + .truncate(), + ), + StoneState::Dead => None, + }; + + black_infos.push((black_stone.state, black_stone.stone, pos)); + } + + Ok(()) + })?; + + let board_infos: Vec<((usize, usize, usize), Vector2, BoardSlotState)> = game + .board + .lock() + .unwrap() + .slots() + .iter() + .flatten() + .flatten() + .map(|slot| ((slot.x, slot.y, slot.z), slot.position, slot.state())) + .collect(); + + Ok(Self { + white_infos, + black_infos, + board_infos, + }) + } + + pub fn diff(&self, other: &Self) -> (Self, Self) { + let mut my_diffs = Self::default(); + let mut other_diffs = Self::default(); + + for my_info in self.white_infos.iter() { + let other_info = other.white_infos.iter().find(|o| my_info.1 == o.1).unwrap(); + + if my_info.0 != other_info.0 || my_info.2 != other_info.2 { + my_diffs.white_infos.push(*my_info); + other_diffs.white_infos.push(*other_info); + } + } + + for my_info in self.black_infos.iter() { + let other_info = other.black_infos.iter().find(|o| my_info.1 == o.1).unwrap(); + + if my_info.0 != other_info.0 || my_info.2 != other_info.2 { + my_diffs.black_infos.push(*my_info); + other_diffs.black_infos.push(*other_info); + } + } + + for my_slot in self.board_infos.iter() { + let other_slot = other.board_infos.iter().find(|o| my_slot.0 == o.0).unwrap(); + + if my_slot.2 != other_slot.2 { + my_diffs.board_infos.push(*my_slot); + other_diffs.board_infos.push(*other_slot); + } + } + + (my_diffs, other_diffs) + } + + pub fn log(&self, severity: LogSeverity) { + if !self.white_infos.is_empty() { + MillGame::log(" == WHITE STONES ==", severity); + + for white_info in self.white_infos.iter() { + MillGame::log(&format!("{:?}", white_info), severity); + } + } + + if !self.black_infos.is_empty() { + MillGame::log(" == BLACK STONES ==", severity); + + for black_info in self.black_infos.iter() { + MillGame::log(&format!("{:?}", black_info), severity); + } + } + + MillGame::log(" == BOARD ==", severity); + + for board_info in self.board_infos.iter() { + MillGame::log(&format!("{:?}", board_info), severity); + } + } + + pub fn is_empty(&self) -> bool { + self.white_infos.is_empty() && self.black_infos.is_empty() && self.board_infos.is_empty() + } +} + pub struct MillGame { engine: Arc, last_turn_timing: Mutex, @@ -98,6 +234,7 @@ pub struct MillGame { mouse_y: AtomicU32, turn_finished: AtomicBool, + turn_states: Mutex>, selected_field: Mutex>, @@ -105,10 +242,10 @@ pub struct MillGame { white_player_label: Arc