summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml2
-rw-r--r--src/bin/perf-test.rs2
-rw-r--r--src/engine/bitwise_engine.rs28
-rw-r--r--src/input/json.rs51
-rw-r--r--src/main.rs2
-rw-r--r--src/strategy/monte_carlo.rs2
-rw-r--r--tests/bigstate.json1498
-rw-r--r--tests/expressive_to_bitwise_comparison.rs129
-rw-r--r--tests/live_comparison.rs4
-rw-r--r--tests/monte_carlo_test.rs2
10 files changed, 200 insertions, 1520 deletions
diff --git a/Cargo.toml b/Cargo.toml
index bc49a40..cf325ad 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,6 +11,8 @@ rand = "0.4.2"
time = "0.1.4"
rayon = "1.0.1"
+[dev-dependencies]
+proptest = "0.7.2"
[features]
benchmarking = []
diff --git a/src/bin/perf-test.rs b/src/bin/perf-test.rs
index 054258f..42b4def 100644
--- a/src/bin/perf-test.rs
+++ b/src/bin/perf-test.rs
@@ -10,7 +10,7 @@ use std::process;
fn main() {
let start_time = PreciseTime::now();
- let (settings, state) = match input::json::read_state_from_file(STATE_PATH) {
+ let (settings, state) = match input::json::read_expressive_state_from_file(STATE_PATH) {
Ok(ok) => ok,
Err(error) => {
println!("Error while parsing JSON file: {}", error);
diff --git a/src/engine/bitwise_engine.rs b/src/engine/bitwise_engine.rs
index ca9cf00..bb1dd76 100644
--- a/src/engine/bitwise_engine.rs
+++ b/src/engine/bitwise_engine.rs
@@ -14,25 +14,25 @@ const MAX_TESLAS: usize = 2;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BitwiseGameState {
- status: GameStatus,
- player: Player,
- opponent: Player,
- player_buildings: PlayerBuildings,
- opponent_buildings: PlayerBuildings,
+ pub status: GameStatus,
+ pub player: Player,
+ pub opponent: Player,
+ pub player_buildings: PlayerBuildings,
+ pub opponent_buildings: PlayerBuildings,
}
#[derive(Debug, Clone, PartialEq, Eq)]
-struct PlayerBuildings {
- unconstructed: Vec<UnconstructedBuilding>,
- energy_towers: [u8; MAP_HEIGHT],
- missile_towers: [[u8; MAP_HEIGHT]; MISSILE_COOLDOWN],
- defence_towers: [[u8; MAP_HEIGHT]; DEFENCE_HEALTH],
- tesla_towers: [u8; MAP_HEIGHT],
+pub struct PlayerBuildings {
+ pub unconstructed: Vec<UnconstructedBuilding>,
+ pub buildings: [u64; DEFENCE_HEALTH],
- missiles: [[u16; MAP_HEIGHT]; MAP_WIDTH/4],
- tesla_cooldowns: [TeslaCooldown; MAX_TESLAS],
+ pub energy_towers: u64,
+ pub missile_towers: [u64; MISSILE_COOLDOWN],
+
+ pub missiles: [(u64, u64); MAP_WIDTH/4],
+ pub tesla_cooldowns: [TeslaCooldown; MAX_TESLAS],
- unoccupied: Vec<Point>
+ pub unoccupied: Vec<Point>
}
#[derive(Debug, Clone, PartialEq, Eq)]
diff --git a/src/input/json.rs b/src/input/json.rs
index 6f7cda1..fb88bf0 100644
--- a/src/input/json.rs
+++ b/src/input/json.rs
@@ -5,9 +5,9 @@ use std::error::Error;
use engine;
use engine::expressive_engine;
+use engine::bitwise_engine;
-
-pub fn read_state_from_file(filename: &str) -> Result<(engine::settings::GameSettings, expressive_engine::ExpressiveGameState), Box<Error>> {
+pub fn read_expressive_state_from_file(filename: &str) -> Result<(engine::settings::GameSettings, expressive_engine::ExpressiveGameState), Box<Error>> {
let mut file = File::open(filename)?;
let mut content = String::new();
file.read_to_string(&mut content)?;
@@ -18,6 +18,53 @@ pub fn read_state_from_file(filename: &str) -> Result<(engine::settings::GameSet
Ok((engine_settings, engine_state))
}
+pub fn read_bitwise_state_from_file(filename: &str) -> Result<bitwise_engine::BitwiseGameState, Box<Error>> {
+ //TODO
+ Ok(bitwise_engine::BitwiseGameState {
+ status: engine::GameStatus::Continue,
+ player: engine::Player {
+ energy: 0, health: 0, energy_generated: 0
+ },
+ opponent: engine::Player {
+ energy: 0, health: 0, energy_generated: 0
+ },
+ player_buildings: bitwise_engine::PlayerBuildings {
+ unconstructed: Vec::new(),
+ buildings: [0,0,0,0],
+ energy_towers: 0,
+ missile_towers: [0,0,0],
+ missiles: [(0,0),(0,0),(0,0),(0,0)],
+ tesla_cooldowns: [bitwise_engine::TeslaCooldown {
+ active: false,
+ pos: engine::geometry::Point::new(0,0),
+ cooldown: 0
+ }, bitwise_engine::TeslaCooldown {
+ active: false,
+ pos: engine::geometry::Point::new(0,0),
+ cooldown: 0
+ }],
+ unoccupied: Vec::new()
+ },
+ opponent_buildings: bitwise_engine::PlayerBuildings {
+ unconstructed: Vec::new(),
+ buildings: [0,0,0,0],
+ energy_towers: 0,
+ missile_towers: [0,0,0],
+ missiles: [(0,0),(0,0),(0,0),(0,0)],
+ tesla_cooldowns: [bitwise_engine::TeslaCooldown {
+ active: false,
+ pos: engine::geometry::Point::new(0,0),
+ cooldown: 0
+ }, bitwise_engine::TeslaCooldown {
+ active: false,
+ pos: engine::geometry::Point::new(0,0),
+ cooldown: 0
+ }],
+ unoccupied: Vec::new()
+ }
+ })
+}
+
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct State {
diff --git a/src/main.rs b/src/main.rs
index 61e2e55..fa9216e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -40,7 +40,7 @@ fn write_command(filename: &str, command: Command) -> Result<(), Box<Error> > {
fn main() {
let start_time = PreciseTime::now();
- let (settings, state) = match input::json::read_state_from_file(STATE_PATH) {
+ let (settings, state) = match input::json::read_expressive_state_from_file(STATE_PATH) {
Ok(ok) => ok,
Err(error) => {
println!("Error while parsing JSON file: {}", error);
diff --git a/src/strategy/monte_carlo.rs b/src/strategy/monte_carlo.rs
index dae74bc..19e663d 100644
--- a/src/strategy/monte_carlo.rs
+++ b/src/strategy/monte_carlo.rs
@@ -185,7 +185,7 @@ fn sensible_buildings(settings: &GameSettings, player: &Player, has_max_teslas:
for b in BuildingType::all().iter() {
let building_setting = settings.building_settings(*b);
let affordable = building_setting.price <= player.energy;
- let is_tesla = b == BuildingType::Tesla;
+ let is_tesla = *b == BuildingType::Tesla;
if affordable && (!is_tesla || !has_max_teslas) {
result.push(*b);
}
diff --git a/tests/bigstate.json b/tests/bigstate.json
deleted file mode 100644
index 2ad555f..0000000
--- a/tests/bigstate.json
+++ /dev/null
@@ -1,1498 +0,0 @@
-{
- "gameDetails": {
- "round": 0,
- "mapWidth": 20,
- "mapHeight": 10,
- "roundIncomeEnergy": 5,
- "buildingPrices": {
- "TESLA": 300,
- "ENERGY": 20,
- "ATTACK": 30,
- "DEFENSE": 30
- },
- "buildingsStats": {
- "TESLA": {
- "health": 5,
- "constructionTime": 11,
- "price": 300,
- "weaponDamage": 20,
- "weaponSpeed": 0,
- "weaponCooldownPeriod": 10,
- "energyGeneratedPerTurn": 0,
- "destroyMultiplier": 1,
- "constructionScore": 1
- },
- "ENERGY": {
- "health": 5,
- "constructionTime": 2,
- "price": 20,
- "weaponDamage": 0,
- "weaponSpeed": 0,
- "weaponCooldownPeriod": 0,
- "energyGeneratedPerTurn": 3,
- "destroyMultiplier": 1,
- "constructionScore": 1
- },
- "ATTACK": {
- "health": 5,
- "constructionTime": 2,
- "price": 30,
- "weaponDamage": 5,
- "weaponSpeed": 1,
- "weaponCooldownPeriod": 3,
- "energyGeneratedPerTurn": 0,
- "destroyMultiplier": 1,
- "constructionScore": 1
- },
- "DEFENSE": {
- "health": 20,
- "constructionTime": 4,
- "price": 30,
- "weaponDamage": 0,
- "weaponSpeed": 0,
- "weaponCooldownPeriod": 0,
- "energyGeneratedPerTurn": 0,
- "destroyMultiplier": 1,
- "constructionScore": 1
- }
- }
- },
- "players": [
- {
- "playerType": "A",
- "energy": 20,
- "health": 100,
- "hitsTaken": 0,
- "score": 0
- },
- {
- "playerType": "B",
- "energy": 20,
- "health": 100,
- "hitsTaken": 0,
- "score": 0
- }
- ],
- "gameMap": [
- [
- {
- "x": 0,
- "y": 0,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 1,
- "y": 0,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 2,
- "y": 0,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 3,
- "y": 0,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 4,
- "y": 0,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 5,
- "y": 0,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 6,
- "y": 0,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 7,
- "y": 0,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 8,
- "y": 0,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 9,
- "y": 0,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 10,
- "y": 0,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 11,
- "y": 0,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 12,
- "y": 0,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 13,
- "y": 0,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 14,
- "y": 0,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 15,
- "y": 0,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 16,
- "y": 0,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 17,
- "y": 0,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 18,
- "y": 0,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 19,
- "y": 0,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- }
- ],
- [
- {
- "x": 0,
- "y": 1,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 1,
- "y": 1,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 2,
- "y": 1,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 3,
- "y": 1,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 4,
- "y": 1,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 5,
- "y": 1,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 6,
- "y": 1,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 7,
- "y": 1,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 8,
- "y": 1,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 9,
- "y": 1,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 10,
- "y": 1,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 11,
- "y": 1,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 12,
- "y": 1,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 13,
- "y": 1,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 14,
- "y": 1,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 15,
- "y": 1,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 16,
- "y": 1,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 17,
- "y": 1,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 18,
- "y": 1,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 19,
- "y": 1,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- }
- ],
- [
- {
- "x": 0,
- "y": 2,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 1,
- "y": 2,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 2,
- "y": 2,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 3,
- "y": 2,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 4,
- "y": 2,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 5,
- "y": 2,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 6,
- "y": 2,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 7,
- "y": 2,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 8,
- "y": 2,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 9,
- "y": 2,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 10,
- "y": 2,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 11,
- "y": 2,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 12,
- "y": 2,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 13,
- "y": 2,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 14,
- "y": 2,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 15,
- "y": 2,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 16,
- "y": 2,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 17,
- "y": 2,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 18,
- "y": 2,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 19,
- "y": 2,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- }
- ],
- [
- {
- "x": 0,
- "y": 3,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 1,
- "y": 3,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 2,
- "y": 3,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 3,
- "y": 3,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 4,
- "y": 3,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 5,
- "y": 3,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 6,
- "y": 3,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 7,
- "y": 3,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 8,
- "y": 3,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 9,
- "y": 3,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 10,
- "y": 3,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 11,
- "y": 3,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 12,
- "y": 3,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 13,
- "y": 3,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 14,
- "y": 3,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 15,
- "y": 3,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 16,
- "y": 3,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 17,
- "y": 3,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 18,
- "y": 3,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 19,
- "y": 3,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- }
- ],
- [
- {
- "x": 0,
- "y": 4,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 1,
- "y": 4,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 2,
- "y": 4,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 3,
- "y": 4,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 4,
- "y": 4,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 5,
- "y": 4,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 6,
- "y": 4,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 7,
- "y": 4,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 8,
- "y": 4,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 9,
- "y": 4,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 10,
- "y": 4,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 11,
- "y": 4,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 12,
- "y": 4,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 13,
- "y": 4,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 14,
- "y": 4,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 15,
- "y": 4,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 16,
- "y": 4,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 17,
- "y": 4,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 18,
- "y": 4,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 19,
- "y": 4,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- }
- ],
- [
- {
- "x": 0,
- "y": 5,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 1,
- "y": 5,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 2,
- "y": 5,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 3,
- "y": 5,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 4,
- "y": 5,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 5,
- "y": 5,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 6,
- "y": 5,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 7,
- "y": 5,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 8,
- "y": 5,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 9,
- "y": 5,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 10,
- "y": 5,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 11,
- "y": 5,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 12,
- "y": 5,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 13,
- "y": 5,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 14,
- "y": 5,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 15,
- "y": 5,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 16,
- "y": 5,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 17,
- "y": 5,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 18,
- "y": 5,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 19,
- "y": 5,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- }
- ],
- [
- {
- "x": 0,
- "y": 6,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 1,
- "y": 6,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 2,
- "y": 6,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 3,
- "y": 6,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 4,
- "y": 6,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 5,
- "y": 6,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 6,
- "y": 6,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 7,
- "y": 6,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 8,
- "y": 6,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 9,
- "y": 6,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 10,
- "y": 6,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 11,
- "y": 6,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 12,
- "y": 6,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 13,
- "y": 6,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 14,
- "y": 6,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 15,
- "y": 6,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 16,
- "y": 6,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 17,
- "y": 6,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 18,
- "y": 6,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 19,
- "y": 6,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- }
- ],
- [
- {
- "x": 0,
- "y": 7,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 1,
- "y": 7,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 2,
- "y": 7,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 3,
- "y": 7,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 4,
- "y": 7,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 5,
- "y": 7,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 6,
- "y": 7,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 7,
- "y": 7,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 8,
- "y": 7,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 9,
- "y": 7,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 10,
- "y": 7,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 11,
- "y": 7,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 12,
- "y": 7,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 13,
- "y": 7,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 14,
- "y": 7,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 15,
- "y": 7,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 16,
- "y": 7,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 17,
- "y": 7,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 18,
- "y": 7,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 19,
- "y": 7,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- }
- ],
- [
- {
- "x": 0,
- "y": 8,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 1,
- "y": 8,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 2,
- "y": 8,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 3,
- "y": 8,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 4,
- "y": 8,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 5,
- "y": 8,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 6,
- "y": 8,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 7,
- "y": 8,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 8,
- "y": 8,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 9,
- "y": 8,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 10,
- "y": 8,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 11,
- "y": 8,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 12,
- "y": 8,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 13,
- "y": 8,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 14,
- "y": 8,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 15,
- "y": 8,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 16,
- "y": 8,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 17,
- "y": 8,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 18,
- "y": 8,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 19,
- "y": 8,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- }
- ],
- [
- {
- "x": 0,
- "y": 9,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 1,
- "y": 9,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 2,
- "y": 9,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 3,
- "y": 9,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 4,
- "y": 9,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 5,
- "y": 9,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 6,
- "y": 9,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 7,
- "y": 9,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 8,
- "y": 9,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 9,
- "y": 9,
- "buildings": [],
- "missiles": [],
- "cellOwner": "A"
- },
- {
- "x": 10,
- "y": 9,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 11,
- "y": 9,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 12,
- "y": 9,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 13,
- "y": 9,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 14,
- "y": 9,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 15,
- "y": 9,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 16,
- "y": 9,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 17,
- "y": 9,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 18,
- "y": 9,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- },
- {
- "x": 19,
- "y": 9,
- "buildings": [],
- "missiles": [],
- "cellOwner": "B"
- }
- ]
- ]
-}
diff --git a/tests/expressive_to_bitwise_comparison.rs b/tests/expressive_to_bitwise_comparison.rs
new file mode 100644
index 0000000..c89c542
--- /dev/null
+++ b/tests/expressive_to_bitwise_comparison.rs
@@ -0,0 +1,129 @@
+extern crate zombot;
+
+#[macro_use] extern crate proptest;
+extern crate rand;
+
+use zombot::input;
+use zombot::engine::command::{Command, BuildingType};
+use zombot::engine::geometry::Point;
+use zombot::engine::settings::GameSettings;
+use zombot::engine::{GameState, GameStatus, Player};
+
+use zombot::engine::expressive_engine;
+use zombot::engine::bitwise_engine;
+
+use proptest::prelude::*;
+
+use rand::{Rng, XorShiftRng, SeedableRng};
+
+
+const STATE_PATH: &str = "tests/state0.json";
+
+proptest! {
+ #[test]
+ fn follows_the_same_random_game_tree(seed in any::<[u32;4]>()) {
+ let mut rng = XorShiftRng::from_seed(seed);
+
+ let (settings, mut expressive_state) = input::json::read_expressive_state_from_file(STATE_PATH).expect("Failed to load expressive state");
+ let mut bitwise_state = input::json::read_bitwise_state_from_file(STATE_PATH).expect("Failed to load bitwise state");
+
+ let mut expected_status = GameStatus::Continue;
+ while expected_status == GameStatus::Continue {
+ let player_command = random_player_move(&settings, &expressive_state, &mut rng);
+ let opponent_command = random_opponent_move(&settings, &expressive_state, &mut rng);
+
+ expected_status = expressive_state.simulate(&settings, player_command, opponent_command);
+ let actual_status = bitwise_state.simulate(&settings, player_command, opponent_command);
+
+ assert_eq!(&expected_status, &actual_status);
+ assert_eq!(build_bitwise_from_expressive(&expressive_state), bitwise_state.clone());
+ }
+ }
+}
+
+
+
+fn random_player_move<R: Rng, GS: GameState>(settings: &GameSettings, state: &GS, rng: &mut R) -> Command {
+ let all_buildings = sensible_buildings(settings, &state.player(), state.player_has_max_teslas());
+ random_move(&state.unoccupied_player_cells(), &all_buildings, rng)
+}
+
+fn random_opponent_move<R: Rng, GS: GameState>(settings: &GameSettings, state: &GS, rng: &mut R) -> Command {
+ let all_buildings = sensible_buildings(settings, &state.opponent(), state.opponent_has_max_teslas());
+ random_move(&state.unoccupied_opponent_cells(), &all_buildings, rng)
+}
+
+fn random_move<R: Rng>(free_positions: &[Point], all_buildings: &[BuildingType], rng: &mut R) -> Command {
+
+ let building_command_count = free_positions.len()*all_buildings.len();
+ let nothing_count = 1;
+
+ let number_of_commands = building_command_count + nothing_count;
+
+ let choice_index = rng.gen_range(0, number_of_commands);
+
+ if choice_index == number_of_commands - 1 {
+ Command::Nothing
+ } else {
+ Command::Build(
+ free_positions[choice_index/all_buildings.len()],
+ all_buildings[choice_index%all_buildings.len()]
+ )
+ }
+}
+
+fn sensible_buildings(settings: &GameSettings, player: &Player, has_max_teslas: bool) -> Vec<BuildingType> {
+ let mut result = Vec::with_capacity(4);
+ for b in BuildingType::all().iter() {
+ let building_setting = settings.building_settings(*b);
+ let affordable = building_setting.price <= player.energy;
+ let is_tesla = *b == BuildingType::Tesla;
+ if affordable && (!is_tesla || !has_max_teslas) {
+ result.push(*b);
+ }
+ }
+ result
+}
+
+fn build_bitwise_from_expressive(expressive: &expressive_engine::ExpressiveGameState) -> bitwise_engine::BitwiseGameState {
+ //TODO
+ bitwise_engine::BitwiseGameState {
+ status: expressive.status,
+ player: expressive.player.clone(),
+ opponent: expressive.opponent.clone(),
+ player_buildings: bitwise_engine::PlayerBuildings {
+ unconstructed: Vec::new(),
+ buildings: [0,0,0,0],
+ energy_towers: 0,
+ missile_towers: [0,0,0],
+ missiles: [(0,0),(0,0),(0,0),(0,0)],
+ tesla_cooldowns: [bitwise_engine::TeslaCooldown {
+ active: false,
+ pos: Point::new(0,0),
+ cooldown: 0
+ }, bitwise_engine::TeslaCooldown {
+ active: false,
+ pos: Point::new(0,0),
+ cooldown: 0
+ }],
+ unoccupied: Vec::new()
+ },
+ opponent_buildings: bitwise_engine::PlayerBuildings {
+ unconstructed: Vec::new(),
+ buildings: [0,0,0,0],
+ energy_towers: 0,
+ missile_towers: [0,0,0],
+ missiles: [(0,0),(0,0),(0,0),(0,0)],
+ tesla_cooldowns: [bitwise_engine::TeslaCooldown {
+ active: false,
+ pos: Point::new(0,0),
+ cooldown: 0
+ }, bitwise_engine::TeslaCooldown {
+ active: false,
+ pos: Point::new(0,0),
+ cooldown: 0
+ }],
+ unoccupied: Vec::new()
+ }
+ }
+}
diff --git a/tests/live_comparison.rs b/tests/live_comparison.rs
index 20dbb2f..91d3530 100644
--- a/tests/live_comparison.rs
+++ b/tests/live_comparison.rs
@@ -20,12 +20,12 @@ fn it_successfully_simulates_replay_with_teslas() {
}
fn test_from_replay(replay_folder: &str, length: usize) {
- let (settings, mut state) = json::read_state_from_file(&format!("{}/Round 000/state.json", replay_folder)).unwrap();
+ let (settings, mut state) = json::read_expressive_state_from_file(&format!("{}/Round 000/state.json", replay_folder)).unwrap();
for i in 0..length {
let player = read_player_command(&format!("{}/Round {:03}/PlayerCommand.txt", replay_folder, i));
let opponent = read_opponent_command(&format!("{}/Round {:03}/OpponentCommand.txt", replay_folder, i), &settings);
- let (_, mut expected_state) = json::read_state_from_file(&format!("{}/Round {:03}/state.json", replay_folder, i+1)).unwrap();
+ let (_, mut expected_state) = json::read_expressive_state_from_file(&format!("{}/Round {:03}/state.json", replay_folder, i+1)).unwrap();
state.simulate(&settings, player, opponent);
state.sort();
diff --git a/tests/monte_carlo_test.rs b/tests/monte_carlo_test.rs
index 479b36d..43476fd 100644
--- a/tests/monte_carlo_test.rs
+++ b/tests/monte_carlo_test.rs
@@ -10,7 +10,7 @@ const STATE_PATH: &str = "tests/state0.json";
#[test]
fn it_does_a_normal_turn_successfully() {
let start_time = PreciseTime::now();
- let (settings, state) = match input::json::read_state_from_file(STATE_PATH) {
+ let (settings, state) = match input::json::read_expressive_state_from_file(STATE_PATH) {
Ok(ok) => ok,
Err(error) => panic!("Error while parsing JSON file: {}", error)
};