Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
primenumber committed Nov 26, 2023
1 parent 24c94ac commit 6746cbd
Showing 1 changed file with 68 additions and 61 deletions.
129 changes: 68 additions & 61 deletions src/engine/midgame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ use futures::future::{BoxFuture, FutureExt};
use futures::StreamExt;
use num_cpus;
use std::cmp::max;
use std::collections::HashSet;
use std::collections::VecDeque;
use std::collections::HashMap;
use std::sync::{Arc, RwLock};
use std::thread;

Expand Down Expand Up @@ -233,25 +232,23 @@ where

fn simplified_abdada_young(
solve_obj: &mut SolveObj,
sub_solver: &SubSolver,
(alpha, beta): (i8, i8),
stat: &mut SolveStat,
q: &mut VecDeque<(Hand, Board, bool)>,
(pos, next, deffered): (Hand, Board, bool),
deffered: &mut Vec<(Hand, Board)>,
(pos, next): (Hand, Board),
res: &mut i8,
best: &mut Option<Hand>,
depth: i8,
cs_hash: &Arc<RwLock<HashSet<Board>>>,
cs_hash: &Arc<RwLock<HashMap<Board, usize>>>,
) -> Option<(i8, Option<Hand>, SolveStat)> {
if !deffered && defer_search(next, cs_hash) {
q.push_back((pos, next, true));
if defer_search(next, cs_hash) {
deffered.push((pos, next));
return None;
}
// NWS
start_search(next, cs_hash);
let (cres, _chand, cstat) = simplified_abdada_intro(
solve_obj,
sub_solver,
next,
(-alpha - 1, -alpha),
false,
Expand All @@ -262,15 +259,7 @@ fn simplified_abdada_young(
stat.merge(cstat);
let mut tmp = -cres;
if alpha < tmp && tmp < beta {
let (cres, _chand, cstat) = simplified_abdada_intro(
solve_obj,
sub_solver,
next,
(-beta, -tmp),
false,
depth + 1,
cs_hash,
);
let (cres, _chand, cstat) = simplified_abdada_intro(solve_obj, next, (-beta, -tmp), false, depth + 1, cs_hash);
stat.merge(cstat);
tmp = -cres;
}
Expand All @@ -286,12 +275,11 @@ fn simplified_abdada_young(

fn simplified_abdada_body(
solve_obj: &mut SolveObj,
sub_solver: &SubSolver,
board: Board,
(mut alpha, beta): (i8, i8),
passed: bool,
depth: i8,
cs_hash: &Arc<RwLock<HashSet<Board>>>,
cs_hash: &Arc<RwLock<HashMap<Board, usize>>>,
) -> (i8, Option<Hand>, SolveStat) {
let v = move_ordering_impl(solve_obj, board, None);
let mut stat = SolveStat::one();
Expand All @@ -301,7 +289,6 @@ fn simplified_abdada_body(
} else {
let (child_res, _child_best, child_stat) = simplified_abdada_intro(
solve_obj,
sub_solver,
board.pass_unchecked(),
(-beta, -alpha),
true,
Expand All @@ -312,42 +299,29 @@ fn simplified_abdada_body(
return (-child_res, Some(Hand::Pass), stat);
}
}
let mut q = VecDeque::with_capacity(v.len());
for (pos, next) in v {
q.push_back((pos, next, false));
}
let mut res = -(BOARD_SIZE as i8);
let mut best = None;
let mut is_first = true;
let mut stat = SolveStat::one();
while let Some((pos, next, deffered)) = q.pop_front() {
if is_first {
let (cres, _chand, cstat) = simplified_abdada_intro(
solve_obj,
sub_solver,
next,
(-beta, -alpha),
false,
depth + 1,
cs_hash,
);
let mut deffered = Vec::new();
for (i, (pos, next)) in v.into_iter().enumerate() {
if i == 0 {
let (cres, _chand, cstat) =
simplified_abdada_intro(solve_obj, next, (-beta, -alpha), false, depth + 1, cs_hash);
stat.merge(cstat);
res = -cres;
best = Some(pos);
alpha = max(alpha, res);
if alpha >= beta {
return (res, best, stat);
}
is_first = false;
continue;
}
if let Some(ret) = simplified_abdada_young(
solve_obj,
sub_solver,
(alpha, beta),
&mut stat,
&mut q,
(pos, next, deffered),
&mut deffered,
(pos, next),
&mut res,
&mut best,
depth,
Expand All @@ -356,17 +330,42 @@ fn simplified_abdada_body(
return ret;
}
}
for (pos, next) in deffered {
// NWS
let (cres, _chand, cstat) = simplified_abdada_intro(
solve_obj,
next,
(-alpha - 1, -alpha),
false,
depth + 1,
cs_hash,
);
stat.merge(cstat);
let mut tmp = -cres;
if alpha < tmp && tmp < beta {
let (cres, _chand, cstat) =
simplified_abdada_intro(solve_obj, next, (-beta, -tmp), false, depth + 1, cs_hash);
stat.merge(cstat);
tmp = -cres;
}
if tmp >= beta {
return (tmp, Some(pos), stat);
}
if tmp > res {
best = Some(pos);
res = tmp;
}
}
(res, best, stat)
}

fn simplified_abdada_intro(
solve_obj: &mut SolveObj,
sub_solver: &SubSolver,
board: Board,
(mut alpha, mut beta): (i8, i8),
passed: bool,
depth: i8,
cs_hash: &Arc<RwLock<HashSet<Board>>>,
cs_hash: &Arc<RwLock<HashMap<Board, usize>>>,
) -> (i8, Option<Hand>, SolveStat) {
let rem = popcnt(board.empty());
if depth >= solve_obj.params.ybwc_depth_limit || rem < solve_obj.params.ybwc_empties_limit {
Expand All @@ -382,15 +381,7 @@ fn simplified_abdada_intro(
CacheLookupResult::Cut(v) => return (v, None, SolveStat::zero()),
CacheLookupResult::NoCut(l, u, b) => (l, u, b),
};
let (res, best, stat) = simplified_abdada_body(
solve_obj,
sub_solver,
board,
(alpha, beta),
passed,
depth,
cs_hash,
);
let (res, best, stat) = simplified_abdada_body(solve_obj, board, (alpha, beta), passed, depth, cs_hash);
if rem >= solve_obj.params.res_cache_limit {
update_table(
solve_obj.res_cache.clone(),
Expand All @@ -405,36 +396,52 @@ fn simplified_abdada_intro(
(res, best, stat)
}

fn start_search(board: Board, cs_hash: &Arc<RwLock<HashSet<Board>>>) {
cs_hash.write().unwrap().insert(board);
fn start_search(board: Board, cs_hash: &Arc<RwLock<HashMap<Board, usize>>>) {
let mut locked_table = cs_hash.write().unwrap();
match locked_table.get_mut(&board) {
Some(nproc) => *nproc += 1,
None => {
locked_table.insert(board, 1);
}
}
}

fn finish_search(board: Board, cs_hash: &Arc<RwLock<HashSet<Board>>>) {
cs_hash.write().unwrap().remove(&board);
fn finish_search(board: Board, cs_hash: &Arc<RwLock<HashMap<Board, usize>>>) {
let mut locked_table = cs_hash.write().unwrap();
match locked_table.get_mut(&board) {
Some(nproc) => {
*nproc -= 1;
if *nproc == 0 {
locked_table.remove(&board);
}
}
None => {
panic!();
}
}
}

fn defer_search(board: Board, cs_hash: &Arc<RwLock<HashSet<Board>>>) -> bool {
cs_hash.read().unwrap().contains(&board)
fn defer_search(board: Board, cs_hash: &Arc<RwLock<HashMap<Board, usize>>>) -> bool {
cs_hash.read().unwrap().contains_key(&board)
}

pub fn simplified_abdada(
solve_obj: &mut SolveObj,
sub_solver: &SubSolver,
_sub_solver: &SubSolver,
board: Board,
(alpha, beta): (i8, i8),
passed: bool,
depth: i8,
) -> (i8, Option<Hand>, SolveStat) {
thread::scope(|s| {
let mut handles = Vec::new();
let cs_hash = Arc::new(RwLock::new(HashSet::new()));
let cs_hash = Arc::new(RwLock::new(HashMap::new()));
for _ in 0..num_cpus::get() {
let mut solve_obj = solve_obj.clone();
let cs_hash = cs_hash.clone();
handles.push(s.spawn(move || {
simplified_abdada_intro(
&mut solve_obj,
sub_solver,
board,
(alpha, beta),
passed,
Expand Down

0 comments on commit 6746cbd

Please sign in to comment.