summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Cargo.lock30
-rw-r--r--Cargo.toml8
-rw-r--r--bot.json8
-rw-r--r--readme.md0
-rw-r--r--src/main.rs119
6 files changed, 167 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..54466f5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/target
+
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..c499a6e
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,30 @@
+[root]
+name = "100k_worthebot_battleships"
+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)",
+]
+
+[[package]]
+name = "json"
+version = "0.11.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "libc"
+version = "0.2.22"
+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"
+dependencies = [
+ "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[metadata]
+"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 rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..6b43272
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "100k_worthebot_battleships"
+version = "0.1.0"
+authors = ["Justin Worthe <justin.worthe@gmail.com>"]
+
+[dependencies]
+rand = "0.3"
+json = "0.11.6" \ No newline at end of file
diff --git a/bot.json b/bot.json
new file mode 100644
index 0000000..04c2127
--- /dev/null
+++ b/bot.json
@@ -0,0 +1,8 @@
+{
+ "Author":"Justin Worthe",
+ "Email":"justin.worthe@gmail.com",
+ "NickName" :"Admiral Worthebot",
+ "BotType": 8,
+ "ProjectLocation" : "",
+ "RunFile" : "target\\release\\100k_worthebot_battleships"
+}
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/readme.md
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..7c904d6
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,119 @@
+extern crate json;
+extern crate rand;
+
+use std::env;
+use std::path::Path;
+use std::path::PathBuf;
+use std::io::prelude::*;
+use std::fs::File;
+use std::fmt;
+
+use rand::distributions::{IndependentSample, Range};
+
+const COMMAND_FILE: &'static str = "command.txt";
+const PLACE_FILE: &'static str = "place.txt";
+const STATE_FILE: &'static str = "state.json";
+
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
+enum Orientation {
+ North,
+ East,
+ South,
+ West,
+}
+
+impl fmt::Display for Orientation {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str(
+ match self {
+ &Orientation::North => "North",
+ &Orientation::East => "East",
+ &Orientation::South => "South",
+ &Orientation::West => "West"
+ }
+ )
+ }
+}
+
+#[derive(Clone, PartialEq, Eq, Debug)]
+enum Action {
+ PlaceShips(Vec<(String, u32, u32, Orientation)>),
+ Shoot(u32, u32)
+}
+
+impl fmt::Display for Action {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ &Action::Shoot(x, y) => writeln!(f, "1,{},{}", x, y),
+ &Action::PlaceShips(ref ships) => ships.iter().map(|&(ref ship_type, x, y, orientation)| {
+ writeln!(f, "{} {} {} {}", ship_type, x, y, orientation)
+ }).fold(Ok(()), |acc, next| acc.and(next))
+ }
+ }
+}
+
+fn main() {
+ let working_dir = env::args()
+ .nth(2)
+ .map(|pwd| PathBuf::from(pwd))
+ .expect("Requires game state folder to be passed as the second parameter");
+
+ // The state file is read here. Chances are, you'll want to read
+ // more values out of it than the sample bot currently does.
+ let state = read_file(&working_dir).expect("Failed to read state.json");
+
+ let is_place_phase = state["Phase"] == 1;
+ let map_dimension = state["MapDimension"].as_u32().expect("Could not read map dimension from the state");
+
+ let action = if is_place_phase {
+ place_ships()
+ }
+ else {
+ shoot_randomly(map_dimension)
+ };
+
+
+ write_action(&working_dir, is_place_phase, action).expect("Failed to write action to file");
+}
+
+fn read_file(working_dir: &Path) -> 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())?;
+ let mut content = String::new();
+ file.read_to_string(&mut content).map_err(|e| e.to_string())?;
+ json::parse(content.as_ref()).map_err(|e| e.to_string())
+}
+
+fn place_ships() -> Action {
+ let ships = vec!(
+ (String::from("Battleship"), 1, 0, Orientation::North),
+ (String::from("Carrier"), 3, 1, Orientation::East),
+ (String::from("Cruiser"), 4, 2, Orientation::North),
+ (String::from("Destroyer"), 7, 3, Orientation::North),
+ (String::from("Submarine"), 1, 8, Orientation::East)
+ );
+
+ Action::PlaceShips(ships)
+}
+
+fn shoot_randomly(map_dimension: u32) -> Action {
+ let mut rng = rand::thread_rng();
+ let between = Range::new(0, map_dimension);
+ let x = between.ind_sample(&mut rng);
+ let y = between.ind_sample(&mut rng);
+ Action::Shoot(x, y)
+}
+
+fn write_action(working_dir: &Path, is_place_phase: bool, action: Action) -> Result<(), String> {
+ let filename = if is_place_phase {
+ PLACE_FILE
+ }
+ else {
+ COMMAND_FILE
+ };
+
+ let full_filename = working_dir.join(filename);
+ let mut file = File::create(full_filename.as_path()).map_err(|e| e.to_string())?;
+ writeln!(file, "{}", action).map_err(|e| e.to_string())?;
+ Ok(())
+}