Fix removing in placing state

This commit is contained in:
hodasemi 2023-05-10 10:22:46 +02:00
parent 7a41b66aa6
commit 01afc6ccf1
2 changed files with 129 additions and 88 deletions

View file

@ -10,6 +10,10 @@ use crate::{game::MillGame, objects::Objects};
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct BoardSlot {
pub x: usize,
pub y: usize,
pub z: usize,
pub state: BoardSlotState,
pub position: Vector2<f32>,
pub slot_marker: Option<Entity>,
@ -18,7 +22,13 @@ pub struct BoardSlot {
impl BoardSlot {
pub const SLOT_MARKER_SIZE: f32 = 1.5;
pub fn new(position: Vector2<f32>, scene: &mut Scene) -> Result<Self> {
pub fn new(
x: usize,
y: usize,
z: usize,
position: Vector2<f32>,
scene: &mut Scene,
) -> Result<Self> {
let mut marker = scene.engine().assets().empty_entity();
let meshes = vec![Self::create_mesh(&scene.engine(), Color::Black)?];
@ -31,14 +41,22 @@ impl BoardSlot {
marker.insert_component(location);
Ok(Self {
x,
y,
z,
state: BoardSlotState::default(),
position,
slot_marker: Some(scene.add_entity(marker)?),
})
}
pub fn invalid() -> Self {
pub fn invalid(x: usize, y: usize, z: usize) -> Self {
Self {
x,
y,
z,
state: BoardSlotState::Invalid,
position: vec2(0.0, 0.0),
slot_marker: None,
@ -147,53 +165,53 @@ impl Board {
slots = Some([
[
[
BoardSlot::new(vec2(-15.0, -15.0), scene)?, // 0 0 0
BoardSlot::new(vec2(-10.0, -10.0), scene)?, // 0 0 1
BoardSlot::new(vec2(-5.0, -5.0), scene)?, // 0 0 2
BoardSlot::new(0, 0, 0, vec2(-15.0, -15.0), scene)?, // 0 0 0
BoardSlot::new(0, 0, 1, vec2(-10.0, -10.0), scene)?, // 0 0 1
BoardSlot::new(0, 0, 2, vec2(-5.0, -5.0), scene)?, // 0 0 2
],
[
BoardSlot::new(vec2(-15.0, 0.0), scene)?, // 0 1 0
BoardSlot::new(vec2(-10.0, 0.0), scene)?, // 0 1 1
BoardSlot::new(vec2(-5.0, 0.0), scene)?, // 0 1 2
BoardSlot::new(0, 1, 0, vec2(-15.0, 0.0), scene)?, // 0 1 0
BoardSlot::new(0, 1, 1, vec2(-10.0, 0.0), scene)?, // 0 1 1
BoardSlot::new(0, 1, 2, vec2(-5.0, 0.0), scene)?, // 0 1 2
],
[
BoardSlot::new(vec2(-15.0, 15.0), scene)?, // 0 2 0
BoardSlot::new(vec2(-10.0, 10.0), scene)?, // 0 2 1
BoardSlot::new(vec2(-5.0, 5.0), scene)?, // 0 2 2
BoardSlot::new(0, 2, 0, vec2(-15.0, 15.0), scene)?, // 0 2 0
BoardSlot::new(0, 2, 1, vec2(-10.0, 10.0), scene)?, // 0 2 1
BoardSlot::new(0, 2, 2, vec2(-5.0, 5.0), scene)?, // 0 2 2
],
],
[
[
BoardSlot::new(vec2(0.0, -15.0), scene)?, // 1 0 0
BoardSlot::new(vec2(0.0, -10.0), scene)?, // 1 0 1
BoardSlot::new(vec2(0.0, -5.0), scene)?, // 1 0 2
BoardSlot::new(1, 0, 0, vec2(0.0, -15.0), scene)?, // 1 0 0
BoardSlot::new(1, 0, 1, vec2(0.0, -10.0), scene)?, // 1 0 1
BoardSlot::new(1, 0, 2, vec2(0.0, -5.0), scene)?, // 1 0 2
],
[
BoardSlot::invalid(), // 1 1 0
BoardSlot::invalid(), // 1 1 1
BoardSlot::invalid(), // 1 1 2
BoardSlot::invalid(1, 1, 0), // 1 1 0
BoardSlot::invalid(1, 1, 1), // 1 1 1
BoardSlot::invalid(1, 1, 2), // 1 1 2
],
[
BoardSlot::new(vec2(0.0, 15.0), scene)?, // 1 2 0
BoardSlot::new(vec2(0.0, 10.0), scene)?, // 1 2 1
BoardSlot::new(vec2(0.0, 5.0), scene)?, // 1 2 2
BoardSlot::new(1, 2, 0, vec2(0.0, 15.0), scene)?, // 1 2 0
BoardSlot::new(1, 2, 1, vec2(0.0, 10.0), scene)?, // 1 2 1
BoardSlot::new(1, 2, 2, vec2(0.0, 5.0), scene)?, // 1 2 2
],
],
[
[
BoardSlot::new(vec2(15.0, -15.0), scene)?, // 2 0 0
BoardSlot::new(vec2(10.0, -10.0), scene)?, // 2 0 1
BoardSlot::new(vec2(5.0, -5.0), scene)?, // 2 0 2
BoardSlot::new(2, 0, 0, vec2(15.0, -15.0), scene)?, // 2 0 0
BoardSlot::new(2, 0, 1, vec2(10.0, -10.0), scene)?, // 2 0 1
BoardSlot::new(2, 0, 2, vec2(5.0, -5.0), scene)?, // 2 0 2
],
[
BoardSlot::new(vec2(15.0, 0.0), scene)?, // 2 1 0
BoardSlot::new(vec2(10.0, 0.0), scene)?, // 2 1 1
BoardSlot::new(vec2(5.0, 0.0), scene)?, // 2 1 2
BoardSlot::new(2, 1, 0, vec2(15.0, 0.0), scene)?, // 2 1 0
BoardSlot::new(2, 1, 1, vec2(10.0, 0.0), scene)?, // 2 1 1
BoardSlot::new(2, 1, 2, vec2(5.0, 0.0), scene)?, // 2 1 2
],
[
BoardSlot::new(vec2(15.0, 15.0), scene)?, // 2 2 0
BoardSlot::new(vec2(10.0, 10.0), scene)?, // 2 2 1
BoardSlot::new(vec2(5.0, 5.0), scene)?, // 2 2 2
BoardSlot::new(2, 2, 0, vec2(15.0, 15.0), scene)?, // 2 2 0
BoardSlot::new(2, 2, 1, vec2(10.0, 10.0), scene)?, // 2 2 1
BoardSlot::new(2, 2, 2, vec2(5.0, 5.0), scene)?, // 2 2 2
],
],
]);

View file

@ -1,5 +1,5 @@
use std::sync::{
atomic::{AtomicU32, Ordering::SeqCst},
atomic::{AtomicBool, AtomicU32, Ordering::SeqCst},
Arc, Mutex, MutexGuard,
};
@ -76,6 +76,8 @@ pub struct MillGame {
mouse_x: AtomicU32,
mouse_y: AtomicU32,
turn_finished: AtomicBool,
simple_ai: SimpleAI,
white_player_label: Arc<Label>,
@ -192,6 +194,8 @@ impl MillGame {
mouse_x: AtomicU32::new(0),
mouse_y: AtomicU32::new(0),
turn_finished: AtomicBool::new(false),
simple_ai: SimpleAI::new(PlayerColor::White),
grid: grid.clone(),
@ -217,7 +221,7 @@ impl MillGame {
*me.state.lock().unwrap() = GameState::Placing;
*me.current_player.lock().unwrap() = PlayerColor::Black;
me.next_game_step()?;
me.turn_finished.store(true, SeqCst);
}
Ok(())
@ -227,6 +231,15 @@ impl MillGame {
Ok(me)
}
pub fn finish_turn(&self) {
Self::log(&format!(
"{:?} finised turn",
*self.current_player.lock().unwrap()
));
self.turn_finished.store(true, SeqCst);
}
fn next_game_step(&self) -> Result<()> {
Self::log("next_game_step");
@ -254,12 +267,7 @@ impl MillGame {
*state = GameState::Main;
}
if self.check_for_mill() != MillState::None {
Self::log("change state to Removing");
*state = GameState::Removing;
} else {
self.current_player.lock().unwrap().swap();
}
self.current_player.lock().unwrap().swap();
}
GameState::Removing => {
if !self
@ -285,12 +293,7 @@ impl MillGame {
self.current_player.lock().unwrap().swap();
}
GameState::Main => {
if self.check_for_mill() != MillState::None {
Self::log("change state to Removing");
*state = GameState::Removing;
} else {
self.current_player.lock().unwrap().swap();
}
self.current_player.lock().unwrap().swap();
}
}
}
@ -322,9 +325,11 @@ impl MillGame {
*self.state.lock().unwrap(),
)?;
self.next_game_step()?;
self.finish_turn();
}
Self::log("leave next_game_step");
Ok(())
}
@ -454,46 +459,43 @@ impl MillGame {
MillState::None
}
pub fn check_for_mill(&self) -> MillState {
pub fn check_for_mill(&self, slot: &BoardSlot, board: &[[[BoardSlot; 3]; 3]; 3]) -> MillState {
Self::log("check for mill");
let mut board = self.board.lock().unwrap();
let slots = board.slots();
let state = Self::check_mill(
&board[slot.x][slot.y][0],
&board[slot.x][slot.y][1],
&board[slot.x][slot.y][2],
);
for x in 0..3 {
for y in 0..3 {
let state = Self::check_mill(&slots[x][y][0], &slots[x][y][1], &slots[x][y][2]);
if state != MillState::None {
Self::log(&format!("mill found {:?}", state));
if state != MillState::None {
Self::log(&format!("mill found {:?}", state));
return state;
}
}
return state;
}
for x in 0..3 {
for z in 0..3 {
let state = Self::check_mill(&slots[x][0][z], &slots[x][1][z], &slots[x][2][z]);
let state = Self::check_mill(
&board[slot.x][0][slot.z],
&board[slot.x][1][slot.z],
&board[slot.x][2][slot.z],
);
if state != MillState::None {
Self::log(&format!("mill found {:?}", state));
if state != MillState::None {
Self::log(&format!("mill found {:?}", state));
return state;
}
}
return state;
}
for y in 0..3 {
for z in 0..3 {
let state = Self::check_mill(&slots[0][y][z], &slots[1][y][z], &slots[2][y][z]);
let state = Self::check_mill(
&board[0][slot.y][slot.z],
&board[1][slot.y][slot.z],
&board[2][slot.y][slot.z],
);
if state != MillState::None {
Self::log(&format!("mill found {:?}", state));
if state != MillState::None {
Self::log(&format!("mill found {:?}", state));
return state;
}
}
return state;
}
MillState::None
@ -501,7 +503,12 @@ impl MillGame {
fn check_mouse_click<F>(&self, f: F) -> Result<()>
where
F: FnOnce(&Self, &mut BoardSlot, &mut Scene) -> Result<()>,
F: FnOnce(
&Self,
(usize, usize, usize),
&mut [[[BoardSlot; 3]; 3]; 3],
&mut Scene,
) -> Result<()>,
{
Self::log("check_mouse_click");
@ -509,15 +516,12 @@ impl MillGame {
if let Some(world_space) =
scene.screen_space_to_world(self.mouse_x.load(SeqCst), self.mouse_y.load(SeqCst))?
{
if let Some(slot) = self
.board
.lock()
.unwrap()
.close_to_marker(world_space.truncate())
{
let mut board = self.board.lock().unwrap();
if let Some(slot) = board.close_to_marker(world_space.truncate()) {
Self::log("click is close to marker");
f(self, slot, scene)?;
f(self, (slot.x, slot.y, slot.z), board.slots(), scene)?;
}
}
@ -536,6 +540,11 @@ impl EngineObject for MillGame {
}
fn update(&self) -> Result<()> {
if self.turn_finished.load(SeqCst) {
self.turn_finished.store(false, SeqCst);
self.next_game_step()?;
}
Ok(())
}
@ -553,14 +562,15 @@ impl EngineObject for MillGame {
}
EngineEvent::MouseButtonDown(button) => match button {
MouseButton::Left => {
let state = *self.state.lock().unwrap();
let mut state = self.state.lock().unwrap();
Self::log(&format!("User click at state {:?}", state));
match state {
match *state {
GameState::Placing => {
let mut placed = false;
let mut mill_found = false;
self.check_mouse_click(|me, slot, scene| {
self.check_mouse_click(|me, (x, y, z), board, scene| {
let current_player = *self.current_player.lock().unwrap();
if let Some(placable) = self
@ -568,7 +578,18 @@ impl EngineObject for MillGame {
.iter_mut()
.find(|stone| stone.state == StoneState::ReadyToBePlaced)
{
Self::place_stone(placable, slot, current_player, scene)?;
Self::place_stone(
placable,
&mut board[x][y][z],
current_player,
scene,
)?;
if me.check_for_mill(&board[x][y][z], board) != MillState::None
{
mill_found = true;
*state = GameState::Removing;
}
placed = true;
}
@ -576,14 +597,16 @@ impl EngineObject for MillGame {
Ok(())
})?;
if placed {
self.next_game_step()?;
if placed && !mill_found {
self.finish_turn();
}
}
GameState::Removing => {
let mut removed = false;
self.check_mouse_click(|me, slot, scene| {
self.check_mouse_click(|me, (x, y, z), board, scene| {
let slot = &mut board[x][y][z];
Self::log(&format!(
"state {:?} - player {:?}",
slot.state,
@ -603,7 +626,7 @@ impl EngineObject for MillGame {
})?;
if removed {
self.next_game_step()?;
self.finish_turn();
}
}
GameState::Main => todo!(),