summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Cargo.lock92
-rw-r--r--Cargo.toml5
-rw-r--r--src/actions.rs4
-rw-r--r--src/files.rs21
-rw-r--r--src/knowledge.rs54
-rw-r--r--src/lib.rs25
-rw-r--r--src/math.rs4
-rw-r--r--src/ships.rs19
-rw-r--r--src/state.rs30
10 files changed, 244 insertions, 11 deletions
diff --git a/.gitignore b/.gitignore
index 54466f5..a41bb2d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
/target
+/knowledge-state.json
diff --git a/Cargo.lock b/Cargo.lock
index 652adca..96ea518 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4,9 +4,22 @@ version = "0.1.0"
dependencies = [
"json 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
+name = "dtoa"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "itoa"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "json"
version = "0.11.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -17,6 +30,16 @@ version = "0.2.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "num-traits"
+version = "0.1.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "quote"
+version = "0.3.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "rand"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -24,7 +47,76 @@ dependencies = [
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "serde"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "serde_derive"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive_internals 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "serde_derive_internals"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "syn"
+version = "0.11.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "synom"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unicode-xid"
+version = "0.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[metadata]
+"checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90"
+"checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c"
"checksum json 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)" = "27600e8bb3b71bcc6213fb36b66b8dce60adc17a624257687ef5d1d4facafba7"
"checksum libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)" = "babb8281da88cba992fa1f4ddec7d63ed96280a1a53ec9b919fd37b53d71e502"
+"checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99"
+"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
+"checksum serde 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "991ef6be409a3b7a46cb9ee701d86156ce851825c65dbee7f16dbd5c4e7e2d47"
+"checksum serde_derive 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd81eef9f0b4ec341b11095335b6a4b28ed85581b12dd27585dee1529df35e0"
+"checksum serde_derive_internals 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "021c338d22c7e30f957a6ab7e388cb6098499dda9fd4ba1661ee074ca7a180d1"
+"checksum serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "48b04779552e92037212c3615370f6bd57a40ebba7f20e554ff9f55e41a69a7b"
+"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
+"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
+"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
diff --git a/Cargo.toml b/Cargo.toml
index c90a18f..cdebbe8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -5,4 +5,7 @@ authors = ["Justin Worthe <justin.worthe@gmail.com>"]
[dependencies]
rand = "0.3"
-json = "0.11.6" \ No newline at end of file
+json = "0.11.6"
+serde = "1.0.4"
+serde_json = "1.0.2"
+serde_derive = "1.0.4" \ No newline at end of file
diff --git a/src/actions.rs b/src/actions.rs
index 1b6400d..9009099 100644
--- a/src/actions.rs
+++ b/src/actions.rs
@@ -5,7 +5,7 @@ use std::fmt;
use std::collections::HashSet;
-#[derive(Clone, PartialEq, Eq, Debug)]
+#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub enum Action {
PlaceShips(Vec<ShipPlacement>),
Shoot(Point)
@@ -22,7 +22,7 @@ impl fmt::Display for Action {
}
}
-#[derive(Clone, PartialEq, Eq, Debug)]
+#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub struct ShipPlacement {
ship_type: Ship,
point: Point,
diff --git a/src/files.rs b/src/files.rs
index 7f3daed..0810a4e 100644
--- a/src/files.rs
+++ b/src/files.rs
@@ -1,15 +1,21 @@
use json;
+use serde_json;
+
use std::io::prelude::*;
use std::fs::File;
use std::path::PathBuf;
use actions::*;
+use knowledge::*;
const STATE_FILE: &'static str = "state.json";
const COMMAND_FILE: &'static str = "command.txt";
const PLACE_FILE: &'static str = "place.txt";
+const KNOWLEDGE_FILE: &'static str = "knowledge-state.json";
+
+
pub fn read_file(working_dir: &PathBuf) -> Result<json::JsonValue, String> {
let state_path = working_dir.join(STATE_FILE);
let mut file = File::open(state_path.as_path()).map_err(|e| e.to_string())?;
@@ -34,3 +40,18 @@ pub fn write_action(working_dir: &PathBuf, is_place_phase: bool, action: Action)
Ok(())
}
+
+pub fn read_knowledge() -> Result<Knowledge, String> {
+ let mut file = File::open(KNOWLEDGE_FILE).map_err(|e| e.to_string())?;
+ let mut content = String::new();
+ file.read_to_string(&mut content).map_err(|e| e.to_string())?;
+ serde_json::from_str(content.as_ref()).map_err(|e| e.to_string())
+}
+
+pub fn write_knowledge(knowledge: &Knowledge) -> Result<(), String> {
+ let json = serde_json::to_string(knowledge).map_err(|e| e.to_string())?;
+ let mut file = File::create(KNOWLEDGE_FILE).map_err(|e| e.to_string())?;
+ write!(file, "{}", json).map_err(|e| e.to_string())?;
+
+ Ok(())
+}
diff --git a/src/knowledge.rs b/src/knowledge.rs
new file mode 100644
index 0000000..3b0c61a
--- /dev/null
+++ b/src/knowledge.rs
@@ -0,0 +1,54 @@
+use actions::*;
+use ships::*;
+use std::collections::HashMap;
+
+#[derive(Serialize, Deserialize, Clone, Debug)]
+pub struct Knowledge {
+ pub last_action: Option<Action>,
+ pub opponent_map: OpponentMapKnowledge
+}
+
+impl Knowledge {
+ pub fn new() -> Knowledge {
+ Knowledge {
+ last_action: None,
+ opponent_map: OpponentMapKnowledge::new()
+ }
+ }
+
+ pub fn with_action(&self, action: Action) -> Knowledge {
+ Knowledge {
+ last_action: Some(action),
+ opponent_map: self.opponent_map.clone()
+ }
+ }
+}
+
+#[derive(Serialize, Deserialize, Clone, Debug)]
+pub struct OpponentMapKnowledge {
+ pub ships: HashMap<Ship, OpponentShipKnowledge>,
+ pub cells: Vec<Vec<KnowledgeCell>>
+}
+
+impl OpponentMapKnowledge {
+ pub fn new() -> OpponentMapKnowledge {
+ OpponentMapKnowledge {
+ ships: HashMap::new(),
+ cells: Vec::new()
+ }
+ }
+}
+
+#[derive(Serialize, Deserialize, Clone, Debug)]
+pub struct OpponentShipKnowledge {
+ pub destroyed: bool
+}
+
+#[derive(Serialize, Deserialize, Clone, Debug)]
+pub struct KnowledgeCell {
+ pub shot_attempted: bool,
+ pub possible_ship_uses: HashMap<Ship, u16>,
+ pub known_ship: Option<Ship>
+}
+
+
diff --git a/src/lib.rs b/src/lib.rs
index 5dda02f..81dd845 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,5 +1,9 @@
extern crate json;
extern crate rand;
+extern crate serde;
+extern crate serde_json;
+#[macro_use]
+extern crate serde_derive;
mod actions;
mod math;
@@ -8,6 +12,7 @@ mod ships;
mod placement;
mod shooting;
mod state;
+mod knowledge;
use math::*;
use files::*;
@@ -15,17 +20,23 @@ use ships::*;
use placement::*;
use shooting::*;
use state::*;
+use knowledge::*;
use std::path::PathBuf;
pub fn write_move(working_dir: PathBuf) -> Result<(), String> {
let state_json = read_file(&working_dir)?;
- println!("\n\n{}\n\n", state_json.pretty(2));
-
let is_place_phase = state_json["Phase"] == 1;
let map_size = State::map_size_from_json(&state_json)?;
+ let starting_knowledge = if is_place_phase {
+ Knowledge::new()
+ }
+ else {
+ read_knowledge()?
+ };
+
let action = if is_place_phase {
place_ships_randomly(map_size)
}
@@ -34,8 +45,18 @@ pub fn write_move(working_dir: PathBuf) -> Result<(), String> {
shoot_randomly(&state)
};
+ let ending_knowledge = starting_knowledge
+ .with_action(action.clone());
+
+ write_knowledge(&ending_knowledge)
+ .map_err(|e| format!("Failed to write knowledge to file. Error: {}", e))?;
+
write_action(&working_dir, is_place_phase, action)
.map_err(|e| format!("Failed to write action to file. Error: {}", e))?;
+
+ println!("Input state:\n{}\n\n", state_json);
+ println!("Existing knowledge:\n{}\n\n", serde_json::to_string(&starting_knowledge).unwrap_or(String::from("")));
+ println!("End of turn knowledge:\n{}\n\n", serde_json::to_string(&ending_knowledge).unwrap_or(String::from("")));
Ok(())
}
diff --git a/src/math.rs b/src/math.rs
index 8e81348..3d8a976 100644
--- a/src/math.rs
+++ b/src/math.rs
@@ -2,7 +2,7 @@ use std::fmt;
use rand;
use rand::distributions::{IndependentSample, Range};
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
pub enum Direction {
North,
East,
@@ -40,7 +40,7 @@ impl Direction {
}
}
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
pub struct Point {
pub x: u16,
pub y: u16
diff --git a/src/ships.rs b/src/ships.rs
index e21b20e..344f9ed 100644
--- a/src/ships.rs
+++ b/src/ships.rs
@@ -1,6 +1,7 @@
use std::fmt;
+use std::str;
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
pub enum Ship {
Battleship,
Carrier,
@@ -25,6 +26,22 @@ impl fmt::Display for Ship {
}
}
+impl str::FromStr for Ship {
+ type Err = String;
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ use Ship::*;
+
+ match s {
+ "Battleship" => Ok(Battleship),
+ "Carrier" => Ok(Carrier),
+ "Cruiser" => Ok(Cruiser),
+ "Destroyer" => Ok(Destroyer),
+ "Submarine" => Ok(Submarine),
+ _ => Err(String::from("ship type is not known"))
+ }
+ }
+}
+
impl Ship {
pub fn length(&self) -> u16 {
use Ship::*;
diff --git a/src/state.rs b/src/state.rs
index df66ec9..8c176e1 100644
--- a/src/state.rs
+++ b/src/state.rs
@@ -1,4 +1,6 @@
use json;
+use std::collections::HashMap;
+use ships::*;
pub struct State {
pub map_size: u16,
@@ -25,7 +27,8 @@ impl State {
}
pub struct OpponentMap {
- pub cells: Vec<Vec<Cell>>
+ pub cells: Vec<Vec<Cell>>,
+ pub ships: HashMap<Ship, OpponentShip>,
}
impl OpponentMap {
@@ -38,7 +41,7 @@ impl OpponentMap {
}
cells.push(row);
}
-
+
for json_cell in json["Cells"].members() {
let x = json_cell["X"]
.as_u16()
@@ -56,13 +59,34 @@ impl OpponentMap {
cells[x as usize][y as usize].damaged = damaged;
cells[x as usize][y as usize].missed = missed;
}
+
+ let mut ships = HashMap::new();
+ for json_ship in json["Ships"].members() {
+ let ship_type_string = json_ship["ShipType"]
+ .as_str()
+ .ok_or(String::from("Failed to read ShipType value of opponent map ship in json file"))?;
+ let ship_type = ship_type_string.parse::<Ship>()?;
+
+ let destroyed = json_ship["Destroyed"]
+ .as_bool()
+ .ok_or(String::from("Failed to read Destroyed value of opponent map ship in json file"))?;
+ ships.insert(ship_type, OpponentShip {
+ destroyed: destroyed
+ });
+ }
+
Ok(OpponentMap {
- cells: cells
+ cells: cells,
+ ships: ships
})
}
}
+pub struct OpponentShip {
+ pub destroyed: bool
+}
+
pub struct Cell {
pub damaged: bool,
pub missed: bool