|
|
|
@ -94,7 +94,7 @@ impl std::fmt::Display for Piece {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub(crate) enum GameError {
|
|
|
|
pub(crate) enum GameError {
|
|
|
|
NullMove,
|
|
|
|
NullMove,
|
|
|
|
InvalidIndex,
|
|
|
|
InvalidIndex,
|
|
|
|
@ -169,7 +169,7 @@ impl Board {
|
|
|
|
match self.at(from.clone()) {
|
|
|
|
match self.at(from.clone()) {
|
|
|
|
Some(from_piece) => {
|
|
|
|
Some(from_piece) => {
|
|
|
|
// Check if this is a valid move for this piece
|
|
|
|
// Check if this is a valid move for this piece
|
|
|
|
if self.possible_moves(from).contains(&to) {
|
|
|
|
if self.valid_moves(from).contains(&to) {
|
|
|
|
// The current epoch is the last epoch + 1
|
|
|
|
// The current epoch is the last epoch + 1
|
|
|
|
let epoch = self.current_epoch();
|
|
|
|
let epoch = self.current_epoch();
|
|
|
|
|
|
|
|
|
|
|
|
@ -218,11 +218,38 @@ impl Board {
|
|
|
|
|
|
|
|
|
|
|
|
/// Returns the possible moves the piece at this tile can make.
|
|
|
|
/// Returns the possible moves the piece at this tile can make.
|
|
|
|
/// !!TODO: exclude pieces on your own side!!
|
|
|
|
/// !!TODO: exclude pieces on your own side!!
|
|
|
|
pub(crate) fn possible_moves(&self, BoardIndex { x, y }: BoardIndex) -> HashSet<BoardIndex> {
|
|
|
|
pub(crate) fn valid_moves(&self, BoardIndex { x, y }: BoardIndex) -> HashSet<BoardIndex> {
|
|
|
|
let f = |(a, b): (Option<usize>, Option<usize>)| {
|
|
|
|
let f = |(a, b): (Option<usize>, Option<usize>)| {
|
|
|
|
if let (Some(x), Some(y)) = (a, b) {
|
|
|
|
if let (Some(this_x), Some(this_y)) = (a, b) {
|
|
|
|
if (0..=7).contains(&x) && (0..=3).contains(&y) {
|
|
|
|
// This has a valid x position
|
|
|
|
Some(BoardIndex { x, y })
|
|
|
|
let valid_x = (0..=7).contains(&this_x);
|
|
|
|
|
|
|
|
if valid_x {
|
|
|
|
|
|
|
|
// It has a valid y position
|
|
|
|
|
|
|
|
let valid_y = (0..=3).contains(&this_y);
|
|
|
|
|
|
|
|
if valid_y {
|
|
|
|
|
|
|
|
// The checked board index
|
|
|
|
|
|
|
|
let this_board_index = BoardIndex {
|
|
|
|
|
|
|
|
x: this_x,
|
|
|
|
|
|
|
|
y: this_y,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
// Only propose tiles that are empty or capture a piece on the other side
|
|
|
|
|
|
|
|
let valid_capture = {
|
|
|
|
|
|
|
|
match self.at(this_board_index) {
|
|
|
|
|
|
|
|
Some(_) => {
|
|
|
|
|
|
|
|
let same_side = Board::side(BoardIndex { x, y });
|
|
|
|
|
|
|
|
Board::side(this_board_index) != same_side
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
None => true,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
if valid_capture {
|
|
|
|
|
|
|
|
Some(this_board_index)
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
None
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
None
|
|
|
|
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|