summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin Worthe <justin@worthe-it.co.za>2019-08-07 14:37:36 +0200
committerJustin Worthe <justin@worthe-it.co.za>2019-08-07 14:37:36 +0200
commitd4539771bca817add851ef484de4773cbbe43f79 (patch)
tree371556db78894f666425d8d28a67b23f89aed196 /src
parent096091af6a3a4d16da133037321c81a51e1bb4b2 (diff)
Assertions to test that my lava logic is right
Diffstat (limited to 'src')
-rw-r--r--src/game.rs64
-rw-r--r--src/strategy.rs8
-rw-r--r--src/strategy/mcts.rs10
-rw-r--r--src/strategy/minimax.rs2
4 files changed, 55 insertions, 29 deletions
diff --git a/src/game.rs b/src/game.rs
index c47d4b8..5f6ab33 100644
--- a/src/game.rs
+++ b/src/game.rs
@@ -178,8 +178,53 @@ impl GameBoard {
.collect();
for cell in json.map.iter().flatten() {
+ let point = Point2d::new(cell.x, cell.y);
+
+ if cfg!(debug_assertions) {
+ // This checks if my lava map is the same as the game
+ // engine's lava map. It's off by one because the game
+ // engine will update its one at the beginning of
+ // processing the round.
+ let lava = LAVA_MAP[self.round as usize];
+
+ let lava_at = lava.at(point);
+ // NB: Map hasn't been updated yet, so it can be used to tell previous state.
+ match (&cell.cell_type, self.map.at(point)) {
+ (json::CellType::Air, Some(false)) => assert!(
+ lava_at == Some(false),
+ "Lava at {:?} expected Some(false), but found {:?}",
+ point,
+ lava_at
+ ),
+ (json::CellType::Air, _) => assert!(
+ lava_at.is_some(),
+ "Lava at {:?} expected Some(_), but found {:?}",
+ point,
+ lava_at
+ ),
+ (json::CellType::Lava, _) => assert!(
+ lava_at == Some(true),
+ "Lava at {:?} expected Some(true), but found {:?}",
+ point,
+ lava_at
+ ),
+ (json::CellType::DeepSpace, _) => assert!(
+ lava_at == None,
+ "Lava at {:?} expected None, but found {:?}",
+ point,
+ lava_at
+ ),
+ (json::CellType::Dirt, _) => assert!(
+ lava_at.is_some(),
+ "Lava at {:?} expected Some(_), but found {:?}",
+ point,
+ lava_at
+ ),
+ };
+ }
+
if cell.cell_type == json::CellType::Air {
- self.map.clear(Point2d::new(cell.x, cell.y))
+ self.map.clear(point)
}
}
@@ -198,23 +243,6 @@ impl GameBoard {
.flat_map(|p| p.worms.iter())
.map(|w| w.position)
.collect();
-
- if cfg!(debug_assertions) {
- // This checks if my lava map is the same as the game
- // engine's lava map. It's off by one because the game
- // engine will update its one at the beginning of
- // processing the round.
- let lava = LAVA_MAP[self.round as usize - 1];
- for cell in json.map.iter().flatten() {
- let lava_at = lava.at(Point2d::new(cell.x, cell.y));
- match cell.cell_type {
- json::CellType::Air => assert!(lava_at == Some(false)),
- json::CellType::Lava => assert!(lava_at == Some(true)),
- json::CellType::DeepSpace => assert!(lava_at == None),
- json::CellType::Dirt => assert!(lava_at.is_some()),
- };
- }
- }
}
pub fn simulate(&mut self, moves: [Command; 2]) {
diff --git a/src/strategy.rs b/src/strategy.rs
index b6069a1..f16a4a0 100644
--- a/src/strategy.rs
+++ b/src/strategy.rs
@@ -1,5 +1,5 @@
-//mod mcts;
-//pub use mcts::{choose_move, Node};
+mod mcts;
+pub use mcts::{choose_move, Node};
-mod minimax;
-pub use minimax::{choose_move, Node};
+//mod minimax;
+//pub use minimax::{choose_move, Node};
diff --git a/src/strategy/mcts.rs b/src/strategy/mcts.rs
index 5a43c6e..b7478b8 100644
--- a/src/strategy/mcts.rs
+++ b/src/strategy/mcts.rs
@@ -41,9 +41,9 @@ pub fn choose_move(
let _ = mcts(&mut root_node);
}
- //eprintln!("Number of simulations: {}", root_node.score_sum.visit_count);
+ eprintln!("Number of simulations: {}", root_node.score_sum.visit_count);
for (command, score_sum) in &root_node.player_score_sums[0] {
- //eprintln!(
+ eprintln!(
"{} = {} ({} visits)",
command,
score_sum.avg().val,
@@ -164,8 +164,8 @@ fn mcts(node: &mut Node) -> Score {
}
fn mcts_move_combo(state: &GameBoard) -> Vec<[Command; 2]> {
- let player_moves = self.valid_moves(0);
- let opponent_moves = self.valid_moves(1);
+ let player_moves = state.valid_moves(0);
+ let opponent_moves = state.valid_moves(1);
debug_assert!(!player_moves.is_empty(), "No player moves");
debug_assert!(!opponent_moves.is_empty(), "No opponent moves");
@@ -228,5 +228,3 @@ fn update(node: &mut Node, commands: [Command; 2], score: Score) {
.or_insert_with(ScoreSum::new) += score;
node.score_sum += score;
}
-
-
diff --git a/src/strategy/minimax.rs b/src/strategy/minimax.rs
index 4b10014..be0c485 100644
--- a/src/strategy/minimax.rs
+++ b/src/strategy/minimax.rs
@@ -289,7 +289,7 @@ fn pruned_moves(state: &GameBoard, player_index: usize) -> Vec<Command> {
.filter(|command| {
//NB: These rules should pass for doing nothing, otherwise
// we need some other mechanism for sticking in a do
- // nothing option
+ // nothing option. Unfortunately, sitting in lava is a situation where this prunes all moves currently :(
let idle_opponent_state = sim_with_idle_opponent(*command);
let hurt_self = idle_opponent_state.players[player_index].health() < my_starting_health;