|
|
|
|
@ -29,7 +29,7 @@ impl Plugin for GamePlugin {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Component, Clone, PartialEq)]
|
|
|
|
|
#[derive(Debug, Component, Clone, PartialEq, Copy)]
|
|
|
|
|
pub(crate) enum Piece {
|
|
|
|
|
Pawn,
|
|
|
|
|
Drone,
|
|
|
|
|
@ -110,7 +110,7 @@ pub(crate) struct Move {
|
|
|
|
|
pub to: Option<BoardIndex>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Component, PartialEq, Clone, Default)]
|
|
|
|
|
#[derive(Debug, Component, PartialEq, Clone, Default, Copy)]
|
|
|
|
|
pub(crate) struct BoardIndex {
|
|
|
|
|
pub x: usize,
|
|
|
|
|
pub y: usize,
|
|
|
|
|
@ -124,8 +124,8 @@ pub(crate) enum Side {
|
|
|
|
|
|
|
|
|
|
impl Board {
|
|
|
|
|
/// Returns the piece at the given location
|
|
|
|
|
pub(crate) fn at(&self, BoardIndex { x, y }: &BoardIndex) -> Option<Piece> {
|
|
|
|
|
self.inner[*y][*x].clone()
|
|
|
|
|
pub(crate) fn at(&self, BoardIndex { x, y }: BoardIndex) -> Option<&Piece> {
|
|
|
|
|
self.inner[y][x].as_ref()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns a list of all pieces on the board with their location
|
|
|
|
|
@ -141,15 +141,17 @@ impl Board {
|
|
|
|
|
.collect()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Moves a piece from -> to
|
|
|
|
|
pub(crate) fn move_piece(
|
|
|
|
|
&mut self,
|
|
|
|
|
from: &BoardIndex,
|
|
|
|
|
to: &BoardIndex,
|
|
|
|
|
from: BoardIndex,
|
|
|
|
|
to: BoardIndex,
|
|
|
|
|
) -> Result<Vec<Move>, GameError> {
|
|
|
|
|
if from == to {
|
|
|
|
|
Err(GameError::NullMove)
|
|
|
|
|
} else {
|
|
|
|
|
self.at(from).map_or(Err(GameError::NullMove), |from_val| {
|
|
|
|
|
match self.at(from.clone()) {
|
|
|
|
|
Some(from_val) => {
|
|
|
|
|
// The current epoch is the last epoch + 1
|
|
|
|
|
let epoch = self.moves.last().unwrap_or(&Move { ..default() }).epoch + 1;
|
|
|
|
|
|
|
|
|
|
@ -172,23 +174,48 @@ impl Board {
|
|
|
|
|
to: Some(to.clone()),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
self.moves.extend(moves.clone());
|
|
|
|
|
|
|
|
|
|
self.inner[to.y][to.x] = Some(from_val);
|
|
|
|
|
self.inner[to.y][to.x] = Some(*from_val);
|
|
|
|
|
self.inner[from.y][from.x] = None;
|
|
|
|
|
|
|
|
|
|
self.moves.extend(moves.clone());
|
|
|
|
|
|
|
|
|
|
Ok(moves)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
None => Err(GameError::NullMove),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) fn side(&BoardIndex { x, .. }: &BoardIndex) -> Result<Side, GameError> {
|
|
|
|
|
/// Returns the Side of a piece
|
|
|
|
|
pub(crate) fn side(BoardIndex { x, .. }: BoardIndex) -> Result<Side, GameError> {
|
|
|
|
|
match x {
|
|
|
|
|
0..=3 => Ok(Side::A),
|
|
|
|
|
4..=7 => Ok(Side::B),
|
|
|
|
|
_ => Err(GameError::InvalidIndex),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns the possible moves the piece at this tile can make.
|
|
|
|
|
pub(crate) fn possible_moves(&self, BoardIndex { x, y }: BoardIndex) -> Vec<BoardIndex> {
|
|
|
|
|
match self.at(BoardIndex { x, y }) {
|
|
|
|
|
// One space in any diagonal
|
|
|
|
|
Some(Piece::Pawn) => {
|
|
|
|
|
self.at(BoardIndex { x: x + 1, y });
|
|
|
|
|
vec![]
|
|
|
|
|
}
|
|
|
|
|
// One or two spaces in either horizontal
|
|
|
|
|
Some(Piece::Drone) => {
|
|
|
|
|
todo!("Where can a drone move?");
|
|
|
|
|
vec![]
|
|
|
|
|
}
|
|
|
|
|
// Any distance in any straight line
|
|
|
|
|
Some(Piece::Queen) => {
|
|
|
|
|
todo!("Where can a queen move?");
|
|
|
|
|
vec![]
|
|
|
|
|
}
|
|
|
|
|
None => Vec::new(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl std::fmt::Display for Board {
|
|
|
|
|
@ -308,7 +335,7 @@ pub(crate) fn update_board(
|
|
|
|
|
pub(crate) fn set_side(mut events: Query<(&mut Side, &BoardIndex), Changed<BoardIndex>>) {
|
|
|
|
|
events
|
|
|
|
|
.iter_mut()
|
|
|
|
|
.for_each(|(mut side, idx)| match Board::side(idx) {
|
|
|
|
|
.for_each(|(mut side, idx)| match Board::side(*idx) {
|
|
|
|
|
Ok(s) => {
|
|
|
|
|
debug!("Set side event {:?} {:?} -> {:?}", idx, side, s);
|
|
|
|
|
if *side != s {
|
|
|
|
|
@ -372,7 +399,7 @@ fn move_piece(
|
|
|
|
|
events.iter().for_each(|(tile, to)| {
|
|
|
|
|
selected_pieces.iter().for_each(|from| {
|
|
|
|
|
// Move piece
|
|
|
|
|
match board.move_piece(from, to) {
|
|
|
|
|
match board.move_piece(*from, *to) {
|
|
|
|
|
Ok(moves) => {
|
|
|
|
|
// De-select the piece
|
|
|
|
|
info!("Applying moves {:?}", moves);
|
|
|
|
|
|