Skip to content

Commit

Permalink
Started outlining the CMBR standard
Browse files Browse the repository at this point in the history
  • Loading branch information
datawater committed Jun 28, 2024
1 parent c167ed6 commit 9c0f7a8
Show file tree
Hide file tree
Showing 9 changed files with 279 additions and 26 deletions.
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,9 @@ mkramdisk
*.data
*.perf
log.log
ast.rs_
ast.rs_
*.aux
*.dvi
*.log
*.out
*.synctex
11 changes: 4 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ litemap = "0.7.3"
memmap2 = "0.9.4"
pgn-lexer = { git = "https://github.com/datawater/pgn-lexer" }

[features]
safe_u24 = []

[profile.release]
opt-level = 3
strip = true
debug-assertions = false
overflow-checks = false
lto = "fat"
incremental = true
codegen-units = 1
Expand All @@ -24,11 +25,7 @@ opt-level = 1
lto = "thin"
incremental = true
codegen-units = 2048

[profile.bolt]
inherits = "release"
strip = false
debug = true
split-debuginfo = "unpacked"

[profile.profile]
inherits = "release"
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ or
cargo run -- help
```

### Documentation
The documentation (WIP/Unfinished) is provided as a latex and [pdf](./docs/CMBR.pdf) file

### License
The software is distributed under the GPL-3.0 License

Expand Down
Binary file added docs/CMBR.pdf
Binary file not shown.
110 changes: 110 additions & 0 deletions docs/CMBR.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
\documentclass{article}
\usepackage{graphicx}
\usepackage{hyperref}
\usepackage{amsmath}
\usepackage{array}

\title{CMBR Docs}
\author{datawizard}
\date{Specification Version 0.0.1}

\begin{document}

\maketitle

\section{Definitions}
u24 - 24 bit unsigned integer \\
u8 - 8 bit unsigned integer \\
NAG - Numerical annotation glyph. See \href{https://w.wiki/AWUT}{Wikipedia} for more information. \\
Variation table - A table that denotes \\

\section{Move notation}
The move is represented with an u24 (First part) with an additional u8 (Second part) if needed for NAG notation.
\subsection{First part}
\begin{equation}
0\text{b}\underbrace{000000}_\text{To square} \underbrace{000000}_\text{From square}
\underbrace{0000}_\text{Piece}\underbrace{00000000}_\text{Flags}
\end{equation}

To and from squares are defined as an index of a chessboard square. The values are between 0-63. Where 0 is 'a1' and 63 is 'h8'.
\par Pieces value represent some piece. See the table for more info
\par The flags are defined as individual values. They're bit-wise anded (\&) together to get the final value.

\begin{center}
\begin{tabular}{|c|c|c|}
\hline
\multicolumn{3}{|c|}{CMBR Flag enumeration} \\
\hline
Flag name & Binary value & Note \\
\hline
FlagNone & 0b00000000 & Empty flag \\
\hline
FlagCheck & 0b00000001 & Move is a check \\
\hline
FlagMate & 0b00000010 & Move is a checkmate \\
\hline
FlagCapture & 0b00000100 & Move is a capture \\
\hline
FlagNag & 0b00001000 & The next 8 bits in the file \\
& & are an u8 denoting the NAG value \\
\hline
FlagPromotesBishop & 0b01000000 & Move promotes to bishop \\
\hline
FlagPromotesKnight & 0b01010000 & Move promotes to knight \\
\hline
FlagPromotesRook & 0b01100000 & Move promotes to rook \\
\hline
FlagPromotesQueen & 0b01110000 & Move promotes to queen \\
\hline
FlagPromotesQueen & 0b01110000 & Move promotes to queen \\
\hline
FlagIsVariationPointeromotesQueen & 0b10000000 & If this flag is set \\
& & The first 16 bits are replaced \\
& & with an index to the variations table \\
\hline
\end{tabular}
\end{center}

\begin{center}
\begin{tabular}{ |c|c| }
\hline
\multicolumn{2}{|c|}{Pieces to binary value table} \\
\hline
Piece & Binary value \\
\hline
White pawn & 0b0000 \\
\hline
White knight & 0b0001 \\
\hline
White bishop & 0b0010 \\
\hline
White rook & 0b0011 \\
\hline
White queen & 0b0100 \\
\hline
White king & 0b0101 \\
\hline
White castles short & 0b0110 \\
\hline
White castles long & 0b0111 \\
\hline
Black pawn & 0b1000 \\
\hline
Black knight & 0b1001 \\
\hline
Black bishop & 0b1010 \\
\hline
Black rook & 010011 \\
\hline
Black queen & 0b1100 \\
\hline
Black king & 0b1101 \\
\hline
Black castles short & 0b1110 \\
\hline
Black castles long & 0b1111 \\
\hline
\end{tabular}
\end{center}

\end{document}
40 changes: 40 additions & 0 deletions src/cmbr/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
mod u24_impl;
pub use u24_impl::*;

// Macro stolen from https://stackoverflow.com/a/62759540
macro_rules! def_enum {
($vis:vis $name:ident => $ty:ty {
$($variant:ident => $val:expr),+
$(,)?
}) => {
#[non_exhaustive]
$vis struct $name;

impl $name {
$(
pub const $variant: $ty = $val;
)+

pub const VARIANTS: &'static [$ty] = &[$(Self::$variant),+];
}
};
}

def_enum! (pub CmbrFlags => u8{
FlagNone => 0,
FlagCheck => 1 << 0,
FlagMate => 1 << 1,
FlagCapture => 1 << 2,
FlagNag => 1 << 3, // Next 8 bits are a NAG index (https://w.wiki/AWUT)

FlagPromotesBishop => (1 << 6) | 0b000000,
FlagPromotesKnight => (1 << 6) | 0b010000,
FlagPromotesRook => (1 << 6) | 0b100000,
FlagPromotesQueen => (1 << 6) | 0b110000,

FlagIsVariationPointer => 1 << 7 // First 8 bits are Index to the table of variations
});

pub type Cmbr = (u24, Option<u8>);

// fn san_to_cmbr(san: &[u8])
103 changes: 103 additions & 0 deletions src/cmbr/u24_impl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Not, Rem, Shl, Shr, Sub};
use std::ops::{
AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, DivAssign, MulAssign, RemAssign, ShlAssign,
ShrAssign, SubAssign,
};

#[derive(Copy, Clone, Debug, Default)]
#[allow(non_camel_case_types)]
pub struct u24([u8; 3]);

impl u24 {
fn to_u32(self) -> u32 {
let u24([a, b, c]) = self;

return u32::from_le_bytes([a, b, c, 0]);
}

fn from_u32(n: u32) -> Self {
let [a, b, c, _d] = n.to_le_bytes();

#[cfg(feature = "safe_u24")]
debug_assert!(_d == 0);
return u24([a, b, c]);
}
}

macro_rules! impl_op_rhs {
($trait:ident, $fn:ident, $op:tt, $type:ty) => {
impl $trait for $type {
type Output = Self;

#[inline(always)]
fn $fn(self, rhs: Self) -> Self {
return Self::from_u32(self.to_u32() $op rhs.to_u32());
}
}
};
}

macro_rules! impl_op_rhs_assign {
($trait:ident, $fn:ident, $op:tt, $type:ty) => {
impl $trait for $type {
#[inline(always)]
fn $fn(&mut self, rhs: Self) {
*self = Self::from_u32(self.to_u32() $op rhs.to_u32())
}
}
};
}

macro_rules! impl_op_single {
($trait:ident, $fn:ident, $op:tt, $type:ty) => {
impl $trait for $type {
type Output = Self;

#[inline(always)]
fn $fn(self) -> Self {
return Self::from_u32($op self.to_u32());
}
}
};
}

impl_op_rhs!(Add, add, +, u24);
impl_op_rhs!(Sub, sub, -, u24);
impl_op_rhs!(Mul, mul, *, u24);
impl_op_rhs!(Div, div, /, u24);
impl_op_rhs!(Rem, rem, %, u24);
impl_op_rhs!(Shr, shr, >>, u24);
impl_op_rhs!(Shl, shl, <<, u24);
impl_op_rhs!(BitAnd, bitand, &, u24);
impl_op_rhs!(BitOr, bitor, |, u24);
impl_op_rhs!(BitXor, bitxor, ^, u24);

impl_op_single!(Not, not, !, u24);

impl_op_rhs_assign!(AddAssign, add_assign, +, u24);
impl_op_rhs_assign!(SubAssign, sub_assign, -, u24);
impl_op_rhs_assign!(MulAssign, mul_assign, *, u24);
impl_op_rhs_assign!(DivAssign, div_assign, /, u24);
impl_op_rhs_assign!(RemAssign, rem_assign, %, u24);
impl_op_rhs_assign!(ShrAssign, shr_assign, >>, u24);
impl_op_rhs_assign!(ShlAssign, shl_assign, <<, u24);
impl_op_rhs_assign!(BitAndAssign, bitand_assign, &, u24);
impl_op_rhs_assign!(BitOrAssign, bitor_assign, |, u24);
impl_op_rhs_assign!(BitXorAssign, bitxor_assign, ^, u24);

impl u24 {
#[inline(always)]
pub fn count_ones(self) -> u32 {
return self.to_u32().count_ones();
}

#[inline(always)]
pub fn count_zeros(self) -> u32 {
return 24 - self.count_ones();
}

#[inline(always)]
pub fn trailing_zeroes(self) -> u32 {
return self.to_u32().trailing_zeros() - 8;
}
}
2 changes: 2 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// TODO: Define and Write documentation for the CMBR Standard.
// TODO: Seperate the cli and libcmbr
#![feature(test)]
#![allow(non_upper_case_globals)]

mod cmbr;
mod eval_args;
mod pgn;
mod tests;
Expand Down
Loading

0 comments on commit 9c0f7a8

Please sign in to comment.