Fix removing in placing state
This commit is contained in:
parent
7a41b66aa6
commit
01afc6ccf1
2 changed files with 129 additions and 88 deletions
76
src/board.rs
76
src/board.rs
|
@ -10,6 +10,10 @@ use crate::{game::MillGame, objects::Objects};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||||
pub struct BoardSlot {
|
pub struct BoardSlot {
|
||||||
|
pub x: usize,
|
||||||
|
pub y: usize,
|
||||||
|
pub z: usize,
|
||||||
|
|
||||||
pub state: BoardSlotState,
|
pub state: BoardSlotState,
|
||||||
pub position: Vector2<f32>,
|
pub position: Vector2<f32>,
|
||||||
pub slot_marker: Option<Entity>,
|
pub slot_marker: Option<Entity>,
|
||||||
|
@ -18,7 +22,13 @@ pub struct BoardSlot {
|
||||||
impl BoardSlot {
|
impl BoardSlot {
|
||||||
pub const SLOT_MARKER_SIZE: f32 = 1.5;
|
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 mut marker = scene.engine().assets().empty_entity();
|
||||||
|
|
||||||
let meshes = vec![Self::create_mesh(&scene.engine(), Color::Black)?];
|
let meshes = vec![Self::create_mesh(&scene.engine(), Color::Black)?];
|
||||||
|
@ -31,14 +41,22 @@ impl BoardSlot {
|
||||||
marker.insert_component(location);
|
marker.insert_component(location);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
z,
|
||||||
|
|
||||||
state: BoardSlotState::default(),
|
state: BoardSlotState::default(),
|
||||||
position,
|
position,
|
||||||
slot_marker: Some(scene.add_entity(marker)?),
|
slot_marker: Some(scene.add_entity(marker)?),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn invalid() -> Self {
|
pub fn invalid(x: usize, y: usize, z: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
z,
|
||||||
|
|
||||||
state: BoardSlotState::Invalid,
|
state: BoardSlotState::Invalid,
|
||||||
position: vec2(0.0, 0.0),
|
position: vec2(0.0, 0.0),
|
||||||
slot_marker: None,
|
slot_marker: None,
|
||||||
|
@ -147,53 +165,53 @@ impl Board {
|
||||||
slots = Some([
|
slots = Some([
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
BoardSlot::new(vec2(-15.0, -15.0), scene)?, // 0 0 0
|
BoardSlot::new(0, 0, 0, vec2(-15.0, -15.0), scene)?, // 0 0 0
|
||||||
BoardSlot::new(vec2(-10.0, -10.0), scene)?, // 0 0 1
|
BoardSlot::new(0, 0, 1, vec2(-10.0, -10.0), scene)?, // 0 0 1
|
||||||
BoardSlot::new(vec2(-5.0, -5.0), scene)?, // 0 0 2
|
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(0, 1, 0, vec2(-15.0, 0.0), scene)?, // 0 1 0
|
||||||
BoardSlot::new(vec2(-10.0, 0.0), scene)?, // 0 1 1
|
BoardSlot::new(0, 1, 1, vec2(-10.0, 0.0), scene)?, // 0 1 1
|
||||||
BoardSlot::new(vec2(-5.0, 0.0), scene)?, // 0 1 2
|
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(0, 2, 0, vec2(-15.0, 15.0), scene)?, // 0 2 0
|
||||||
BoardSlot::new(vec2(-10.0, 10.0), scene)?, // 0 2 1
|
BoardSlot::new(0, 2, 1, vec2(-10.0, 10.0), scene)?, // 0 2 1
|
||||||
BoardSlot::new(vec2(-5.0, 5.0), scene)?, // 0 2 2
|
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(1, 0, 0, vec2(0.0, -15.0), scene)?, // 1 0 0
|
||||||
BoardSlot::new(vec2(0.0, -10.0), scene)?, // 1 0 1
|
BoardSlot::new(1, 0, 1, vec2(0.0, -10.0), scene)?, // 1 0 1
|
||||||
BoardSlot::new(vec2(0.0, -5.0), scene)?, // 1 0 2
|
BoardSlot::new(1, 0, 2, vec2(0.0, -5.0), scene)?, // 1 0 2
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
BoardSlot::invalid(), // 1 1 0
|
BoardSlot::invalid(1, 1, 0), // 1 1 0
|
||||||
BoardSlot::invalid(), // 1 1 1
|
BoardSlot::invalid(1, 1, 1), // 1 1 1
|
||||||
BoardSlot::invalid(), // 1 1 2
|
BoardSlot::invalid(1, 1, 2), // 1 1 2
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
BoardSlot::new(vec2(0.0, 15.0), scene)?, // 1 2 0
|
BoardSlot::new(1, 2, 0, vec2(0.0, 15.0), scene)?, // 1 2 0
|
||||||
BoardSlot::new(vec2(0.0, 10.0), scene)?, // 1 2 1
|
BoardSlot::new(1, 2, 1, vec2(0.0, 10.0), scene)?, // 1 2 1
|
||||||
BoardSlot::new(vec2(0.0, 5.0), scene)?, // 1 2 2
|
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(2, 0, 0, vec2(15.0, -15.0), scene)?, // 2 0 0
|
||||||
BoardSlot::new(vec2(10.0, -10.0), scene)?, // 2 0 1
|
BoardSlot::new(2, 0, 1, vec2(10.0, -10.0), scene)?, // 2 0 1
|
||||||
BoardSlot::new(vec2(5.0, -5.0), scene)?, // 2 0 2
|
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(2, 1, 0, vec2(15.0, 0.0), scene)?, // 2 1 0
|
||||||
BoardSlot::new(vec2(10.0, 0.0), scene)?, // 2 1 1
|
BoardSlot::new(2, 1, 1, vec2(10.0, 0.0), scene)?, // 2 1 1
|
||||||
BoardSlot::new(vec2(5.0, 0.0), scene)?, // 2 1 2
|
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(2, 2, 0, vec2(15.0, 15.0), scene)?, // 2 2 0
|
||||||
BoardSlot::new(vec2(10.0, 10.0), scene)?, // 2 2 1
|
BoardSlot::new(2, 2, 1, vec2(10.0, 10.0), scene)?, // 2 2 1
|
||||||
BoardSlot::new(vec2(5.0, 5.0), scene)?, // 2 2 2
|
BoardSlot::new(2, 2, 2, vec2(5.0, 5.0), scene)?, // 2 2 2
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
141
src/game.rs
141
src/game.rs
|
@ -1,5 +1,5 @@
|
||||||
use std::sync::{
|
use std::sync::{
|
||||||
atomic::{AtomicU32, Ordering::SeqCst},
|
atomic::{AtomicBool, AtomicU32, Ordering::SeqCst},
|
||||||
Arc, Mutex, MutexGuard,
|
Arc, Mutex, MutexGuard,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,6 +76,8 @@ pub struct MillGame {
|
||||||
mouse_x: AtomicU32,
|
mouse_x: AtomicU32,
|
||||||
mouse_y: AtomicU32,
|
mouse_y: AtomicU32,
|
||||||
|
|
||||||
|
turn_finished: AtomicBool,
|
||||||
|
|
||||||
simple_ai: SimpleAI,
|
simple_ai: SimpleAI,
|
||||||
|
|
||||||
white_player_label: Arc<Label>,
|
white_player_label: Arc<Label>,
|
||||||
|
@ -192,6 +194,8 @@ impl MillGame {
|
||||||
mouse_x: AtomicU32::new(0),
|
mouse_x: AtomicU32::new(0),
|
||||||
mouse_y: AtomicU32::new(0),
|
mouse_y: AtomicU32::new(0),
|
||||||
|
|
||||||
|
turn_finished: AtomicBool::new(false),
|
||||||
|
|
||||||
simple_ai: SimpleAI::new(PlayerColor::White),
|
simple_ai: SimpleAI::new(PlayerColor::White),
|
||||||
|
|
||||||
grid: grid.clone(),
|
grid: grid.clone(),
|
||||||
|
@ -217,7 +221,7 @@ impl MillGame {
|
||||||
*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.next_game_step()?;
|
me.turn_finished.store(true, SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -227,6 +231,15 @@ impl MillGame {
|
||||||
Ok(me)
|
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<()> {
|
fn next_game_step(&self) -> Result<()> {
|
||||||
Self::log("next_game_step");
|
Self::log("next_game_step");
|
||||||
|
|
||||||
|
@ -254,12 +267,7 @@ impl MillGame {
|
||||||
*state = GameState::Main;
|
*state = GameState::Main;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.check_for_mill() != MillState::None {
|
self.current_player.lock().unwrap().swap();
|
||||||
Self::log("change state to Removing");
|
|
||||||
*state = GameState::Removing;
|
|
||||||
} else {
|
|
||||||
self.current_player.lock().unwrap().swap();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
GameState::Removing => {
|
GameState::Removing => {
|
||||||
if !self
|
if !self
|
||||||
|
@ -285,12 +293,7 @@ impl MillGame {
|
||||||
self.current_player.lock().unwrap().swap();
|
self.current_player.lock().unwrap().swap();
|
||||||
}
|
}
|
||||||
GameState::Main => {
|
GameState::Main => {
|
||||||
if self.check_for_mill() != MillState::None {
|
self.current_player.lock().unwrap().swap();
|
||||||
Self::log("change state to Removing");
|
|
||||||
*state = GameState::Removing;
|
|
||||||
} else {
|
|
||||||
self.current_player.lock().unwrap().swap();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -322,9 +325,11 @@ impl MillGame {
|
||||||
*self.state.lock().unwrap(),
|
*self.state.lock().unwrap(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.next_game_step()?;
|
self.finish_turn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Self::log("leave next_game_step");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,46 +459,43 @@ impl MillGame {
|
||||||
MillState::None
|
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");
|
Self::log("check for mill");
|
||||||
|
|
||||||
let mut board = self.board.lock().unwrap();
|
let state = Self::check_mill(
|
||||||
let slots = board.slots();
|
&board[slot.x][slot.y][0],
|
||||||
|
&board[slot.x][slot.y][1],
|
||||||
|
&board[slot.x][slot.y][2],
|
||||||
|
);
|
||||||
|
|
||||||
for x in 0..3 {
|
if state != MillState::None {
|
||||||
for y in 0..3 {
|
Self::log(&format!("mill found {:?}", state));
|
||||||
let state = Self::check_mill(&slots[x][y][0], &slots[x][y][1], &slots[x][y][2]);
|
|
||||||
|
|
||||||
if state != MillState::None {
|
return state;
|
||||||
Self::log(&format!("mill found {:?}", state));
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for x in 0..3 {
|
let state = Self::check_mill(
|
||||||
for z in 0..3 {
|
&board[slot.x][0][slot.z],
|
||||||
let state = Self::check_mill(&slots[x][0][z], &slots[x][1][z], &slots[x][2][z]);
|
&board[slot.x][1][slot.z],
|
||||||
|
&board[slot.x][2][slot.z],
|
||||||
|
);
|
||||||
|
|
||||||
if state != MillState::None {
|
if state != MillState::None {
|
||||||
Self::log(&format!("mill found {:?}", state));
|
Self::log(&format!("mill found {:?}", state));
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for y in 0..3 {
|
let state = Self::check_mill(
|
||||||
for z in 0..3 {
|
&board[0][slot.y][slot.z],
|
||||||
let state = Self::check_mill(&slots[0][y][z], &slots[1][y][z], &slots[2][y][z]);
|
&board[1][slot.y][slot.z],
|
||||||
|
&board[2][slot.y][slot.z],
|
||||||
|
);
|
||||||
|
|
||||||
if state != MillState::None {
|
if state != MillState::None {
|
||||||
Self::log(&format!("mill found {:?}", state));
|
Self::log(&format!("mill found {:?}", state));
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MillState::None
|
MillState::None
|
||||||
|
@ -501,7 +503,12 @@ impl MillGame {
|
||||||
|
|
||||||
fn check_mouse_click<F>(&self, f: F) -> Result<()>
|
fn check_mouse_click<F>(&self, f: F) -> Result<()>
|
||||||
where
|
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");
|
Self::log("check_mouse_click");
|
||||||
|
|
||||||
|
@ -509,15 +516,12 @@ impl MillGame {
|
||||||
if let Some(world_space) =
|
if let Some(world_space) =
|
||||||
scene.screen_space_to_world(self.mouse_x.load(SeqCst), self.mouse_y.load(SeqCst))?
|
scene.screen_space_to_world(self.mouse_x.load(SeqCst), self.mouse_y.load(SeqCst))?
|
||||||
{
|
{
|
||||||
if let Some(slot) = self
|
let mut board = self.board.lock().unwrap();
|
||||||
.board
|
|
||||||
.lock()
|
if let Some(slot) = board.close_to_marker(world_space.truncate()) {
|
||||||
.unwrap()
|
|
||||||
.close_to_marker(world_space.truncate())
|
|
||||||
{
|
|
||||||
Self::log("click is close to marker");
|
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<()> {
|
fn update(&self) -> Result<()> {
|
||||||
|
if self.turn_finished.load(SeqCst) {
|
||||||
|
self.turn_finished.store(false, SeqCst);
|
||||||
|
self.next_game_step()?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,14 +562,15 @@ impl EngineObject for MillGame {
|
||||||
}
|
}
|
||||||
EngineEvent::MouseButtonDown(button) => match button {
|
EngineEvent::MouseButtonDown(button) => match button {
|
||||||
MouseButton::Left => {
|
MouseButton::Left => {
|
||||||
let 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));
|
||||||
|
|
||||||
match state {
|
match *state {
|
||||||
GameState::Placing => {
|
GameState::Placing => {
|
||||||
let mut placed = false;
|
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();
|
let current_player = *self.current_player.lock().unwrap();
|
||||||
|
|
||||||
if let Some(placable) = self
|
if let Some(placable) = self
|
||||||
|
@ -568,7 +578,18 @@ impl EngineObject for MillGame {
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.find(|stone| stone.state == StoneState::ReadyToBePlaced)
|
.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;
|
placed = true;
|
||||||
}
|
}
|
||||||
|
@ -576,14 +597,16 @@ impl EngineObject for MillGame {
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if placed {
|
if placed && !mill_found {
|
||||||
self.next_game_step()?;
|
self.finish_turn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GameState::Removing => {
|
GameState::Removing => {
|
||||||
let mut removed = false;
|
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!(
|
Self::log(&format!(
|
||||||
"state {:?} - player {:?}",
|
"state {:?} - player {:?}",
|
||||||
slot.state,
|
slot.state,
|
||||||
|
@ -603,7 +626,7 @@ impl EngineObject for MillGame {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if removed {
|
if removed {
|
||||||
self.next_game_step()?;
|
self.finish_turn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GameState::Main => todo!(),
|
GameState::Main => todo!(),
|
||||||
|
|
Loading…
Reference in a new issue