diff --git a/2018/day15/Cargo.lock b/2018/day15/Cargo.lock new file mode 100644 index 0000000..7158e08 --- /dev/null +++ b/2018/day15/Cargo.lock @@ -0,0 +1,278 @@ +[[package]] +name = "aho-corasick" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "atty" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cfg-if" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "chrono" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "day15" +version = "0.1.0" +dependencies = [ + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "pretty_env_logger 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "env_logger" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "humantime" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lazy_static" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.45" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "log" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memchr" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-integer" +version = "0.1.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "pretty_env_logger" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quick-error" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "redox_syscall" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "redox_termios" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "termcolor" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "termion" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thread_local" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "time" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ucd-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "utf8-ranges" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "version_check" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "wincolor" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[metadata] +"checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e" +"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" +"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" +"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" +"checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38" +"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" +"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" +"checksum libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)" = "2d2857ec59fadc0773853c664d2d18e7198e83883e7060b63c924cb077bd5c74" +"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" +"checksum memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "db4c41318937f6e76648f42826b1d9ade5c09cafb5aef7e351240a70f39206e9" +"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" +"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" +"checksum pretty_env_logger 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8d1e63042e889b85228620629b51c011d380eed2c7e0015f8a644def280c28" +"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" +"checksum redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "a84bcd297b87a545980a2d25a0beb72a1f490c31f0a9fde52fca35bfbb1ceb70" +"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" +"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f" +"checksum regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4e47a2ed29da7a9e1960e1639e7a982e6edc6d49be308a3b02daf511504a16d1" +"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" +"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" +"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" +"checksum time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "847da467bf0db05882a9e2375934a8a55cffdc9db0d128af1518200260ba1f6c" +"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" +"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" +"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" +"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +"checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" diff --git a/2018/day15/Cargo.toml b/2018/day15/Cargo.toml new file mode 100644 index 0000000..7e80893 --- /dev/null +++ b/2018/day15/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "day15" +version = "0.1.0" +authors = ["Andrew Coleman "] +edition = "2018" + +[dependencies] +log = "0.4" +pretty_env_logger = "0.2" diff --git a/2018/day15/input b/2018/day15/input new file mode 100644 index 0000000..0fe82d1 --- /dev/null +++ b/2018/day15/input @@ -0,0 +1,32 @@ +################################ +##########################.##### +##########################.##### +##########################.#.### +#######################......### +#################....#........## +##############.##....G......G.## +#############..#G...##.........# +#############.GG..G..##.......## +#############.................## +#############G.........G....#.## +###########G..........E........# +###########...#####............# +###########..#######...........# +#######.....#########........### +#######....G#########.......#### +##...G.G....#########...#....### +#...G..G...G#########.###E...### +##.......#..#########.#####..E## +#............#######..########## +#.GG........G.#####...########## +#................E.....######### +########..........##.########### +#########.....###.....########## +##########.E..##......########## +#######..#....###.E...########## +######.........###.E############ +######.#..G....##..############# +######.....##..##.E############# +#######....##.E...E############# +######....G#......############## +################################ diff --git a/2018/day15/src/main.rs b/2018/day15/src/main.rs new file mode 100644 index 0000000..b535c46 --- /dev/null +++ b/2018/day15/src/main.rs @@ -0,0 +1,364 @@ +#[macro_use] +extern crate log; +extern crate pretty_env_logger; + +use std::collections::{HashSet, VecDeque}; +use std::fs::File; +use std::io::{BufRead, BufReader}; + +type MapType = [[char; MAP_SIZE]; MAP_SIZE]; +const MAP_SIZE: usize = 32; +const EMPTY_SPACE: char = '.'; + +#[derive(Copy, Clone, Debug)] +struct Player { + id: usize, + x: usize, + y: usize, + dead: bool, + attack: i16, + hp: i16, + player_type: char, + enemy_type: char, +} + +#[derive(Debug)] +struct PlayerVector { + weight: usize, + x: usize, + y: usize, +} + +fn has_enemy_neighbor(player: &Player, players: &Vec, map: &MapType) -> Option { + let mut hps = [0i16; 4]; + let mut min_hp = std::i16::MAX; + let mut indexes = [0usize; 4]; + if map[player.x][player.y - 1] == player.enemy_type { + let (i, target) = players + .iter() + .enumerate() + .find(|p| !p.1.dead && p.1.x == player.x && p.1.y == player.y - 1) + .expect("could not find the target north"); + hps[0] = target.hp; + indexes[0] = i; + if target.hp < min_hp { + min_hp = target.hp; + } + } + if map[player.x - 1][player.y] == player.enemy_type { + let (i, target) = players + .iter() + .enumerate() + .find(|p| !p.1.dead && p.1.x == player.x - 1 && p.1.y == player.y) + .expect("could not find the target west"); + hps[1] = target.hp; + indexes[1] = i; + if target.hp < min_hp { + min_hp = target.hp; + } + } + if map[player.x + 1][player.y] == player.enemy_type { + let (i, target) = players + .iter() + .enumerate() + .find(|p| !p.1.dead && p.1.x == player.x + 1 && p.1.y == player.y) + .expect("could not find the target east"); + hps[2] = target.hp; + indexes[2] = i; + if target.hp < min_hp { + min_hp = target.hp; + } + } + if map[player.x][player.y + 1] == player.enemy_type { + let (i, target) = players + .iter() + .enumerate() + .find(|p| !p.1.dead && p.1.x == player.x && p.1.y == player.y + 1) + .expect("could not find the target south"); + hps[3] = target.hp; + indexes[3] = i; + if target.hp < min_hp { + min_hp = target.hp; + } + } + + if hps[0] == min_hp { + Some(indexes[0]) + } else if hps[1] == min_hp { + Some(indexes[1]) + } else if hps[2] == min_hp { + Some(indexes[2]) + } else if hps[3] == min_hp { + Some(indexes[3]) + } else { + None + } +} + +fn find_next_move(player: &Player, map: &MapType) -> Option { + match find_enemy(player, map) { + Some(target) => { + debug!("found target {:?}", target); + let best_direction = find_best_direction_to_player(player, map, &target); + debug!("best direction {:?}", best_direction); + best_direction + } + None => None, + } +} + +fn find_enemy(player: &Player, map: &MapType) -> Option { + let mut visited = HashSet::new(); + let mut queue = VecDeque::new(); + queue.push_back(PlayerVector { + x: player.x, + y: player.y, + weight: 0, + }); + while let Some(coord) = queue.pop_front() { + if !visited.insert((coord.x, coord.y)) { + continue; + } + if map[coord.x][coord.y] == player.enemy_type { + return Some(coord); + } + if coord.weight > 0 { + match map[coord.x][coord.y] { + 'E' => continue, + 'G' => continue, + '#' => continue, + _ => () + } + } + queue.push_back(PlayerVector { + x: coord.x, + y: coord.y - 1, + weight: coord.weight + 1, + }); + queue.push_back(PlayerVector { + x: coord.x - 1, + y: coord.y, + weight: coord.weight + 1, + }); + queue.push_back(PlayerVector { + x: coord.x + 1, + y: coord.y, + weight: coord.weight + 1, + }); + queue.push_back(PlayerVector { + x: coord.x, + y: coord.y + 1, + weight: coord.weight + 1, + }); + } + None +} + +fn find_best_direction_to_player( + player: &Player, + map: &MapType, + source: &PlayerVector, +) -> Option { + let mut visited = HashSet::new(); + let mut queue = VecDeque::new(); + queue.push_back(PlayerVector { + x: source.x, + y: source.y, + weight: 0, + }); + visited.insert((source.x, source.y)); + let mut destinations = HashSet::new(); + destinations.insert((player.x, player.y - 1)); + destinations.insert((player.x - 1, player.y)); + destinations.insert((player.x + 1, player.y)); + destinations.insert((player.x, player.y + 1)); + while let Some(coord) = queue.pop_front() { + if coord.weight > 0 { + if !visited.insert((coord.x, coord.y)) { + continue; + } + if map[coord.x][coord.y] != EMPTY_SPACE { + continue; + } + } + // it's weight - 1 because we are only travelling to the neighbor cell + if coord.weight == source.weight - 1 && destinations.contains(&(coord.x, coord.y)) { + return Some(coord); + } + queue.push_back(PlayerVector { + x: coord.x, + y: coord.y - 1, + weight: coord.weight + 1, + }); + queue.push_back(PlayerVector { + x: coord.x - 1, + y: coord.y, + weight: coord.weight + 1, + }); + queue.push_back(PlayerVector { + x: coord.x + 1, + y: coord.y, + weight: coord.weight + 1, + }); + queue.push_back(PlayerVector { + x: coord.x, + y: coord.y + 1, + weight: coord.weight + 1, + }); + } + None +} + +fn play_game(mut players: Vec, map: &mut MapType) -> (i32, usize) { + let mut rounds = 0; + let player_count = players.len(); + loop { + info!("round {}", rounds); + for i in 0..MAP_SIZE { + let mut row = String::new(); + for j in 0..MAP_SIZE { + row.push(map[j][i]); + } + debug!("{}", row); + } + players.sort_by(|a, b| { + if a.y == b.y { + a.x.cmp(&b.x) + } else { + a.y.cmp(&b.y) + } + }); + + let mut quit_condition = false; + for i in 0..player_count { + let mut player = players[i]; + if player.dead { + continue; + } + debug!("{:?}", player); + + if !players + .iter() + .any(|p| !p.dead && p.enemy_type == player.player_type) + { + if i < player_count - 1 { + debug!("quitting before end of round"); + quit_condition = true; + } + break; + } + + match has_enemy_neighbor(&player, &players, map) { + Some(_) => { + debug!("have enemy neighbor, no moving allowed"); + () + } + None => match find_next_move(&player, map) { + Some(new_vect) => { + debug!("moving"); + map[player.x][player.y] = EMPTY_SPACE; + players[i].x = new_vect.x; + players[i].y = new_vect.y; + player.x = new_vect.x; + player.y = new_vect.y; + map[new_vect.x][new_vect.y] = player.player_type; + } + None => (), + }, + } + match has_enemy_neighbor(&player, &players, map) { + Some(enemy_index) => { + debug!("attacking {:?}", players[enemy_index]); + players[enemy_index].hp -= player.attack; + if players[enemy_index].hp <= 0 { + debug!("enemy is dead"); + players[enemy_index].dead = true; + players[enemy_index].hp = 0; + map[players[enemy_index].x][players[enemy_index].y] = EMPTY_SPACE; + } + } + None => { + debug!("no enemy neighbors, ending turn"); + () + } + } + } + + if quit_condition { + debug!("quitting condition"); + break; + } + + rounds += 1; + } + + let sum: i32 = players.iter().map(|p| p.hp as i32).sum(); + info!("sum {} rounds {}", sum, rounds); + let elf_count = players.iter().filter(|p| p.player_type == 'E' && !p.dead).count(); + (sum * rounds, elf_count) +} + +fn main() { + pretty_env_logger::init(); + let lines: Vec = BufReader::new(File::open("input").unwrap()) + .lines() + .map(|line| line.unwrap()) + .collect(); + let mut map = [[EMPTY_SPACE; MAP_SIZE]; MAP_SIZE]; + let mut y = 0; + let mut players: Vec = Vec::with_capacity(20); + let mut id = 0; + let mut elf_count = 0; + for line in lines.iter() { + for (x, c) in line.char_indices() { + map[x][y] = c; + if c == '.' { + map[x][y] = EMPTY_SPACE; + } + if c != 'E' && c != 'G' { + continue; + } + if c == 'E' { + elf_count += 1; + } + let enemy_type = if c == 'E' { 'G' } else { 'E' }; + id += 1; + players.push(Player { + id, + x, + y, + dead: false, + attack: 3, + hp: 200, + player_type: c, + enemy_type, + }); + } + y += 1; + } + let (score, _elves_remaining) = play_game(players.clone(), &mut map.clone()); + println!("score of winning team is {}", score); + for i in 4..50 { + let new_players: Vec = players.clone().into_iter().map(|p| { + if p.player_type == 'G' { + p + } else { + Player { + id: p.id, + x: p.x, + y: p.y, + dead: false, + attack: i, + hp: 200, + player_type: 'E', + enemy_type: 'G' + } + } + }).collect(); + let (score, elves_remaining) = play_game(new_players, &mut map.clone()); + if elves_remaining == elf_count { + println!("all elves survived with a score of {} with attack of {}", score, i); + break; + } + } +}