Wait I think merging works?! fuck yeah.

main
Elijah C. Voigt 2 years ago
parent 098df2998b
commit 0c56bd18a1

@ -157,6 +157,9 @@ pub(crate) struct ValidMove;
#[derive(Debug, Component)] #[derive(Debug, Component)]
pub(crate) struct Captured; pub(crate) struct Captured;
#[derive(Debug, Component)]
pub(crate) struct Merged;
// manually for the type. // manually for the type.
impl std::fmt::Display for Piece { impl std::fmt::Display for Piece {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
@ -242,6 +245,7 @@ pub(crate) struct Move {
pub epoch: usize, pub epoch: usize,
pub from: BoardIndex, pub from: BoardIndex,
pub to: Option<BoardIndex>, pub to: Option<BoardIndex>,
pub move_type: MoveType,
} }
/// Enum for the Capture event flow /// Enum for the Capture event flow
@ -290,12 +294,13 @@ impl From<(usize, usize)> for BoardIndex {
} }
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Clone, Default)]
pub(crate) enum MoveType { pub(crate) enum MoveType {
Valid, Valid,
#[default]
Invalid, Invalid,
Capture, Capture,
Merge, Merge(Piece),
} }
#[derive(Debug, Component, PartialEq, Clone, Copy, Eq, Hash, Default)] #[derive(Debug, Component, PartialEq, Clone, Copy, Eq, Hash, Default)]
@ -367,10 +372,15 @@ impl Board {
fn new() -> Board { fn new() -> Board {
Board::from_ascii( Board::from_ascii(
r#".....dqq // r#".....dqq
dpp..pdq // dpp..pdq
qdp..ppd // qdp..ppd
qqd....."#, // qqd....."#,
r#"........
..p.p...
...p....
........"#,
) )
} }
@ -429,38 +439,44 @@ impl Board {
} else { } else {
match self.at(from) { match self.at(from) {
Some(from_piece) => { Some(from_piece) => {
// Check if this is a valid move for this piece let move_type = self.move_type(from, to);
if self.valid_moves(from).contains(&to) { match move_type {
// The current epoch is the last epoch + 1 MoveType::Invalid => {
let epoch = self.current_epoch(); Err(GameError::InvalidMove)
},
MoveType::Valid | MoveType::Capture | MoveType::Merge(..) => {
// The current epoch is the last epoch + 1
let epoch = self.current_epoch();
// Local moves vec we can return
let mut moves = vec![];
// Local moves vec we can return // If the position we are moving to is occupied, capture the removal in the ledger
let mut moves = vec![]; if self.inner[to.y][to.x].is_some() {
moves.push(Move {
epoch,
from: to,
to: None,
move_type: move_type.clone(),
});
}
// If the position we are moving to is occupied, capture the removal in the ledger // Capture the intended move in the moves ledger
if self.inner[to.y][to.x].is_some() {
moves.push(Move { moves.push(Move {
epoch, epoch,
from: to, from,
to: None, to: Some(to),
move_type: move_type.clone(),
}); });
}
// Capture the intended move in the moves ledger self.inner[to.y][to.x] = Some(*from_piece);
moves.push(Move { self.inner[from.y][from.x] = None;
epoch,
from,
to: Some(to),
});
self.inner[to.y][to.x] = Some(*from_piece); self.moves.extend(moves.clone());
self.inner[from.y][from.x] = None;
self.moves.extend(moves.clone()); Ok(moves)
}
Ok(moves)
} else {
Err(GameError::InvalidMove)
} }
} }
None => Err(GameError::NullMove), None => Err(GameError::NullMove),
@ -512,8 +528,10 @@ impl Board {
&self, &self,
from: BoardIndex, from: BoardIndex,
to: BoardIndex, to: BoardIndex,
) -> Option<MoveType> { ) -> MoveType {
self.line(from, to).all(|board_index| self.at(board_index).is_none()).then(|| { self.line(from, to)
.all(|board_index| self.at(board_index).is_none())
.then(|| {
self.at(from).map(|piece| { self.at(from).map(|piece| {
// Given that the side does not have a queen||drone // Given that the side does not have a queen||drone
// And the piece is a drone||pawn // And the piece is a drone||pawn
@ -541,10 +559,10 @@ impl Board {
Some(to_piece) => { Some(to_piece) => {
match (piece, to_piece) { match (piece, to_piece) {
(Piece::Pawn, Piece::Pawn) => { (Piece::Pawn, Piece::Pawn) => {
(!side_has_drone).then_some(MoveType::Merge) (!side_has_drone).then_some(MoveType::Merge(Piece::Drone))
} }
(Piece::Drone, Piece::Pawn) | (Piece::Pawn, Piece::Drone) => { (Piece::Drone, Piece::Pawn) | (Piece::Pawn, Piece::Drone) => {
(!side_has_queen).then_some(MoveType::Merge) (!side_has_queen).then_some(MoveType::Merge(Piece::Queen))
}, },
_ => { _ => {
Some(MoveType::Invalid) Some(MoveType::Invalid)
@ -581,7 +599,7 @@ impl Board {
} }
}) })
}) })
}).flatten().flatten().or(Some(MoveType::Invalid)) }).flatten().flatten().or(Some(MoveType::Invalid)).unwrap()
} }
/// Returns the possible moves the piece at this tile can make. /// Returns the possible moves the piece at this tile can make.
@ -591,8 +609,8 @@ impl Board {
// Get the move type (or none if totally invalid) // Get the move type (or none if totally invalid)
let result = self.move_type(current_board_index, *move_index); let result = self.move_type(current_board_index, *move_index);
match result { match result {
None | Some(MoveType::Invalid) => None, MoveType::Invalid => None,
Some(MoveType::Capture) | Some(MoveType::Merge) | Some(MoveType::Valid) => { MoveType::Capture | MoveType::Merge(..) | MoveType::Valid => {
Some(*move_index) Some(*move_index)
}, },
} }
@ -751,7 +769,7 @@ mod test {
assert_eq!(expected, given, "Pawn can merge to make a drone"); assert_eq!(expected, given, "Pawn can merge to make a drone");
let move_type = board.move_type((0, 0).into(), (1, 1).into()); let move_type = board.move_type((0, 0).into(), (1, 1).into());
assert_eq!(Some(MoveType::Merge), move_type); assert_eq!(MoveType::Merge(Piece::Drone), move_type);
} }
// Pawn cannot merge with queen // Pawn cannot merge with queen
@ -892,20 +910,17 @@ mod test {
let actual = board.valid_moves((3, 1).into()); let actual = board.valid_moves((3, 1).into());
assert_eq!(expected, actual); assert_eq!(expected, actual);
// Merging drone and pawn to make a queen
let capture_move = board.move_type((3, 1).into(), (5, 1).into()); let capture_move = board.move_type((3, 1).into(), (5, 1).into());
assert_eq!(Some(MoveType::Capture), capture_move); assert_eq!(MoveType::Capture, capture_move);
// Merging does not cross the canal
let merge_move = board.move_type((3, 1).into(), (2, 1).into()); let merge_move = board.move_type((3, 1).into(), (2, 1).into());
assert_eq!(Some(MoveType::Merge), merge_move); assert_eq!(MoveType::Merge(Piece::Queen), merge_move);
let long_merge_move = board.move_type((3, 1).into(), (3, 3).into()); let long_merge_move = board.move_type((3, 1).into(), (3, 3).into());
assert_eq!(Some(MoveType::Merge), long_merge_move); assert_eq!(MoveType::Merge(Piece::Queen), long_merge_move);
// Still cannot cross over friendlies
let jump_move = board.move_type((3, 1).into(), (1, 1).into()); let jump_move = board.move_type((3, 1).into(), (1, 1).into());
assert_eq!(Some(MoveType::Invalid), jump_move); assert_eq!(MoveType::Invalid, jump_move);
} }
} }
@ -926,19 +941,19 @@ mod test {
// Pawn + Pawn on same side = Promotion // Pawn + Pawn on same side = Promotion
let merge_move = board.move_type((3, 1).into(), (2, 2).into()); let merge_move = board.move_type((3, 1).into(), (2, 2).into());
assert_eq!(Some(MoveType::Merge), merge_move); assert_eq!(MoveType::Merge(Piece::Drone), merge_move);
// Pawn + Pawn on other side = Capture // Pawn + Pawn on other side = Capture
let capture_move = board.move_type((3, 1).into(), (4, 2).into()); let capture_move = board.move_type((3, 1).into(), (4, 2).into());
assert_eq!(Some(MoveType::Capture), capture_move); assert_eq!(MoveType::Capture, capture_move);
// Pawn + Empty = Move // Pawn + Empty = Move
let place_move = board.move_type((3, 1).into(), (2, 0).into()); let place_move = board.move_type((3, 1).into(), (2, 0).into());
assert_eq!(Some(MoveType::Valid), place_move); assert_eq!(MoveType::Valid, place_move);
// Pawn + Invalid Empty = Invalid // Pawn + Invalid Empty = Invalid
let invalid_move = board.move_type((3, 1).into(), (7, 7).into()); let invalid_move = board.move_type((3, 1).into(), (7, 7).into());
assert_eq!(Some(MoveType::Invalid), invalid_move); assert_eq!(MoveType::Invalid, invalid_move);
} }
} }
} }
@ -992,30 +1007,63 @@ pub(crate) fn update_board(
curr_state: Res<State<TurnState>>, curr_state: Res<State<TurnState>>,
mut next_state: ResMut<NextState<TurnState>>, mut next_state: ResMut<NextState<TurnState>>,
) { ) {
events.read().for_each(|Move { from, to, .. }| { // Each move event we get
events.read().for_each(|Move { from, to, move_type, .. }| {
// Iterate over all pieces
pieces.iter_mut().for_each(|(entity, mut index)| { pieces.iter_mut().for_each(|(entity, mut index)| {
// If the current index is the 'from' for the move
// All moves cover From -> To (captures and merges have to: None)
if *index == *from { if *index == *from {
match to { match to {
// If we are moving on the board...
Some(to_idx) => { Some(to_idx) => {
info!("Moving piece {:?} {:?} -> {:?}", entity, from, to_idx); info!("Moving piece {:?} {:?} -> {:?}", entity, from, to_idx);
// Update the piece's index
*index = *to_idx; *index = *to_idx;
// Play audio sfx
if !(*played) { if !(*played) {
audio_events.send(audio::AudioEvent::PutDown); audio_events.send(audio::AudioEvent::PutDown);
audio_events.send(audio::AudioEvent::StopIdle); audio_events.send(audio::AudioEvent::StopIdle);
*played = true; *played = true;
if *from != *to_idx { }
let ns = !*curr_state.get(); if *from != *to_idx {
info!("Piece moved, switching sides: {:?}", ns); match move_type {
next_state.set(ns); MoveType::Merge(piece) => {
error!("Hey Eli, this is where you are merging pieces");
// Here we insert a new Piece type based on the merge
// Other system should automatically update the model
commands
.entity(entity)
.insert(*piece);
}
_ => ()
} }
let ns = !*curr_state.get();
info!("Piece moved, switching sides: {:?}", ns);
next_state.set(ns);
} }
} }
// We are moving off the board (e.g,. capture or merge)
None => { None => {
info!("Capturing piece {:?}", entity); match move_type {
commands MoveType::Capture => {
.entity(entity) info!("Capturing piece {:?}", entity);
.remove::<BoardIndex>() commands
.insert(Captured); .entity(entity)
.remove::<BoardIndex>()
.insert(Captured);
},
MoveType::Merge(..) => {
commands
.entity(entity)
.remove::<BoardIndex>()
.insert(Merged);
},
_ => {
panic!("How did you do this!?");
}
}
} }
} }
} }

Loading…
Cancel
Save