Skip to content

Commit

Permalink
improving memory usage a tiny bit
Browse files Browse the repository at this point in the history
  • Loading branch information
bananasmoothii committed Oct 7, 2023
1 parent 8b62b1a commit 00248de
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ mod min_max;
mod scalar;

fn main() {
let max_depth = 9;
let max_depth = 10;
let bot_vs_bot = true;

let p1 = NonZeroU8::new(1).unwrap();
Expand Down
62 changes: 46 additions & 16 deletions src/min_max.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::collections::HashMap;
use std::sync::{Arc, Mutex};

use rayon::iter::*;
Expand Down Expand Up @@ -98,7 +99,9 @@ impl<G: Game> GameNode<G> {
G::Score::MIN()
}));

let check_children = self.fill_children(now_playing);
// WARNING: (maybe) destroying game here, for memory efficiency

let check_children = self.fill_children_and_destroy_game(now_playing, real_plays);

let maybe_explore_children = |child: &mut Self| {
let child_score = child.explore_children_recur(
Expand Down Expand Up @@ -154,36 +157,63 @@ impl<G: Game> GameNode<G> {
weight.unwrap()
};

// WARNING: (maybe) destroying game here, for memory efficiency
if self.depth() != real_plays {
self.game = None;
}

weight
}

fn fill_children(&mut self, now_playing: <G as Game>::Player) -> bool {
/// Returns true if childrens should be checked for win or draw, false if they were already checked
fn fill_children_and_destroy_game(
&mut self,
now_playing: <G as Game>::Player,
real_plays: u32,
) -> bool {
let game = self.game.as_ref().expect("game was removed too early");

if self.children.is_empty() {
self.children = game
.possible_plays()
.iter()
.map(|&input_coord| {
// if we take the game from us, we don't have to clone it, but we can do this only once
let take_game = self.depth() != real_plays;

let possible_plays = game.possible_plays();
let possibilities = possible_plays.len();
let mut map = HashMap::with_capacity(possibilities);

if possibilities >= 2 || !take_game {
for i in 0..(possibilities - 1) {
let input_coord = possible_plays[i];
let mut game = game.clone();
game.play(now_playing, input_coord).unwrap(); // should not panic as input_coord is a possible play

(
map.insert(
input_coord,
GameNode::new(
Some(game),
self.depth() + 1,
None,
PlayersTurn(now_playing.other(), Some(input_coord)),
),
)
})
.collect(); // todo: a lot of memory is used here
);
}
}
if possibilities >= 1 {
let input_coord = possible_plays[possibilities - 1];
let mut game = if take_game {
// we don't want to destroy the game in the root node
// add the game itself while "destroying" it for us
self.game.take().unwrap()
} else {
game.clone()
};
game.play(now_playing, input_coord).unwrap();
map.insert(
input_coord,
GameNode::new(
Some(game),
self.depth() + 1,
None,
PlayersTurn(now_playing.other(), Some(input_coord)),
),
);
}

self.children = map;
true
} else {
self.regenerate_children_games();
Expand Down

0 comments on commit 00248de

Please sign in to comment.