Skip to content

Commit

Permalink
1.0.0 corrected
Browse files Browse the repository at this point in the history
  • Loading branch information
akanalytics committed Jul 22, 2024
1 parent 0f91567 commit 3098f53
Show file tree
Hide file tree
Showing 34 changed files with 765 additions and 801 deletions.
96 changes: 48 additions & 48 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ authors = [
"mark raistrick <[email protected]>",
]
rust-version = "1.78"
version = "0.9.0"
version = "1.0.0"
edition = "2021"
license = "AGPL-3.0 license"
description = "A UCI compliant chess engine"
Expand All @@ -24,55 +24,74 @@ categories = ["games"]
odonata-base = { path = "./crates/odonata-base" }
odonata-engine = { path = "./crates/odonata-engine" }

alphanumeric-sort = "1.4.4"
anyhow = { version = "1.0", features = ["backtrace"] }
append-only-vec = "0.1.3"
argmin = { version = "0.8" }
argmin-math = { version = "0.3", features = ["ndarray_latest-nolinalg-serde"] }
arrayvec = { version = "0.7", features = ["serde"] }
backtrace = "0.3.64"
bitflags = { version = "2.5.0", features = ["serde"] }
clap = { version = "4.5", features = ["derive"] }
once_cell = "1.19"
boxcar = "0.2"
byteorder = "1.5.0"
rand = "0.8"
rand_chacha = "0.3"
fs-err = "2.11"
regex = "1.4"
test-log = { version = "0.2", features = ["trace"] }
anyhow = { version = "1.0", features = ["backtrace"] }
backtrace = "0.3.64"
crossbeam-utils = "0.8"
chrono = { version = "0.4" }
clap = { version = "4.5", features = ["derive"] }
console = "0.15"
crossbeam-channel = "0.5"
crossbeam-queue = "0.3"
crossbeam-utils = "0.8"
ctrlc = "3.4"
daisychain = { version = "0.0.5" }
derive_more = "0.99"
format_num = "0.1"
fs-err = "2.11"
fslock = "0.2.1"
glob = "0.3"
hdrhist = "0.5.0"
include_dir = "0.7.2"
indexmap = { version = "2.2", features = ["serde"] }
indicatif = { version = "0.17", features = ["rayon"] }
itertools = "0.13"
liblinear = "1.0.0"
log = { version = "0.4", features = ["release_max_level_debug"] }
nalgebra = "0.32"
ndarray = { version = "0.15.6", features = ["rayon"] }
nom = "7.1.1"
nom-supreme = "0.8.0"
num-traits = "0.2"
once_cell = "1.19"
pariter = "0.5.1"
perf-event = "0.4.7"
petgraph = "0.6.0"
postcard = { version = "1.0.8", features = ["use-std"] }
pretty_assertions = "1.4.0"
rand = "0.8"
rand_chacha = "0.3"
rayon = "1.10"
regex = "1.4"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_with = "3.8"
serde_yaml = "0.9"
simba = "0.8.1"
static_init = "1.0"
statrs = "0.16.0"
strum = "0.26"
strum_macros = "0.26"
tabled = "0.15.0"
tabwriter = "1.4"
test-log = { version = "0.2", features = ["trace"] }
testresult = "0.4.0"
textplots = "0.8"
thread_local = "1.1.4"
timeout-readwrite = "0.3.2"
toml = { version = "0.8", features = ["display", "parse", "indexmap"] }
tabwriter = "1.4"
append-only-vec = "0.1.3"
daisychain = { version = "0.0.5" }
console = "0.15"
tracing-appender = "0.2.3"
url = "2.3.1"
wide = "0.7.22"
xshell = "0.2"
derive_more = "0.99"
pariter = "0.5.1"
fslock = "0.2.1"
rayon = "1.10"
timeout-readwrite = "0.3.2"
# serde_json = "1.0"
# serde_with = "1.9"
alphanumeric-sort = "1.4.4"
chrono = { version = "0.4" }
nom = "7.1.1"
nom-supreme = "0.8.0"
perf-event = "0.4.7"


