fn search(pos: &Pos, alpha: i32, beta: i32, depth: i32, _ply: i32) -> i32 {
    assert!(-EVAL_INF <= alpha && alpha < beta && beta <= EVAL_INF);
    // leaf?

    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
    {
        if is_x86_feature_detected!("avx512bw") {
            unsafe {
                if pos_is_winner_avx512(&pos) {
                    return -EVAL_INF + _ply;
                }

                if pos_is_draw_avx512(&pos) {
                    return 0;
                }
            }
        } else {
            if pos_is_winner(&pos) {
                return -EVAL_INF + _ply;
            }

            if pos_is_draw(&pos) {
                return 0;
            }
        }
    }

    #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
    {
        if pos_is_winner(&pos) {
            return -EVAL_INF + _ply;
        }

        if pos_is_draw(&pos) {
            return 0;
        }
    }

    if depth == 0 {
        return eval(&pos, _ply);
    }

    let p_move_new: [Move; (FILE_SIZE * RANK_SIZE) as usize] =
        [0; (FILE_SIZE * RANK_SIZE) as usize];

    let mut list = List {
        p_move: p_move_new,
        p_size: 0,
    };

    let mut bm: Move = MOVE_NONE;
    let mut bs: i32 = SCORE_NONE;

    gen_moves(&mut list, &pos);

    // move loop

    if _ply == 0 {
        list.shuffle();
    }

    for i in 0..list.size() {
        if bs < beta {
            let mv: Move = list.p_move[i as usize];

            let mut new_pos = Pos {
                state: pos.state,
                p_turn: pos.p_turn,
                bitboard: pos.bitboard,
            };

            new_pos.do_move(mv);

            let sc: i32 = -search(&new_pos, -beta, -cmp::max(alpha, bs), depth - 1, _ply + 1);

            if sc > bs {
                bm = mv;
                bs = sc;
            }
        }
    }

    assert!(bm != MOVE_NONE);
    assert!(bs >= -EVAL_INF && bs <= EVAL_INF);

    if _ply == 0 {
        bm
    } else {
        bs
    } //best move at the root node, best score elsewhere
}
/// AI: use Minimax search with alpha-beta pruning
use Minimax search with alpha-beta pruning
use Minimax search with alpha - beta pruning
fn search(pos: &Pos, alpha: i32, beta: i32, depth: i32, _ply: i32) -> i32 {
    assert!(-EVAL_INF <= alpha && alpha < beta && beta <= EVAL_INF);
    // leaf?
    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
    {
        if is_x86_feature_detected!("avx512bw") {
            unsafe {
                if pos_is_winner_avx512(&pos) {
                    return -EVAL_INF + _ply;
                }
                if pos_is_draw_avx512(&pos) {
                    return 0;
                }
            }
        } else {
            if pos_is_winner(&pos) {
                return -EVAL_INF + _ply;
            }
            if pos_is_draw(&pos) {
                return 0;
            }
        }
    }
    #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
    {
        if pos_is_winner(&pos) {
            return -EVAL_INF + _ply;
        }
        if pos_is_draw(&pos) {
            return 0;
        }
    }
    if depth == 0 {
        return eval(&pos, _ply);
    }
    let p_move_new: [Move; (FILE_SIZE * RANK_SIZE) as usize] =
        [0; (FILE_SIZE * RANK_SIZE) as usize];
    let mut list = List {
        p_move: p_move_new,
        p_size: 0,
    };
    let mut bm: Move = MOVE_NONE;
    let mut bs: i32 = SCORE_NONE;
    gen_moves(&mut list, &pos);
    // move loop
    if _ply == 0 {
        list.shuffle();
    }
    for i in 0..list.size() {
        if bs < beta {
            let mv: Move = list.p_move[i as usize];
            let mut new_pos = Pos {
                state: pos.state,
                p_turn: pos.p_turn,
                bitboard: pos.bitboard,
            };
            new_pos.do_move(mv);
            let sc: i32 = -search(&new_pos, -beta, -cmp::max(alpha, bs), depth - 1, _ply + 1);
            if sc > bs {
                bm = mv;
                bs = sc;
            }
        }
    }
    assert!(bm != MOVE_NONE);
    assert!(bs >= -EVAL_INF && bs <= EVAL_INF);
    if _ply == 0 {
        bm
    } else {
        bs
    } //best move at the root node, best score elsewhere
}
fn search ( pos : & Pos , alpha : i32 , beta : i32 , depth : i32 , _ply : i32 ) -> i32 { assert ! ( EVAL_INF alpha alpha beta beta EVAL_INF ) ; // leaf? # [ cfg ( any ( target_arch " " target_arch " " ) ) ] { if is_x86_feature_detected ! ( " " ) { unsafe { if pos_is_winner_avx512 ( & pos ) { return - EVAL_INF + _ply ; } if pos_is_draw_avx512 ( & pos ) { return 0 ; } } } else { if pos_is_winner ( & pos ) { return - EVAL_INF + _ply ; } if pos_is_draw ( & pos ) { return 0 ; } } } # [ cfg ( not ( any ( target_arch " " target_arch " " ) ) ) ] { if pos_is_winner ( & pos ) { return - EVAL_INF + _ply ; } if pos_is_draw ( & pos ) { return 0 ; } } if depth == 0 { return eval ( & pos , _ply ) ; } let p_move_new : [ Move ; ( FILE_SIZE * RANK_SIZE ) as usize ] = [ 0 ; ( FILE_SIZE * RANK_SIZE ) as usize ] ; let mut list = List { p_move : p_move_new , p_size : 0 , } ; let mut bm : Move = MOVE_NONE ; let mut bs : i32 = SCORE_NONE ; gen_moves ( & mut list , & pos ) ; // move loop if _ply == 0 { list . shuffle ( ) ; } for i in 0 .. list . size ( ) { if bs < beta { let mv : Move = list . p_move [ i as usize ] ; let mut new_pos = Pos { state : pos . state , p_turn : pos . p_turn , bitboard : pos . bitboard , } ; new_pos . do_move ( mv ) ; let sc : i32 = - search ( & new_pos , - beta , - cmp :: max ( alpha , bs ) , depth - 1 , _ply + 1 ) ; if sc > bs { bm = mv ; bs = sc ; } } } assert ! ( bm MOVE_NONE ) ; assert ! ( bs EVAL_INF bs EVAL_INF ) ; if _ply == 0 { bm } else { bs } //best move at the root node, best score elsewhere }
AI: use Minimax search with alpha-beta pruning
AI : use Minimax search with alpha - beta pruning
pos
&Pos
alpha
i32
beta
i32
depth
i32
_ply
i32
pos
&Pos
alpha
i32
beta
i32
depth
i32
_ply
i32