use std::convert::From;
use shakmaty::{uci::Uci, Chess, Color, Position, Rank, Role, Square};
#[derive(Copy, Clone, Debug)]
pub struct ObkMoveEntry {
pub key: u64,
pub is_last_in_variation: bool,
pub is_last_at_level: bool,
pub from_rank: u8,
pub from_file: u8,
pub weight: u8,
pub to_rank: u8,
pub to_file: u8,
}
pub struct ObkNoteEntry {
pub move_number: u32,
pub note_length: u8,
pub note_type: u8,
pub note_text: String,
}
impl From<ObkMoveEntry> for Uci {
fn from(obk_move: ObkMoveEntry) -> Self {
let from = Square::from_coords(
shakmaty::File::new(u32::from(obk_move.from_file)),
shakmaty::Rank::new(u32::from(obk_move.from_rank)),
);
let to = Square::from_coords(
shakmaty::File::new(u32::from(obk_move.to_file)),
shakmaty::Rank::new(u32::from(obk_move.to_rank)),
);
Uci::Normal {
from,
to,
promotion: None,
}
}
}
pub fn uci_from_obk_move_and_position(obk_move: ObkMoveEntry, pos: &Chess) -> Uci {
let from = Square::from_coords(
shakmaty::File::new(u32::from(obk_move.from_file)),
shakmaty::Rank::new(u32::from(obk_move.from_rank)),
);
let to = Square::from_coords(
shakmaty::File::new(u32::from(obk_move.to_file)),
shakmaty::Rank::new(u32::from(obk_move.to_rank)),
);
let piece_at_from = pos
.board()
.piece_at(from)
.expect("No piece on 'from' square");
let promotion = if piece_at_from.role == Role::Pawn
&& ((piece_at_from.color == Color::White && to.rank() == Rank::Eighth)
|| (piece_at_from.color == Color::Black && to.rank() == Rank::First))
{
Some(Role::Queen)
} else {
None
};
Uci::Normal {
from,
to,
promotion,
}
}
impl ObkMoveEntry {
pub fn from_bytes(bytes: [u8; 2], key: u64) -> Self {
let byte1 = bytes[0];
let byte2 = bytes[1];
let from_file = byte1 & 0b111;
let from_rank = (byte1 >> 3) & 0b111;
let to_file = byte2 & 0b111;
let to_rank = (byte2 >> 3) & 0b111;
let weight = match (byte2 >> 6) & 0x03 {
0 => 1,
1 => 25,
2 => 50,
3 => 100,
_ => 1,
};
ObkMoveEntry {
key,
weight,
from_rank,
from_file,
to_rank,
to_file,
is_last_in_variation: (byte1 & 0x80) != 0,
is_last_at_level: (byte1 & 0x40) != 0,
}
}
}