plotters = { version = "0.3.4", default-features = false, features = [
"svg_backend",
"full_palette",
Expand All @@ -83,22 +102,7 @@ plotters = { version = "0.3.4", default-features = false, features = [
pprof = { git = "https://github.com/Erigara/pprof-rs.git", branch = "fix_pointer_align", features = [
"flamegraph",
] }
serde_yaml = "0.9"
# serde_regex = "1.1.0"
statrs = "0.16.0"
url = "2.3.1"
ctrlc = "3.4"
glob = "0.3"
# log = { version = "0.4", features = ["release_max_level_debug"] }
argmin = { version = "0.8" }
argmin-math = { version = "0.3", features = ["ndarray_latest-nolinalg-serde"] }
liblinear = "1.0.0"
nalgebra = "0.32"
ndarray = { version = "0.15.6", features = ["rayon"] }
indicatif = { version = "0.17", features = ["rayon"] }
textplots = "0.8"
boxcar = "0.2"
postcard = { version = "1.0.8", features = ["use-std"] }

# env_logger = "0.11"
tracing = { version = "0.1.37", features = [
"max_level_trace",
Expand All @@ -111,11 +115,7 @@ tracing-subscriber = { version = "0.3", default-features = false, features = [
"ansi",
"fmt",
] }
tracing-appender = "0.2.3"
pretty_assertions = "1.4.0"
wide = "0.7.22"
simba = "0.8.1"
testresult = "0.4.0"


# criterion = "0.5"

Expand Down
84 changes: 66 additions & 18 deletions crates/odonata-base/src/boards/board.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,20 @@ impl Default for Board {
}
}

impl Ord for Board {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.halfmove_clock()
.cmp(&other.halfmove_clock())
.then(self.hash().cmp(&other.hash()))
}
}

impl PartialOrd for Board {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}

impl fmt::Debug for Board {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Board").field("fen", &self.to_fen()).finish()
Expand Down Expand Up @@ -219,18 +233,34 @@ impl BoardBuilder {
/// Parses a FEN string to create a board. FEN format is detailed at https://en.wikipedia.org/wiki/Forsyth–Edwards_Notation
/// terminology of "piece placement data" from http://kirill-kryukov.com/chess/doc/fen.html
pub fn parse_piece_placement(fen: &str) -> Result<Self> {
let mut pos = String::from(fen);
for i in 1..=8 {
pos = pos.replace(i.to_string().as_str(), " ".repeat(i).as_str());
}
// pos.retain(|ch| "pPRrNnBbQqKk ".contains(ch));
let r: Vec<&str> = pos.rsplit('/').collect();
if r.iter().any(|r| r.chars().count() != 8) || r.len() != 8 {
bail!("expected 8 ranks of 8 pieces in fen {}", fen);
}
Ok(Self::parse_piece_placement2(fen)?.1)
}

fn parse_piece_placement2(fen: &str) -> Result<(&str, Self)> {
let mut bb = Board::builder();
bb.set(Bitboard::all(), &r.concat())?;
Ok(bb)
let mut ir = 7_u32;
let mut ic = 0_u32;
for (_i, c) in fen.char_indices() {
match c {
c if c.is_ascii_digit() => ic += (c as u8 - b'0') as u32,
'.' => ic += 1,
'/' => {
if ir == 0 || ic != 8 {
bail!("expected 8 ranks of 8 pieces in fen {}", fen);
}
ic = 0;
ir -= 1;
}
_ => {
let (p, c) = Piece::and_color_from_char(c)?;
let sq = Square::from_xy(ic, ir);
bb.add_piece(sq, p, c);
ic += 1;
}
};
}
anyhow::ensure!(ir == 0 && ic == 8, "expected 8 ranks of 8 pieces in fen {}", fen);
Ok((fen, bb))
}

pub fn clear(&mut self, bb: Bitboard) {
Expand Down Expand Up @@ -397,6 +427,13 @@ impl Board {
}
}

#[inline]
pub fn piece_color(&self, sq: Square) -> Option<(Piece, Color)> {
let c = self.color_of(sq)?;
let p = self.piece_unchecked(sq); // caught by color_of above
Some((p, c))
}

#[inline]
pub fn is_occupied_by(&self, sq: Square, p: Piece) -> bool {
sq.is_in(self.pieces(p))
Expand Down Expand Up @@ -900,7 +937,7 @@ impl Board {
if words.len() < 6 {
bail!("must specify at least 6 parts in epd/fen '{}'", fen);
}
let mut bb = BoardBuilder::parse_piece_placement(words[0])?;
let (mut _s, mut bb) = BoardBuilder::parse_piece_placement2(words[0])?;
bb.set_turn(Color::parse(words[1])?);
bb.set_castling(CastlingRights::parse(words[2])?);
bb.set_ep_square(if words[3] == "-" {
Expand Down Expand Up @@ -973,17 +1010,17 @@ mod tests {
}

#[test]
fn to_fen() {
fn test_to_fen() {
for &fen in &[
"7k/8/8/8/8/8/8/7K b KQkq - 45 100",
Catalog::STARTING_POSITION_FEN,
"8/8/8/8/8/8/8/B7 w - - 0 0",
] {
let b = Board::parse_fen(fen).unwrap();
println!("{fen}");
// println!("{:#}", b);
// println!("{:L>}", b);
assert_eq!(fen, b.to_fen());
println!("{:#}", b);
println!("{}", b);
println!("{:L>}", b);
}
}

Expand All @@ -1003,7 +1040,7 @@ mod tests {
}

#[test]
fn parse_piece() -> Result<()> {
fn test_fen_parse_errors() -> Result<()> {
let fen1 = "1/1/7/8/8/8/PPPPPPPP/RNBQKBNR";
assert_eq!(
BoardBuilder::parse_piece_placement(fen1).unwrap_err().to_string(),
Expand All @@ -1021,7 +1058,7 @@ mod tests {
BoardBuilder::parse_piece_placement("X7/8/8/8/8/8/8/8")
.unwrap_err()
.to_string(),
"Unknown piece 'X'"
"Unknown color/piece 'X'"
);
let buf = BoardBuilder::parse_piece_placement("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR")?.build();
assert_eq!(buf.get(Bitboard::A1), "R");
Expand All @@ -1032,10 +1069,21 @@ mod tests {
#[test]
fn parse_fen() -> Result<()> {
let b = Board::parse_fen("7k/8/8/8/8/8/8/7K b KQkq - 45 100")?;
assert_eq!(b.piece_color(Square::H8), Some((Piece::King, Color::Black)));
assert_eq!(b.piece_color(Square::H1), Some((Piece::King, Color::White)));
assert_eq!(b.occupied().popcount(), 2);
assert_eq!(b.color_us(), Color::Black);
assert_eq!(b.fullmove_number(), 100);
assert_eq!(b.halfmove_clock(), 45);
assert_eq!(b.castling(), CastlingRights::all());

let b = Board::parse_fen("7k/p7/8/8/8/8/7P/7K b KQkq - 45 100")?;
assert_eq!(b.piece_color(Square::A7), Some((Piece::Pawn, Color::Black)));
assert_eq!(b.piece_color(Square::H2), Some((Piece::Pawn, Color::White)));
assert_eq!(b.piece_color(Square::H8), Some((Piece::King, Color::Black)));
assert_eq!(b.piece_color(Square::H1), Some((Piece::King, Color::White)));
assert_eq!(b.occupied().popcount(), 4);

Ok(())
}

Expand Down
7 changes: 3 additions & 4 deletions crates/odonata-base/src/boards/boardcalcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ mod tests {
use crate::catalog::*;
use crate::infra::profiler::PerfProfiler;
use crate::mv::Move;
use crate::other::tags::TagOps;
use crate::other::Perft;

#[test]
Expand All @@ -147,7 +148,7 @@ mod tests {
fn test_pinned() {
for epd in Catalog::pins() {
let pins = BoardCalcs::pinned_and_discoverers(&epd.board(), epd.board().color_us()).0;
assert_eq!(pins, epd.bitboard("Sq").unwrap(), "{epd}");
assert_eq!(Some(pins), epd.bitboard("Sq"), "{epd}\ntags:{:#?}", epd.tags());
}
}

Expand All @@ -156,9 +157,7 @@ mod tests {
let positions = Catalog::discovered_check();
for epd in positions {
let discoverers = BoardCalcs::pinned_and_discoverers(&epd.board(), epd.board().color_us()).1;
assert_eq!(discoverers, epd.bitboard("Sq").unwrap(), "{epd}");
let discoverers = BoardCalcs::pinned_and_discoverers(&epd.board(), epd.board().color_us()).1;
assert_eq!(discoverers, epd.bitboard("Sq").unwrap(), "{epd}");
assert_eq!(Some(discoverers), epd.bitboard("Sq"), "{epd}");
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/odonata-base/src/boards/movegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ mod tests {
.sorted()
.join(" ");

assert_eq!(lm, expected, "{epd} {:#}", epd.board());
assert_eq!(lm, expected, "{epd:#?} {:#}", epd.board());
}
}

Expand Down
28 changes: 28 additions & 0 deletions crates/odonata-base/src/domain/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,34 @@ impl Info {
};
Ok(())
}

// pub fn to_epd(&self, b: &Board) -> Epd {
// let mut epd = Epd::from_board(b.clone());
// if let Some(pv) = &self.pv {
// epd.set_tag("sv", &pv.to_san(b));
// epd.set_tag("sm", &pv.first().unwrap_or_default().to_san(b));
// }
// if let Some(score) = self.score {
// epd.set_tag("ce", &score.as_i16().to_string());
// }
// if let Some(depth) = self.depth {
// epd.set_tag("acd", &depth.to_string());
// }
// if let Some(nodes) = self.nodes {
// epd.set_tag("acn", &nodes.to_string());
// }
// if let Some(seldepth) = self.seldepth {
// epd.set_tag("acsd", &seldepth.to_string());
// }
// if let Some(time_millis) = self.time_millis {
// epd.set_tag("acs", &(time_millis / 1000).to_string());
// epd.set_tag("Acms", &time_millis.to_string());
// }
// if let Some(comment) = &self.string_text {
// epd.set_tag("c0", comment);
// }
// epd
// }
}

impl fmt::Display for Info {
Expand Down
Loading

0 comments on commit 3098f53

Please sign in to comment.