summaryrefslogtreecommitdiff
path: root/src/strategy
diff options
context:
space:
mode:
authorJustin Worthe <justin@worthe-it.co.za>2019-08-11 12:28:38 +0200
committerJustin Worthe <justin@worthe-it.co.za>2019-08-11 12:28:38 +0200
commitb3d48c9924a2502ba7e93bafb0a8afcd096bec76 (patch)
treee2237839759e3e44788c8aa482eff27b375cf6cd /src/strategy
parentf663267dd78b99322e70aba6417955221564d733 (diff)
Replaced hashmaps with deterministic hashmaps
I'm not worried about ddos attacks here, and this also has better perf for small keys.
Diffstat (limited to 'src/strategy')
-rw-r--r--src/strategy/minimax.rs29
1 files changed, 20 insertions, 9 deletions
diff --git a/src/strategy/minimax.rs b/src/strategy/minimax.rs
index b34d2f8..55abcec 100644
--- a/src/strategy/minimax.rs
+++ b/src/strategy/minimax.rs
@@ -2,8 +2,8 @@ use crate::command::{Action, Command};
use crate::constants::*;
use crate::game::{GameBoard, SimulationOutcome};
+use fnv::FnvHashMap;
use std::cmp;
-use std::collections::HashMap;
use std::ops::*;
use time::{Duration, PreciseTime};
@@ -45,9 +45,9 @@ pub fn choose_move(
) -> Command {
let mut root_node = Node {
score_sum: ScoreSum::new(),
- player_score_sums: [HashMap::new(), HashMap::new()],
+ player_score_sums: [FnvHashMap::default(), FnvHashMap::default()],
unexplored: move_combos(state),
- children: HashMap::new(),
+ children: FnvHashMap::default(),
};
while start_time.to(PreciseTime::now()) < max_time {
@@ -75,23 +75,33 @@ pub fn choose_move_with_normalized_perf(
) -> Command {
let mut root_node = Node {
score_sum: ScoreSum::new(),
- player_score_sums: [HashMap::new(), HashMap::new()],
+ player_score_sums: [FnvHashMap::default(), FnvHashMap::default()],
unexplored: move_combos(state),
- children: HashMap::new(),
+ children: FnvHashMap::default(),
};
for _ in 0..iterations {
let _ = expand_tree(&mut root_node, state.clone(), config);
}
+ eprintln!("Number of simulations: {}", root_node.score_sum.visit_count);
+ for (command, score_sum) in &root_node.player_score_sums[player_index] {
+ eprintln!(
+ "{} = {} ({} visits)",
+ command,
+ score_sum.avg().val,
+ score_sum.visit_count
+ );
+ }
+
best_player_move(&root_node, player_index)
}
pub struct Node {
score_sum: ScoreSum,
- player_score_sums: [HashMap<Command, ScoreSum>; 2],
+ player_score_sums: [FnvHashMap<Command, ScoreSum>; 2],
unexplored: Vec<[Command; 2]>,
- children: HashMap<[Command; 2], Node>,
+ children: FnvHashMap<[Command; 2], Node>,
}
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
@@ -177,9 +187,9 @@ fn expand_tree(node: &mut Node, mut state: GameBoard, config: &ScoreConfig) -> S
let new_node = Node {
score_sum: ScoreSum::with_initial(score),
- player_score_sums: [HashMap::new(), HashMap::new()],
+ player_score_sums: [FnvHashMap::default(), FnvHashMap::default()],
unexplored,
- children: HashMap::new(),
+ children: FnvHashMap::default(),
};
node.children.insert(commands, new_node);
update(node, commands, score);
@@ -243,6 +253,7 @@ fn score(state: &GameBoard, config: &ScoreConfig) -> Score {
let snowballs = state.players[0].snowballs() as f32 - state.players[1].snowballs() as f32;
let bombs = state.players[0].bombs() as f32 - state.players[1].bombs() as f32;
+ // TODO: None of these attributes give any signal early on.
// TODO: Try adding new features here. Something about board position?
Score {
val: max_health * config.max_health_weight