diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Cargo.lock | 30 | ||||
-rw-r--r-- | Cargo.toml | 8 | ||||
-rw-r--r-- | bot.json | 8 | ||||
-rw-r--r-- | readme.md | 0 | ||||
-rw-r--r-- | src/main.rs | 119 |
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(()) +} |