fog-of-chess

[toy] Chess, but with the fog of war.
Log | Files | Refs

commit 516ee52526788de2e85db5951dc50921f67cef24
parent 860b21e4ba64b0d90d5c335ae3db466ba01bc921
Author: Jack Mordaunt <jackmordaunt@gmail.com>
Date:   Thu, 26 Dec 2019 13:34:41 +1300

Feat: Knight movement. Fix: Use i32 to allow for negative coords.

Diffstat:
Msrc/main.rs | 77++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
1 file changed, 56 insertions(+), 21 deletions(-)

diff --git a/src/main.rs b/src/main.rs @@ -49,14 +49,19 @@ impl EventHandler for Game { fn mouse_button_up_event(&mut self, _ctx: &mut Context, _b: MouseButton, x: f32, y: f32) { let (w, h) = (800.0, 600.0); let (w_size, h_size) = (w / 8.0, h / 8.0); - let (col, row) = ((x / w_size).floor() as u8, (y / h_size).floor() as u8); + let (col, row) = ((x / w_size).floor() as i32, (y / h_size).floor() as i32); // TODO: Sanity check. // TODO: Refactor out movement code. match self.board.0[row as usize][col as usize] { None => { if let Some((x, y)) = self.selected_piece { if self.moves().contains(&(col, row)) { - if let Some(Piece {unit, player, moved}) = self.board.0[y as usize][x as usize].take() { + if let Some(Piece { + unit, + player, + moved, + }) = self.board.0[y as usize][x as usize].take() + { self.board.0[row as usize][col as usize] = Some(Piece { unit: unit, player: player, @@ -70,7 +75,12 @@ impl EventHandler for Game { if self.contains_enemy((col, row)) { if let Some((x, y)) = self.selected_piece { if self.moves().contains(&(col, row)) { - if let Some(Piece {unit, player, moved}) = self.board.0[y as usize][x as usize].take() { + if let Some(Piece { + unit, + player, + moved, + }) = self.board.0[y as usize][x as usize].take() + { self.board.0[row as usize][col as usize] = Some(Piece { unit: unit, player: player, @@ -80,7 +90,7 @@ impl EventHandler for Game { } } } else { - self.selected_piece = Some((col as u8, row as u8)); + self.selected_piece = Some((col as i32, row as i32)); } } }; @@ -197,7 +207,7 @@ pub struct Board([[Option<Piece>; 8]; 8]); pub struct Game { pub board: Board, pub turn: Player, - pub selected_piece: Option<(u8, u8)>, + pub selected_piece: Option<(i32, i32)>, } impl Game { @@ -211,11 +221,15 @@ impl Game { } /// Moves calculates all valid moves for the currently selected piece. // TODO: Finish movement logic. - pub fn moves(&self) -> Vec<(u8, u8)> { + pub fn moves(&self) -> Vec<(i32, i32)> { use Unit::*; match self.selected_piece { Some((x, y)) => match &self.board.0[y as usize][x as usize] { - Some(Piece { unit, player, moved }) => match unit { + Some(Piece { + unit, + player, + moved, + }) => match unit { // Pawn can move in the direction of the player by 1 square. // For the first move, a pawn can move up to 2 squares. // Pawns can only attack diagonally in the direction of the @@ -262,6 +276,19 @@ impl Game { }; moves } + Knight => vec![ + (x + 2, y - 1), + (x + 2, y + 1), + (x - 2, y - 1), + (x - 2, y + 1), + (x + 1, y + 2), + (x - 1, y + 2), + (x + 1, y - 2), + (x - 1, y - 2), + ] + .into_iter() + .filter(|(x, y)| self.contains_ally((*x, *y))) + .collect(), // King can move to any adjacent cell that isn't occupied by // a piece of the same player. King => vec![ @@ -275,16 +302,7 @@ impl Game { (x, y - 1), ] .into_iter() - .filter(|(x, y)| { - if x - 1 < 7 && y - 1 < 7 { - match &self.board.0[*y as usize][*x as usize] { - Some(Piece { player: p, .. }) => player != p, - None => true, - } - } else { - false - } - }) + .filter(|(x, y)| self.contains_ally((*x, *y))) .collect(), _ => vec![], }, @@ -295,11 +313,28 @@ impl Game { } /// Contains enemy if the specified position is occupied by a piece owned /// by the other player. - pub fn contains_enemy(&self, pos: (u8, u8)) -> bool { + pub fn contains_enemy(&self, pos: (i32, i32)) -> bool { let (x, y) = pos; - match &self.board.0[y as usize][x as usize] { - Some(Piece { player, .. }) => *player != self.turn, - _ => false, + if x > -1 && y > -1 && x - 1 < 7 && y - 1 < 7 { + match &self.board.0[y as usize][x as usize] { + Some(Piece { player, .. }) => *player != self.turn, + _ => false, + } + } else { + false + } + } + /// Contains ally if the specified position is occupied by a piece owned by + /// the currently player. + pub fn contains_ally(&self, pos: (i32, i32)) -> bool { + let (x, y) = pos; + if x > -1 && y > -1 && x - 1 < 7 && y - 1 < 7 { + match &self.board.0[y as usize][x as usize] { + Some(Piece { player, .. }) => *player == self.turn, + None => true, + } + } else { + false } } }