Skip to content

Commit

Permalink
chore: cleanup go invocation
Browse files Browse the repository at this point in the history
  • Loading branch information
raklaptudirm committed May 31, 2024
1 parent 6007a2a commit b06a314
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 136 deletions.
215 changes: 85 additions & 130 deletions src/commands/go.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,72 +11,89 @@ pub fn go() -> Command<Context> {
let winc = bundle.is_flag_set("winc");
let btime = bundle.is_flag_set("btime");
let wtime = bundle.is_flag_set("wtime");
let movestogo = bundle.is_flag_set("movestogo");
// let movestogo = bundle.is_flag_set("movestogo");
let depth = bundle.is_flag_set("depth");
let nodes = bundle.is_flag_set("nodes");
let movetime = bundle.is_flag_set("movetime");
// let ponder = bundle.is_flag_set("ponder");
let infinite = bundle.is_flag_set("infinite");

let std_tc = btime && wtime;
let std_tc = btime || wtime || binc || winc;

if !std_tc && (binc | winc | btime | wtime | movestogo) {
return error!("bad flag set: unexpected standard time control flags");
if std_tc && !(btime && wtime && binc && winc) {
return error!("bad flag set: missing standard time control flags");
}

if infinite && (std_tc || depth || nodes || movetime) {
return error!("bad flag set: time control flags set alongside infinite");
}

let ctx = bundle.lock();
let position = ctx.position;
drop(ctx);

let best_move = if infinite {
if std_tc | depth | nodes | movetime {
return error!("bad flag set: no other flags with infinite");
}

todo!()
} else if std_tc {
if depth | nodes | movetime {
return error!("bad flag set: unexpected non-standard time control flags");
}
let movestogo = match bundle.get_single_flag("movestogo") {
Some(string) => Some(string.parse()?),
None => None,
};

macro_rules! get_flag {
($name:literal) => {
bundle.get_single_flag($name).unwrap().parse()?
let limits = Limits {
nodes: match bundle.get_single_flag("nodes") {
Some(nodes) => nodes.parse()?,
None => usize::MAX,
},
depth: match bundle.get_single_flag("depth") {
Some(depth) => depth.parse()?,
None => u16::MAX,
},
movetime: {
let movetime = match bundle.get_single_flag("movetime") {
Some(movetime) => time::Duration::from_millis(movetime.parse()?),
None => time::Duration::MAX,
};
}

let tc = StandardTC {
btime: get_flag!("btime"),
wtime: get_flag!("wtime"),
binc: get_flag!("binc"),
winc: get_flag!("winc"),
movestogo: match bundle.get_single_flag("movestogo") {
Some(movestogo) => Some(movestogo.parse()?),
None => None,
},
};

search_std(position, tc)
} else {
let tc = InternalTC {
nodes: match bundle.get_single_flag("nodes") {
Some(nodes) => Some(nodes.parse()?),
None => None,
},
depth: match bundle.get_single_flag("depth") {
Some(depth) => Some(depth.parse()?),
None => None,
},
movetime: match bundle.get_single_flag("movetime") {
Some(movetime) => Some(time::Duration::from_millis(movetime.parse()?)),
None => None,
},
};

search_int(position, tc)
if std_tc {
macro_rules! get_flag {
($name:literal) => {
bundle.get_single_flag($name).unwrap().parse()?
};
}

let tc = StandardTC {
btime: get_flag!("btime"),
wtime: get_flag!("wtime"),
binc: get_flag!("binc"),
winc: get_flag!("winc"),
};

let our_time = match position.side_to_move {
ataxx::Piece::Black => tc.wtime,
ataxx::Piece::White => tc.btime,
_ => unreachable!(),
};

let our_inc = match position.side_to_move {
ataxx::Piece::Black => tc.winc,
ataxx::Piece::White => tc.binc,
_ => unreachable!(),
};

let usable_time = time::Duration::from_millis(
(our_time / movestogo.unwrap_or(20) as u64 + our_inc / 2).max(1),
);

usable_time.min(movetime)
} else {
movetime
}
},

movestogo,
};

println!("bestmove {}", best_move);
let bestmove = search(position, limits);

println!("bestmove {}", bestmove);

Ok(())
})
Expand Down Expand Up @@ -104,32 +121,23 @@ pub struct StandardTC {
pub wtime: u64,
pub binc: u64,
pub winc: u64,
pub movestogo: Option<u8>,
}

pub fn search_std(position: ataxx::Position, tc: StandardTC) -> ataxx::Move {
let our_time = match position.side_to_move {
ataxx::Piece::Black => tc.wtime,
ataxx::Piece::White => tc.btime,
_ => unreachable!(),
};

let our_inc = match position.side_to_move {
ataxx::Piece::Black => tc.winc,
ataxx::Piece::White => tc.binc,
_ => unreachable!(),
};

let movetime = time::Duration::from_millis(
(our_time / tc.movestogo.unwrap_or(20) as u64 + our_inc / 2).max(1),
);
#[derive(Debug)]
pub struct Limits {
pub depth: u16,
pub nodes: usize,
pub movetime: time::Duration,
pub movestogo: Option<u8>,
}

pub fn search(position: ataxx::Position, tc: Limits) -> ataxx::Move {
let mut tree = mcts::Tree::new(position);
let start = time::Instant::now();
let mut last_info = start;
let mut seldepth = 0;

println!("node size {}", mem::size_of::<Node>());
println!("{:?}", tc);

loop {
let node = tree.playout();
Expand All @@ -150,85 +158,32 @@ pub fn search_std(position: ataxx::Position, tc: StandardTC) -> ataxx::Move {
new_depth,
seldepth,
node.q() * 100.0,
tree.nodes(),
tree.playouts(),
tree.nodes() * 1000 / start.elapsed().as_millis().max(1) as usize
);
}

//
if start.elapsed() > movetime {
if start.elapsed() > tc.movetime || seldepth > tc.depth || tree.nodes() > tc.nodes {
break;
}

//println!("nodes {}", tree.nodes());
if tree.nodes() > 2_000_000_000 / mem::size_of::<Node>() {
break;
}
}
}

println!(
"info depth {} seldepth {} score cp {:.0} nodes {} nps {}",
0,
seldepth,
100.0,
tree.playouts(),
tree.nodes() * 1000 / start.elapsed().as_millis().max(1) as usize
);

// Verify the tree.
debug_assert!(tree.verify().is_ok());

tree.best_move()
}

pub struct InternalTC {
pub depth: Option<u16>,
pub nodes: Option<usize>,
pub movetime: Option<time::Duration>,
}

pub fn search_int(position: ataxx::Position, tc: InternalTC) -> ataxx::Move {
let mut tree = mcts::Tree::new(position);
let start = time::Instant::now();
let mut last_info = start;
let mut seldepth = 0;

loop {
let node = tree.playout();
if tree.playouts() & 4095 == 0 {
if last_info.elapsed() > time::Duration::from_secs(1) {
// Update last info report timestamp.
last_info = time::Instant::now();

let node = tree.node(node);
let new_depth = node.position.ply_count - position.ply_count;
if new_depth > seldepth {
seldepth = new_depth;
}

// Make a new info report.
println!(
"info depth {} seldepth {} score cp {:.0} nodes {} nps {}",
new_depth,
seldepth,
node.q() * 100.0,
tree.playouts(),
tree.nodes() * 1000 / start.elapsed().as_millis().max(1) as usize
);
}

//
if let Some(nodes) = tc.nodes {
if tree.nodes() > nodes {
break;
}
}

if let Some(depth) = tc.depth {
if seldepth > depth {
break;
}
}

if let Some(movetime) = tc.movetime {
if start.elapsed() > movetime {
break;
}
}
}
}

tree.best_move()
}
14 changes: 8 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use core::time;
use std::{env, str::FromStr};

use commands::{search_int, InternalTC};
use commands::{search, Limits};
use uxi::Client;

mod commands;
Expand Down Expand Up @@ -73,13 +74,14 @@ fn main() {
for (i, fen) in BENCH_FENS.iter().enumerate() {
println!("[#{}] {}", i + 1, fen);
let position = ataxx::Position::from_str(fen).unwrap();
let tc = InternalTC {
nodes: Some(20000),
depth: None,
movetime: None,
let tc = Limits {
nodes: 20000,
depth: u16::MAX,
movetime: time::Duration::MAX,
movestogo: None,
};

search_int(position, tc);
search(position, tc);
}

return
Expand Down

0 comments on commit b06a314

Please sign in to comment.