Skip to content

Commit

Permalink
Fix material difference (#86)
Browse files Browse the repository at this point in the history
* Add reset the game/ go to the menu by pressing a key

* Material difference

---------

Signed-off-by: Thomas Mauran <[email protected]>
Co-authored-by: Thomas Mauran <[email protected]>
  • Loading branch information
infernosalex and thomas-mauran authored Nov 12, 2024
1 parent d6247ec commit 4f2914a
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ impl App {
}
}

pub fn go_to_home(&mut self) {
self.current_page = Pages::Home;
self.board = Board::default();
}

/// Handles the tick event of the terminal.
pub fn tick(&self) {}

Expand Down
94 changes: 94 additions & 0 deletions src/board.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ pub struct Board {
pub engine: Option<Engine>,
pub is_game_against_bot: bool,
pub display_mode: DisplayMode,

pub white_taken_pieces: Vec<PieceType>,
pub black_taken_pieces: Vec<PieceType>,
}

impl Default for Board {
Expand Down Expand Up @@ -180,6 +183,8 @@ impl Default for Board {
engine: None,
is_game_against_bot: false,
display_mode: DisplayMode::DEFAULT,
white_taken_pieces: vec![],
black_taken_pieces: vec![],
}
}
}
Expand All @@ -202,6 +207,8 @@ impl Board {
engine: None,
is_game_against_bot: false,
display_mode: DisplayMode::DEFAULT,
white_taken_pieces: vec![],
black_taken_pieces: vec![],
}
}

Expand Down Expand Up @@ -600,6 +607,26 @@ impl Board {
}
}

// We check if the move is a capture and add the piece to the taken pieces
match (piece_type_from, piece_type_to) {
(_, None) => {}
(_, Some(piece)) => {
let piece_color = get_piece_color(self.board, to);
if let Some(piece_color) = piece_color {
match piece_color {
PieceColor::Black => {
self.white_taken_pieces.push(piece);
self.white_taken_pieces.sort();
}
PieceColor::White => {
self.black_taken_pieces.push(piece);
self.black_taken_pieces.sort();
}
}
}
}
}

// We check for en passant as the latest move
if self.is_latest_move_en_passant(*from, *to) {
// we kill the pawn
Expand Down Expand Up @@ -950,7 +977,40 @@ impl Board {
history_paragraph,
history_block.inner(right_panel_layout[0]),
);
}

pub fn white_material_render(&self, area: Rect, frame: &mut Frame) {
let white_block = Block::default()
.title("White material")
.borders(Borders::ALL)
.border_style(Style::default().fg(WHITE))
.border_type(BorderType::Rounded);

let mut pieces: String = String::new();

for i in 0..self.white_taken_pieces.len() {
let utf_icon_white =
PieceType::piece_to_utf_enum(self.white_taken_pieces[i], Some(PieceColor::Black));

pieces.push_str(&format!("{utf_icon_white} "));
}

let white_material_paragraph = Paragraph::new(pieces)
.alignment(Alignment::Center)
.add_modifier(Modifier::BOLD);

let height = area.height;

let right_panel_layout = Layout::default()
.direction(Direction::Vertical)
.constraints([Constraint::Length(height - 1), Constraint::Length(1)].as_ref())
.split(area);

frame.render_widget(white_block.clone(), right_panel_layout[0]);
frame.render_widget(
white_material_paragraph,
white_block.inner(right_panel_layout[0]),
);
// Bottom paragraph help text
let text = vec![Line::from("Press ? for help").alignment(Alignment::Center)];

Expand All @@ -959,6 +1019,40 @@ impl Board {
.alignment(Alignment::Center);
frame.render_widget(help_paragraph, right_panel_layout[1]);
}

pub fn black_material_render(&self, area: Rect, frame: &mut Frame) {
let black_block = Block::default()
.title("Black material")
.borders(Borders::ALL)
.border_style(Style::default().fg(WHITE))
.border_type(BorderType::Rounded);

let mut pieces: String = String::new();

for i in 0..self.black_taken_pieces.len() {
let utf_icon_black =
PieceType::piece_to_utf_enum(self.black_taken_pieces[i], Some(PieceColor::White));

pieces.push_str(&format!("{utf_icon_black} "));
}

let black_material_paragraph = Paragraph::new(pieces)
.alignment(Alignment::Center)
.add_modifier(Modifier::BOLD);

let height = area.height;

let right_panel_layout = Layout::default()
.direction(Direction::Vertical)
.constraints([Constraint::Length(height - 1), Constraint::Length(1)].as_ref())
.split(area);

frame.render_widget(black_block.clone(), right_panel_layout[0]);
frame.render_widget(
black_material_paragraph,
black_block.inner(right_panel_layout[0]),
);
}
}

