diff --git a/src/board.rs b/src/board.rs index 06fbb50..6e7fed8 100644 --- a/src/board.rs +++ b/src/board.rs @@ -16,7 +16,7 @@ pub struct BoardSlot { state: BoardSlotState, pub position: Vector2, - pub slot_marker: Option, + pub _slot_marker: Option, } impl BoardSlot { @@ -40,9 +40,8 @@ impl BoardSlot { let draw = Draw::new(meshes); marker.insert_component(draw); - let mut location = Location::from_entity(&mut marker); + let location = Location::new_and_setup(&mut marker)?; location.set_position(position.extend(MillGame::OFFSET_TO_BOARD)); - marker.insert_component(location); Ok(Self { x, @@ -51,7 +50,7 @@ impl BoardSlot { state: BoardSlotState::default(), position, - slot_marker: Some(world.add_entity(marker)?), + _slot_marker: Some(world.add_entity(marker)?), }) } @@ -63,7 +62,7 @@ impl BoardSlot { state: BoardSlotState::Invalid, position: vec2(0.0, 0.0), - slot_marker: None, + _slot_marker: None, } } @@ -169,9 +168,7 @@ impl Board { let draw = Draw::new(meshes); board_entity.insert_component(draw); - - let location = Location::from_entity(&mut board_entity); - board_entity.insert_component(location); + Location::new_and_setup(&mut board_entity)?; let board = world.add_entity(board_entity)?; @@ -234,14 +231,14 @@ impl Board { let white_start_slots = (16..=16) .step_by(4) .map(|x| vec2(x as f32, distance)) - .collect() + .collect::>() .try_into() .unwrap(); let black_start_slots = (16..=16) .step_by(4) .map(|x| vec2(x as f32, -distance)) - .collect() + .collect::>() .try_into() .unwrap(); @@ -546,9 +543,8 @@ impl Board { }]); lines.insert_component(draw); - let mut location = Location::from_entity(&mut lines); + let location = Location::new_and_setup(&mut lines)?; location.set_offset(vec3(0.0, 0.0, MillGame::OFFSET_TO_BOARD)); - lines.insert_component(location); entities.push(world.add_entity(lines)?); diff --git a/src/game.rs b/src/game.rs index 10c1772..ba75fc8 100644 --- a/src/game.rs +++ b/src/game.rs @@ -325,8 +325,7 @@ impl MillGame { me.state = GameState::Placing; me.current_player = PlayerColor::Black; - me.finish_turn(world); - me.last_turn_timing = now; + me.finish_turn(now); Ok(()) } @@ -365,13 +364,13 @@ impl MillGame { Ok(()) } - pub fn finish_turn(&mut self, world: &World) { + pub fn finish_turn(&mut self, now: Duration) { Self::log( &format!("{:?} finished turn", self.current_player), LogSeverity::Debug, ); - self.last_turn_timing = world.now(); + self.last_turn_timing = now; self.turn_finished = true; self.selected_field = None; } @@ -406,7 +405,7 @@ impl MillGame { Ok(()) } - fn next_game_step(&mut self, world: &World) -> Result<()> { + fn next_game_step(&mut self, world: &mut World) -> Result<()> { Self::log( &format!( " =========================== NEW TURN ({:?}) ===========================", @@ -492,7 +491,7 @@ impl MillGame { LogSeverity::Debug, ); - let mut resources = world.resources.multi_mut(); + let mut resources = unsafe { remove_life_time_mut(world) }.resources.multi_mut(); let gui_handler = resources.get::(); let simple_ai = resources.get::(); @@ -515,13 +514,13 @@ impl MillGame { Self::log("current player is AI", LogSeverity::Debug); simple_ai.step( - &mut self.stones(simple_ai.player_color), - self.board.slots_mut(), - &mut *self.scene.lock().unwrap(), + unsafe { remove_life_time_mut(self.stones_mut(simple_ai.player_color)) }, + unsafe { remove_life_time_mut(self.board.slots_mut()) }, + world, &mut self.state, )?; - self.finish_turn(world); + self.finish_turn(world.now()); } Self::log("leave next_game_step", LogSeverity::Debug); @@ -529,10 +528,10 @@ impl MillGame { Ok(()) } - fn stones(&self, player_color: PlayerColor) -> &[Stone; 9] { + fn stones_mut(&mut self, player_color: PlayerColor) -> &mut [Stone; 9] { match player_color { - PlayerColor::White => &self.white_stones, - PlayerColor::Black => &self.black_stones, + PlayerColor::White => &mut self.white_stones, + PlayerColor::Black => &mut self.black_stones, } } @@ -586,8 +585,7 @@ impl MillGame { }]); marker.insert_component(draw); - let location = Location::from_entity(&mut marker); - marker.insert_component(location); + Location::new_and_setup(&mut marker)?; Ok(marker) } @@ -664,7 +662,7 @@ impl MillGame { LogSeverity::Debug, ); - let slot = &mut board[x][y][z]; + let slot = unsafe { remove_life_time_mut(&mut board[x][y][z]) }; let neighbour = &mut board[tx][ty][tz]; if neighbour.state() != BoardSlotState::Empty @@ -829,15 +827,20 @@ impl MillGame { fn check_mouse_click(&mut self, scene: &Scene, f: F) -> Result<()> where - F: FnOnce(&Self, (usize, usize, usize), &mut [[[BoardSlot; 3]; 3]; 3]) -> Result<()>, + F: FnOnce(&mut Self, (usize, usize, usize), &mut [[[BoardSlot; 3]; 3]; 3]) -> Result<()>, { Self::log("check_mouse_click", LogSeverity::Debug); if let Some(world_space) = scene.screen_space_to_world(self.mouse_x, self.mouse_y)? { - if let Some(slot) = self.board.close_to_marker(world_space.truncate()) { + if let Some(slot) = unsafe { remove_life_time(self) } + .board + .close_to_marker(world_space.truncate()) + { Self::log("click is close to marker", LogSeverity::Debug); - f(self, (slot.x, slot.y, slot.z), self.board.slots_mut())?; + let slots = unsafe { remove_life_time_mut(self.board.slots_mut()) }; + + f(self, (slot.x, slot.y, slot.z), slots)?; } } @@ -886,7 +889,7 @@ impl MillGame { pub fn update(world: &mut World) -> Result { let now = world.now(); - let me = world.resources.get_mut::(); + let me = world.resources.get_mut_unchecked::(); if me.turn_finished { if (me.last_turn_timing + Self::TURN_WAIT_TIME) < now { @@ -921,15 +924,14 @@ impl EventConsumer for MillGame { match self.state { GameState::Placing => { - let mut resources = world.resources.multi_mut(); - self.check_mouse_click( - resources.get::(), + world.resources.get_unchecked::(), |me, (x, y, z), board| { - if let Some(placable) = me - .stones(me.current_player) - .iter_mut() - .find(|stone| stone.state == StoneState::ReadyToBePlaced) + if let Some(placable) = unsafe { + remove_life_time_mut(me.stones_mut(me.current_player)) + } + .iter_mut() + .find(|stone| stone.state == StoneState::ReadyToBePlaced) { if board[x][y][z].is_empty() { if Self::place_stone( @@ -938,10 +940,10 @@ impl EventConsumer for MillGame { board, me.current_player, world, - &mut self.state, + &mut me.state, )? == MillState::None { - me.finish_turn(world); + me.finish_turn(world.now()); } } else { Self::log( @@ -960,10 +962,8 @@ impl EventConsumer for MillGame { )?; } GameState::Removing => { - let mut resources = world.resources.multi_mut(); - self.check_mouse_click( - resources.get::(), + world.resources.get_unchecked::(), |me, (x, y, z), board| { let slot = &mut board[x][y][z]; @@ -981,9 +981,8 @@ impl EventConsumer for MillGame { (BoardSlotState::White(_), PlayerColor::Black) => true, _ => false, } { - let mut stones = self.stones(me.current_player.other()); - - let stone = stones + let stone = me + .stones_mut(me.current_player.other()) .iter_mut() .find(|s| { s.stone @@ -997,7 +996,7 @@ impl EventConsumer for MillGame { Self::remove_stone(stone, slot, world)?; - me.finish_turn(world); + me.finish_turn(world.now()); } Ok(()) @@ -1005,17 +1004,15 @@ impl EventConsumer for MillGame { )?; } GameState::Main => { - let mut resources = world.resources.multi_mut(); - - self.check_mouse_click(resources.get::() , |me, (tx, ty, tz), board| { + self.check_mouse_click(world.resources.get_unchecked::() , |me, (tx, ty, tz), board| { match me.selected_field { Some((x, y, z)) => { if Self::is_neighbour((x, y, z), (tx, ty, tz)) { if let Some(millstate) - = Self::move_stone((x,y,z), (tx,ty,tz), world, board, &mut self.state)? { + = Self::move_stone((x,y,z), (tx,ty,tz), world, board, &mut me.state)? { if let MillState::None = millstate { me.selected_field = None; - self.finish_turn(world); + me.finish_turn(world.now()); } } } diff --git a/src/main.rs b/src/main.rs index c2b4399..1ae186a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,10 @@ fn main() -> Result<()> { create_engine(&mut world_builder)?; world_builder.add_system(MillGame::update); - world_builder.build().run() + let mut world = world_builder.build(); + MillGame::new(&mut world)?; + + world.run() } fn create_engine(world_builder: &mut WorldBuilder) -> Result<()> { @@ -39,7 +42,5 @@ fn create_engine(world_builder: &mut WorldBuilder) -> Result<()> { create_info.enable_keyboard = true; create_info.enable_mouse = true; - let engine = Engine::new::(create_info, world_builder)?; - - Ok(()) + Engine::new::(create_info, world_builder) } diff --git a/src/simple_ai.rs b/src/simple_ai.rs index 5e7beec..a344086 100644 --- a/src/simple_ai.rs +++ b/src/simple_ai.rs @@ -47,21 +47,17 @@ impl SimpleAI { (slot.x, slot.y, slot.z) }; - scene.on_scene(|scene| { - if MillGame::place_stone( - placable, - (x, y, z), - board, - self.player_color, - scene, - state, - )? != MillState::None - { - found_a_mill = true; - } - - Ok(()) - })?; + if MillGame::place_stone( + placable, + (x, y, z), + board, + self.player_color, + world, + state, + )? != MillState::None + { + found_a_mill = true; + } } } GameState::Removing => { @@ -95,82 +91,67 @@ impl SimpleAI { MillGame::log("[AI] remove stone", LogSeverity::Debug); - scene.on_scene(|scene| { - MillGame::remove_stone(stone, slot, scene)?; - - Ok(()) - })?; + MillGame::remove_stone(stone, slot, world)?; } - GameState::Main => { - 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(); + GameState::Main => 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(); - 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; + let mut successful_move = false; - MillGame::log("[AI] going to make a move", LogSeverity::Debug); + MillGame::log("[AI] going to make a move", LogSeverity::Debug); - if let Some(millstate) = MillGame::move_stone( - (x, y, z), - (tx, ty, tz), - scene, - board, - state, - )? { - MillGame::log("[AI] successful move", LogSeverity::Debug); + if let Some(millstate) = + MillGame::move_stone((x, y, z), (tx, ty, tz), world, board, state)? + { + MillGame::log("[AI] successful move", LogSeverity::Debug); - if MillState::None != millstate { - MillGame::log("[AI] found a mill", 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); - } - - if successful_move { - break; - } + found_a_mill = true; } + + successful_move = true; + } else { + MillGame::log("[AI] move failed", LogSeverity::Debug); + } + + if successful_move { + break; } } - - Ok(()) - })?; - } + } + }, GameState::Waiting => unreachable!(), GameState::Won(_) => (), } if found_a_mill { - self.step(stones, board, scene, state)?; + self.step(stones, board, world, state)?; } MillGame::log("finish AI", LogSeverity::Debug);