day15 part1 done

This commit is contained in:
Johannes
2018-12-18 19:11:55 +01:00
parent ac3a741f0d
commit 3f2ff6e5a2
2 changed files with 75 additions and 22 deletions

View File

@@ -1,7 +1,32 @@
#######
#.G...#
#...EG#
#.#.#G#
#..G#E#
#.....#
#######
################################
####################.......#####
##################.G.......###.#
##################...G.........#
#############................###
############..............######
############...##......#########
############...G.....#.#########
##..##........G##.........######
##..##.....#.G...........E#..###
##..##.....#.....G......G..E..##
##G............................#
#....G........#####..G.........#
#......#.G...#######..E.......##
#...##..G...#########E.....#####
##...G.#....#########.....######
######G.G...#########..#.#######
######.#...G#########.##########
#####.......#########.##########
#####.GE.....#######..##########
#####.....E...#####...##########
#######....G..........##########
#######..........G..############
######.G............############
#########...........#..#########
############..........##########
############E...E.##...#########
#############.....E..E.#########
##############.........#########
##############...#....##########
###############..#.#############
################################

View File

@@ -14,15 +14,12 @@ pub fn task1() {
let mut round = 0;
while game.round() {
round += 1;
println!("{}", game);
println!("{:?}", game.units);
}
println!("Final full round was {}", round);
println!(
"Remaining HP: {}",
game.units.iter().map(|it| it.health).sum::<i32>()
"Result: {}",
game.units.iter().map(|it| it.health).sum::<i32>() * round as i32
);
println!("{:?}", game.units);
}
#[derive(Clone, PartialEq)]
@@ -63,6 +60,20 @@ impl Position {
.map(|it| Position(it.0 as usize, it.1 as usize))
.collect()
}
fn manhattan_distance(&self, other: &Self) -> usize {
let a = if self.0 > other.0 {
self.0 - other.0
} else {
other.0 - self.0
};
let b = if self.1 > other.1 {
self.1 - other.1
} else {
other.1 - self.1
};
a + b
}
}
impl PartialOrd for Position {
@@ -134,7 +145,7 @@ impl Game {
if let Some((_, best)) = input
.iter()
.filter_map(|(delta, start)| {
let map = Map::from_game(&self, *start);
let map = Map::from_game(&self, from);
if let Some(path) = map.shortest_path(*start, to) {
Some((delta + path.len() * 10, *path.first().unwrap_or(start)))
} else {
@@ -170,14 +181,14 @@ impl Game {
self.units[curr].position,
self.units[curr].warrior_type.enemy_type(),
) {
if let Some(next_position) =
self.next_position(self.units[curr].position, next_target_position)
{
let curr_pos = self.units[curr].position;
self.tiles[curr_pos.0][curr_pos.1] = Tile::Empty;
self.units[curr].position = next_position;
} else {
panic!("We have a reachable target but no path to it!");
if self.units[curr].position != next_target_position {
if let Some(next_position) =
self.next_position(self.units[curr].position, next_target_position)
{
self.units[curr].position = next_position;
} else {
panic!("We have a reachable target but no path to it! {:?} wants to go to {:?}", self.units[curr], next_target_position);
}
}
}
@@ -187,6 +198,7 @@ impl Game {
.units
.iter()
.enumerate()
.filter(|(_, it)| it.warrior_type == self.units[curr].warrior_type.enemy_type())
.filter(|(_, it)| neighbors.contains(&it.position))
.map(|(i, _)| i)
.collect();
@@ -200,6 +212,13 @@ impl Game {
}
});
if let Some(closest_index) = close_enemies.first() {
if self.units[*closest_index]
.position
.manhattan_distance(&self.units[curr].position)
> 1
{
panic!("Distance WTF")
}
let enemy = &mut self.units[*closest_index];
enemy.health -= ATTACK_POWER;
if enemy.health <= 0 {
@@ -327,11 +346,14 @@ impl Map {
for y in 0..game.height {
new.push(match &game.tiles[x][y] {
Tile::Empty => MapTile::Empty,
_ => MapTile::Occupied,
Tile::Wall => MapTile::Occupied,
});
}
fields.push(new);
}
for warrior in game.units.iter() {
fields[warrior.position.0][warrior.position.1] = MapTile::Occupied;
}
fields[clear.0][clear.1] = MapTile::Empty;
Map {
fields: fields,
@@ -356,6 +378,9 @@ impl Map {
if curr_pos == to {
break;
}
if self.fields[curr_pos.0][curr_pos.1] != MapTile::Empty {
continue;
}
for pos in curr_pos.neighbors(self.width, self.height) {
if !predecessors.contains_key(&pos) && !open.iter().any(|it| it.1 == pos) {
open.push_back((Some(curr_pos), pos));
@@ -394,6 +419,9 @@ impl Map {
// all others would have a higher distance and therefore are not relevant
continue;
}
if self.fields[curr_pos.0][curr_pos.1] == MapTile::Occupied {
continue;
}
for pos in curr_pos.neighbors(self.width, self.height) {
if !visited.contains(&pos) && !open.iter().any(|it| it.1 == pos) {
open.push_back((curr_dist + 1, pos));