#[cfg(test)]
Expand Down
3 changes: 3 additions & 0 deletions src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
}
app.board.unselect_cell();
}
KeyCode::Char('b') => {
app.go_to_home();
}
// Other handlers you could add here.
_ => {}
}
Expand Down
32 changes: 32 additions & 0 deletions src/pieces/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::cmp::Ordering;

use crate::board::{Coord, GameBoard};

use self::{bishop::Bishop, king::King, knight::Knight, pawn::Pawn, queen::Queen, rook::Rook};
Expand Down Expand Up @@ -150,6 +152,36 @@ impl PieceType {
}
}

// Implementing the PartialOrd trait for PieceType to allow comparison between PieceType
#[allow(clippy::non_canonical_partial_ord_impl)]
impl PartialOrd for PieceType {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
if self == other {
return Some(Ordering::Equal);
}
match (self, other) {
(PieceType::Pawn, _) => Some(Ordering::Less),
(PieceType::Queen, _) => Some(Ordering::Greater),
(_, PieceType::Pawn) => Some(Ordering::Greater),
(_, PieceType::Queen) => Some(Ordering::Less),
(PieceType::Rook, PieceType::Bishop) => Some(Ordering::Greater),
(PieceType::Rook, PieceType::Knight) => Some(Ordering::Greater),
(PieceType::Bishop, PieceType::Knight) => Some(Ordering::Greater), // just for visual purpose
(PieceType::Bishop, PieceType::Rook) => Some(Ordering::Less),
(PieceType::Knight, PieceType::Rook) => Some(Ordering::Less),
(PieceType::Knight, PieceType::Bishop) => Some(Ordering::Less), // just for visual purpose
_ => Some(Ordering::Equal),
}
}
}
impl Ord for PieceType {
fn cmp(&self, other: &Self) -> Ordering {
self.partial_cmp(other).unwrap()
}
}

impl Eq for PieceType {}

#[derive(Debug, Copy, Clone, PartialEq)]
pub struct PieceMove {
pub piece_type: PieceType,
Expand Down
2 changes: 2 additions & 0 deletions src/popups.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ pub fn render_help_popup(frame: &mut Frame) {
Line::from(""),
Line::from("q: Quit the game"),
Line::from(""),
Line::from("b: Go to the home menu / reset the game"),
Line::from(""),
Line::from(""),
Line::from("Color codes:".underlined().bold()),
Line::from(""),
Expand Down
21 changes: 20 additions & 1 deletion src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,17 @@ pub fn render_game_ui(frame: &mut Frame, app: &App, main_area: Rect) {
)
.split(main_layout_horizontal[1]);

let right_box_layout = Layout::default()
.direction(Direction::Vertical)
.constraints(
[
Constraint::Ratio(2, 15),
Constraint::Ratio(11, 15),
Constraint::Ratio(2, 15),
]
.as_ref(),
)
.split(main_layout_vertical[3]);
// Board block representing the full board div
let board_block = Block::default().style(Style::default());

Expand All @@ -170,9 +181,17 @@ pub fn render_game_ui(frame: &mut Frame, app: &App, main_area: Rect) {
app.board
.board_render(board_block.inner(main_layout_vertical[1]), frame);

//top box for white material
app.board
.black_material_render(board_block.inner(right_box_layout[0]), frame);

// We make the inside of the board
app.board
.history_render(board_block.inner(main_layout_vertical[3]), frame);
.history_render(board_block.inner(right_box_layout[1]), frame);

//bottom box for black matetrial
app.board
.white_material_render(board_block.inner(right_box_layout[2]), frame);

if app.board.is_promotion {
render_promotion_popup(frame, app);
Expand Down

0 comments on commit 4f2914a

Please sign in to comment.