chess_game 0.2.0

Simple Chess game
Documentation
use std::process::Command;
use std::thread::sleep;
use std::time::Duration;
use std::fmt::Write;
use method_shorthands::methods::*;
use chess::*;

use crate::color::Opposite;
use crate::game::ui_settings::UISettings;
use crate::{piece::Name, square::IsBackRank};
use crate::gui::*;

pub fn handle_turn(board: Board, m: ChessMove, ui_settings: UISettings) -> Result<Board, &'static str> {
    if board.legal(m) == false { return Err("Illegal move."); }

    if ui_settings.cls { Command::new("clear").spawn().uw(); sleep(Duration::from_millis(10)); }
    if ui_settings.view_board_display { display_board(board.make_move_new(m), ui_settings); }
    if ui_settings.view_move { println!("{}", m.to_string().to_uppercase()) }
    if ui_settings.view_move_desc { describe_move(board, m) };

    if insufficient_material_stalemate(board.make_move_new(m)) { return Err("insuff mat"); }
    
    Ok(board.make_move_new(m))
}

fn insufficient_material_stalemate(board: Board) -> bool {
    if *board.pieces(Piece::Rook) != EMPTY { return false; }
    if *board.pieces(Piece::Pawn) != EMPTY { return false; }
    if *board.pieces(Piece::Queen) != EMPTY { return false; }
    if board.pieces(Piece::Bishop).count() > 1 { return false; }
    if board.pieces(Piece::Knight).count() > 2 { return false; }
    if *board.pieces(Piece::Bishop) != EMPTY && *board.pieces(Piece::Knight) != EMPTY { return false; }

    true
}

pub fn describe_move(board: Board, m: ChessMove) {
    let temp_board = board.make_move_new(m);
    let color = board.side_to_move();

    let king_square = board.king_square(board.side_to_move());
    let post_move_king_square = temp_board.king_square(board.side_to_move());
    if king_square.get_file() == File::E {
        if post_move_king_square.get_file() == File::C {
            println!("{:?} castled Queen side.", color);
            return;
        }
        else if post_move_king_square.get_file() == File::G {
            println!("{:?} castled King side.", color);
            return;
        }
    }

    let mut desc = String::new();
    let source = m.get_source().to_string().to_uppercase();
    let dest = m.get_dest();
    let piece = board.piece_on(m.get_source()).uw();

    write!(desc, "{:?} moved their {} from {} to {}", color, piece.name(), source, dest.to_string().to_uppercase()).uw();

    if let Some(capture_piece) = board.piece_on(m.get_dest()) {
        let color2 = color.opposite();
        write!(desc, ", capturing {:?}'s {}", color2, capture_piece.name()).uw();
    }
    if piece == Piece::Pawn && dest.is_back_rank() {
        let promo_piece = m.get_promotion().uw();
        write!(desc, ", promoting to a {}", promo_piece.name()).uw();
    }
    if *temp_board.checkers() != EMPTY {
        let color2 = color.opposite();
        write!(desc, ", checking {:?}'s King", color2).uw();
    }

    write!(desc, ".").uw();
    println!("{desc}");
}