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)]
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<BoardIndex>,
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<MoveType> {
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<State<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)| {
// 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::<BoardIndex>()
.insert(Captured);
match move_type {
MoveType::Capture => {
info!("Capturing piece {:?}", entity);
commands
.entity(entity)
.remove::<BoardIndex>()
.insert(Captured);
},
MoveType::Merge(..) => {
commands
.entity(entity)
.remove::<BoardIndex>()
.insert(Merged);
},
_ => {
panic!("How did you do this!?");
}
}
}
}
}

Loading…
Cancel
Save