From 0c56bd18a1e765ee6b237f6733c20e6158f7a9f6 Mon Sep 17 00:00:00 2001 From: "Elijah C. Voigt" Date: Sat, 4 May 2024 23:18:23 -0700 Subject: [PATCH] Wait I think merging works?! fuck yeah. --- src/game.rs | 166 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 107 insertions(+), 59 deletions(-) diff --git a/src/game.rs b/src/game.rs index 8363605..3c698ba 100644 --- a/src/game.rs +++ b/src/game.rs @@ -157,6 +157,9 @@ pub(crate) struct ValidMove; #[derive(Debug, Component)] pub(crate) struct Captured; +#[derive(Debug, Component)] +pub(crate) struct Merged; + // manually for the type. impl std::fmt::Display for Piece { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { @@ -242,6 +245,7 @@ pub(crate) struct Move { pub epoch: usize, pub from: BoardIndex, pub to: Option, + pub move_type: MoveType, } /// 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 { Valid, + #[default] Invalid, Capture, - Merge, + Merge(Piece), } #[derive(Debug, Component, PartialEq, Clone, Copy, Eq, Hash, Default)] @@ -367,10 +372,15 @@ impl Board { fn new() -> Board { Board::from_ascii( - r#".....dqq - dpp..pdq - qdp..ppd - qqd....."#, + // r#".....dqq + // dpp..pdq + // qdp..ppd + // qqd....."#, + + r#"........ + ..p.p... + ...p.... + ........"#, ) } @@ -429,38 +439,44 @@ impl Board { } else { match self.at(from) { Some(from_piece) => { - // Check if this is a valid move for this piece - if self.valid_moves(from).contains(&to) { - // The current epoch is the last epoch + 1 - let epoch = self.current_epoch(); + let move_type = self.move_type(from, to); + match move_type { + MoveType::Invalid => { + 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 - let mut moves = vec![]; + // If the position we are moving to is occupied, capture the removal in the ledger + 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 - if self.inner[to.y][to.x].is_some() { + // Capture the intended move in the moves ledger moves.push(Move { epoch, - from: to, - to: None, + from, + to: Some(to), + move_type: move_type.clone(), }); - } - // Capture the intended move in the moves ledger - moves.push(Move { - epoch, - from, - to: Some(to), - }); + self.inner[to.y][to.x] = Some(*from_piece); + self.inner[from.y][from.x] = None; - self.inner[to.y][to.x] = Some(*from_piece); - self.inner[from.y][from.x] = None; + self.moves.extend(moves.clone()); - self.moves.extend(moves.clone()); - - Ok(moves) - } else { - Err(GameError::InvalidMove) + Ok(moves) + } } } None => Err(GameError::NullMove), @@ -512,8 +528,10 @@ impl Board { &self, from: BoardIndex, to: BoardIndex, - ) -> Option { - self.line(from, to).all(|board_index| self.at(board_index).is_none()).then(|| { + ) -> MoveType { + self.line(from, to) + .all(|board_index| self.at(board_index).is_none()) + .then(|| { self.at(from).map(|piece| { // Given that the side does not have a queen||drone // And the piece is a drone||pawn @@ -541,10 +559,10 @@ impl Board { Some(to_piece) => { match (piece, to_piece) { (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) => { - (!side_has_queen).then_some(MoveType::Merge) + (!side_has_queen).then_some(MoveType::Merge(Piece::Queen)) }, _ => { 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. @@ -591,8 +609,8 @@ impl Board { // Get the move type (or none if totally invalid) let result = self.move_type(current_board_index, *move_index); match result { - None | Some(MoveType::Invalid) => None, - Some(MoveType::Capture) | Some(MoveType::Merge) | Some(MoveType::Valid) => { + MoveType::Invalid => None, + MoveType::Capture | MoveType::Merge(..) | MoveType::Valid => { Some(*move_index) }, } @@ -751,7 +769,7 @@ mod test { assert_eq!(expected, given, "Pawn can merge to make a drone"); 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 @@ -892,20 +910,17 @@ mod test { let actual = board.valid_moves((3, 1).into()); assert_eq!(expected, actual); - // Merging drone and pawn to make a queen 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()); - 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()); - 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()); - 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 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 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 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 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>, mut next_state: ResMut>, ) { - 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)| { + // If the current index is the 'from' for the move + // All moves cover From -> To (captures and merges have to: None) if *index == *from { match to { + // If we are moving on the board... Some(to_idx) => { info!("Moving piece {:?} {:?} -> {:?}", entity, from, to_idx); + // Update the piece's index *index = *to_idx; + // Play audio sfx if !(*played) { audio_events.send(audio::AudioEvent::PutDown); audio_events.send(audio::AudioEvent::StopIdle); *played = true; - if *from != *to_idx { - let ns = !*curr_state.get(); - info!("Piece moved, switching sides: {:?}", ns); - next_state.set(ns); + } + if *from != *to_idx { + match move_type { + 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 => { - info!("Capturing piece {:?}", entity); - commands - .entity(entity) - .remove::() - .insert(Captured); + match move_type { + MoveType::Capture => { + info!("Capturing piece {:?}", entity); + commands + .entity(entity) + .remove::() + .insert(Captured); + }, + MoveType::Merge(..) => { + commands + .entity(entity) + .remove::() + .insert(Merged); + }, + _ => { + panic!("How did you do this!?"); + } + } } } }