Files
e2hang b7a7d7404a
Some checks failed
deploy-docs / build (push) Has been cancelled
build-libriichi / build (push) Has been cancelled
Mortal
2025-10-07 20:30:03 +08:00

255 lines
10 KiB
Rust

use riichi::algo::agari::{self, AgariCalculator};
use riichi::algo::shanten;
use riichi::algo::sp::{InitState, SPCalculator};
use riichi::hand::hand;
use riichi::state::PlayerState;
use riichi::{t, tu8};
use std::hint::black_box;
use criterion::{Criterion, criterion_group, criterion_main};
fn shanten(c: &mut Criterion) {
shanten::ensure_init();
let tehai = hand("2344456m 14p 127s 2z 7p").unwrap();
c.bench_function("shanten", |b| {
b.iter(|| {
let tehai = black_box(tehai);
black_box(shanten::calc_all(&tehai, 4));
});
});
}
fn agari(c: &mut Criterion) {
agari::ensure_init();
let tehai = hand("111m 9m 9m").unwrap();
c.bench_function("agari", |b| {
b.iter(|| {
let tehai = black_box(tehai);
let calc = AgariCalculator {
tehai: &tehai,
is_menzen: false,
chis: &[],
pons: &tu8![S, C],
minkans: &[],
ankans: &tu8![N,],
bakaze: tu8!(S),
jikaze: tu8!(N),
winning_tile: tu8!(9m),
is_ron: true,
};
black_box(calc.search_yakus().unwrap());
});
});
}
fn sp(c: &mut Criterion) {
let calc = SPCalculator {
tehai_len_div3: 4,
chis: &[],
pons: &[],
minkans: &[],
ankans: &[],
bakaze: tu8!(E),
jikaze: tu8!(E),
prefer_riichi: true,
is_menzen: true,
num_doras_in_fuuro: 0,
dora_indicators: &[t!(6m)],
calc_double_riichi: false,
calc_haitei: false,
sort_result: true,
maximize_win_prob: true,
calc_tegawari: true,
calc_shanten_down: true,
};
let tehai = hand("3667m 23489p 34688s").unwrap();
let mut tiles_seen = tehai;
for ind in calc.dora_indicators {
tiles_seen[ind.deaka().as_usize()] += 1;
}
let can_discard = true;
let cur_shanten = shanten::calc_all(&tehai, calc.tehai_len_div3);
let tsumos_left = 12;
let init_state = InitState {
tehai,
akas_in_hand: [false; 3],
tiles_seen,
akas_seen: [false; 3],
};
c.bench_function(&format!("sp {cur_shanten} shanten"), |b| {
b.iter(|| {
let state = black_box(init_state.clone());
let candidates = black_box(&calc)
.calc(state, can_discard, tsumos_left, cur_shanten)
.unwrap();
black_box(candidates);
});
});
// ---
let calc = SPCalculator {
tehai_len_div3: 4,
chis: &[],
pons: &[],
minkans: &[],
ankans: &[],
bakaze: tu8!(E),
jikaze: tu8!(E),
prefer_riichi: true,
is_menzen: true,
num_doras_in_fuuro: 0,
dora_indicators: &[t!(6m)],
calc_double_riichi: false,
calc_haitei: false,
sort_result: true,
maximize_win_prob: true,
calc_tegawari: true,
calc_shanten_down: true,
};
let tehai = hand("45677m 456778p 248s").unwrap();
let mut tiles_seen = tehai;
for ind in calc.dora_indicators {
tiles_seen[ind.deaka().as_usize()] += 1;
}
let can_discard = true;
let cur_shanten = shanten::calc_all(&tehai, calc.tehai_len_div3);
let tsumos_left = 12;
let init_state = InitState {
tehai,
akas_in_hand: [false; 3],
tiles_seen,
akas_seen: [false; 3],
};
c.bench_function(&format!("sp {cur_shanten} shanten"), |b| {
b.iter(|| {
let state = black_box(init_state.clone());
let candidates = black_box(&calc)
.calc(state, can_discard, tsumos_left, cur_shanten)
.unwrap();
black_box(candidates);
});
});
}
fn encode_obs(c: &mut Criterion) {
let log = r#"
{"type":"start_kyoku","bakaze":"S","dora_marker":"F","kyoku":1,"honba":2,"kyotaku":1,"oya":0,"scores":[32300,18000,22000,26700],"tehais":[["1m","3m","4m","5mr","6m","6m","7m","5p","8p","6s","E","W","N"],["4m","5m","5m","8m","7p","1s","3s","4s","7s","9s","E","E","N"],["1m","2m","3m","3m","7m","9m","6p","9p","1s","4s","5sr","8s","C"],["8m","8m","3p","4p","4p","5p","8p","1s","6s","9s","9s","S","F"]]}
{"type":"tsumo","actor":0,"pai":"C"}
{"type":"dahai","actor":0,"pai":"W","tsumogiri":false}
{"type":"tsumo","actor":1,"pai":"N"}
{"type":"dahai","actor":1,"pai":"8m","tsumogiri":false}
{"type":"tsumo","actor":2,"pai":"5s"}
{"type":"dahai","actor":2,"pai":"1s","tsumogiri":false}
{"type":"tsumo","actor":3,"pai":"7p"}
{"type":"dahai","actor":3,"pai":"1s","tsumogiri":false}
{"type":"tsumo","actor":0,"pai":"7s"}
{"type":"dahai","actor":0,"pai":"N","tsumogiri":false}
{"type":"pon","actor":1,"target":0,"pai":"N","consumed":["N","N"]}
{"type":"dahai","actor":1,"pai":"7p","tsumogiri":false}
{"type":"tsumo","actor":2,"pai":"6p"}
{"type":"dahai","actor":2,"pai":"9p","tsumogiri":false}
{"type":"tsumo","actor":3,"pai":"2m"}
{"type":"dahai","actor":3,"pai":"F","tsumogiri":false}
{"type":"tsumo","actor":0,"pai":"4p"}
{"type":"dahai","actor":0,"pai":"8p","tsumogiri":false}
{"type":"tsumo","actor":1,"pai":"P"}
{"type":"dahai","actor":1,"pai":"4m","tsumogiri":false}
{"type":"tsumo","actor":2,"pai":"7s"}
{"type":"dahai","actor":2,"pai":"5s","tsumogiri":false}
{"type":"tsumo","actor":3,"pai":"2p"}
{"type":"dahai","actor":3,"pai":"S","tsumogiri":false}
{"type":"tsumo","actor":0,"pai":"2p"}
{"type":"dahai","actor":0,"pai":"2p","tsumogiri":true}
{"type":"tsumo","actor":1,"pai":"2s"}
{"type":"dahai","actor":1,"pai":"5m","tsumogiri":false}
{"type":"tsumo","actor":2,"pai":"3s"}
{"type":"dahai","actor":2,"pai":"C","tsumogiri":false}
{"type":"tsumo","actor":3,"pai":"6m"}
{"type":"dahai","actor":3,"pai":"2m","tsumogiri":false}
{"type":"tsumo","actor":0,"pai":"W"}
{"type":"dahai","actor":0,"pai":"W","tsumogiri":true}
{"type":"tsumo","actor":1,"pai":"3p"}
{"type":"dahai","actor":1,"pai":"5m","tsumogiri":false}
{"type":"tsumo","actor":2,"pai":"E"}
{"type":"dahai","actor":2,"pai":"E","tsumogiri":true}
{"type":"pon","actor":1,"target":2,"pai":"E","consumed":["E","E"]}
{"type":"dahai","actor":1,"pai":"3p","tsumogiri":false}
{"type":"tsumo","actor":2,"pai":"2p"}
{"type":"dahai","actor":2,"pai":"2p","tsumogiri":true}
{"type":"tsumo","actor":3,"pai":"2p"}
{"type":"dahai","actor":3,"pai":"6s","tsumogiri":false}
{"type":"tsumo","actor":0,"pai":"1m"}
{"type":"dahai","actor":0,"pai":"E","tsumogiri":false}
{"type":"tsumo","actor":1,"pai":"9p"}
{"type":"dahai","actor":1,"pai":"9p","tsumogiri":true}
{"type":"tsumo","actor":2,"pai":"8p"}
{"type":"dahai","actor":2,"pai":"8p","tsumogiri":true}
{"type":"tsumo","actor":3,"pai":"5s"}
{"type":"dahai","actor":3,"pai":"5s","tsumogiri":true}
{"type":"tsumo","actor":0,"pai":"3s"}
{"type":"dahai","actor":0,"pai":"C","tsumogiri":false}
{"type":"tsumo","actor":1,"pai":"C"}
{"type":"dahai","actor":1,"pai":"P","tsumogiri":false}
{"type":"tsumo","actor":2,"pai":"S"}
{"type":"dahai","actor":2,"pai":"S","tsumogiri":true}
{"type":"tsumo","actor":3,"pai":"3s"}
{"type":"dahai","actor":3,"pai":"3s","tsumogiri":true}
{"type":"tsumo","actor":0,"pai":"6p"}
{"type":"dahai","actor":0,"pai":"3s","tsumogiri":false}
{"type":"tsumo","actor":1,"pai":"4m"}
{"type":"dahai","actor":1,"pai":"4m","tsumogiri":true}
{"type":"tsumo","actor":2,"pai":"S"}
{"type":"dahai","actor":2,"pai":"S","tsumogiri":true}
{"type":"tsumo","actor":3,"pai":"1s"}
{"type":"dahai","actor":3,"pai":"1s","tsumogiri":true}
{"type":"tsumo","actor":0,"pai":"7m"}
{"type":"dahai","actor":0,"pai":"6m","tsumogiri":false}
{"type":"tsumo","actor":1,"pai":"W"}
{"type":"dahai","actor":1,"pai":"W","tsumogiri":true}
{"type":"tsumo","actor":2,"pai":"8s"}
{"type":"dahai","actor":2,"pai":"3m","tsumogiri":false}
{"type":"tsumo","actor":3,"pai":"1m"}
{"type":"dahai","actor":3,"pai":"1m","tsumogiri":true}
{"type":"tsumo","actor":0,"pai":"9m"}
{"type":"dahai","actor":0,"pai":"9m","tsumogiri":true}
{"type":"tsumo","actor":1,"pai":"1p"}
{"type":"dahai","actor":1,"pai":"1p","tsumogiri":true}
{"type":"tsumo","actor":2,"pai":"3m"}
{"type":"dahai","actor":2,"pai":"3m","tsumogiri":true}
{"type":"tsumo","actor":3,"pai":"2s"}
{"type":"dahai","actor":3,"pai":"2s","tsumogiri":true}
{"type":"tsumo","actor":0,"pai":"6s"}
{"type":"dahai","actor":0,"pai":"7m","tsumogiri":false}
{"type":"tsumo","actor":1,"pai":"9p"}
{"type":"dahai","actor":1,"pai":"9p","tsumogiri":true}
{"type":"tsumo","actor":2,"pai":"9m"}
{"type":"dahai","actor":2,"pai":"9m","tsumogiri":true}
{"type":"tsumo","actor":3,"pai":"P"}
{"type":"dahai","actor":3,"pai":"P","tsumogiri":true}
{"type":"tsumo","actor":0,"pai":"5p"}
{"type":"dahai","actor":0,"pai":"5p","tsumogiri":true}
{"type":"tsumo","actor":1,"pai":"2s"}
{"type":"dahai","actor":1,"pai":"2s","tsumogiri":true}
{"type":"tsumo","actor":2,"pai":"5s"}
{"type":"dahai","actor":2,"pai":"7m","tsumogiri":false}
{"type":"tsumo","actor":3,"pai":"6s"}
"#;
let mut ps = PlayerState::new(3);
for line in log.trim().split('\n') {
ps.update(&serde_json::from_str(line).unwrap()).unwrap();
}
c.bench_function("encode obs", |b| {
b.iter(|| {
let ps = black_box(&ps);
let result = ps.encode_obs(4, false);
black_box(result);
});
});
}
criterion_group!(algo, shanten, agari, sp);
criterion_group!(state, encode_obs);
criterion_main!(algo, state);