rustenginelib/
lineargame.rs1use crate::constants::*;
3use crate::square::*;
5use crate::state::*;
6
7use std::time::Instant;
8
9pub struct LinearGame {
11 pub states: Vec<State>,
12 pub state_ptr: usize,
13 pub nodes: usize,
14}
15
16impl LinearGame {
18 pub fn new() -> LinearGame {
20 LinearGame {
21 states: vec![State::new(); MAX_STATES],
22 state_ptr: 0,
23 nodes: 0,
24 }
25 }
26
27 pub fn current(&mut self) -> &mut State {
29 &mut self.states[self.state_ptr]
30 }
31
32 pub fn pretty_print_string(&mut self) -> String {
34 self.current().pretty_print_string()
35 }
36
37 pub fn print(&mut self) {
39 println!("{}", self.pretty_print_string())
40 }
41
42 pub fn init(&mut self, variant: Variant) {
44 self.state_ptr = 0;
45 self.current().init(variant);
46 }
47
48 pub fn push(&mut self, mv: Move) {
50 self.state_ptr += 1;
51 self.states[self.state_ptr] = self.states[self.state_ptr - 1].clone();
52 self.current().make_move(mv);
53 }
54
55 pub fn pop(&mut self) {
57 if self.state_ptr <= 0 {
58 return;
59 }
60 self.state_ptr -= 1;
61 }
62
63 pub fn push_by_index(&mut self, index: usize) -> bool {
65 if index < self.current().move_buff.len() {
66 let mv = self.current().move_buff[index].mv;
67 self.push(mv);
68 return true;
69 }
70 false
71 }
72
73 pub fn perft_rec(&mut self, depth: usize) {
74 self.nodes += 1;
75 if depth == 0 {
76 return;
77 }
78 let moves = self.current().generate_pseudo_legal_moves(MoveGenMode::All);
79 for mv in moves.iter() {
80 self.push(*mv);
81 self.perft_rec(depth - 1);
82 self.pop();
83 }
84 }
85
86 pub fn perft(&mut self, depth: usize) -> (usize, f32, f32) {
87 self.nodes = 0;
88 let start = Instant::now();
89 self.perft_rec(depth);
90 let duration = start.elapsed();
91 let secs = ((duration.as_secs() as f32) * 1e9 + (duration.subsec_nanos() as f32)) / 1e9;
92 (self.nodes, secs, (self.nodes as f32) / secs / 1000.0)
93 }
94}