day15 part1 done
This commit is contained in:
@@ -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.#########
|
||||
##############.........#########
|
||||
##############...#....##########
|
||||
###############..#.#############
|
||||
################################
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user