day15 part1 done
This commit is contained in:
@@ -1,7 +1,32 @@
|
|||||||
#######
|
################################
|
||||||
#.G...#
|
####################.......#####
|
||||||
#...EG#
|
##################.G.......###.#
|
||||||
#.#.#G#
|
##################...G.........#
|
||||||
#..G#E#
|
#############................###
|
||||||
#.....#
|
############..............######
|
||||||
#######
|
############...##......#########
|
||||||
|
############...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;
|
let mut round = 0;
|
||||||
while game.round() {
|
while game.round() {
|
||||||
round += 1;
|
round += 1;
|
||||||
println!("{}", game);
|
|
||||||
println!("{:?}", game.units);
|
|
||||||
}
|
}
|
||||||
println!("Final full round was {}", round);
|
println!("Final full round was {}", round);
|
||||||
println!(
|
println!(
|
||||||
"Remaining HP: {}",
|
"Result: {}",
|
||||||
game.units.iter().map(|it| it.health).sum::<i32>()
|
game.units.iter().map(|it| it.health).sum::<i32>() * round as i32
|
||||||
);
|
);
|
||||||
println!("{:?}", game.units);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
@@ -63,6 +60,20 @@ impl Position {
|
|||||||
.map(|it| Position(it.0 as usize, it.1 as usize))
|
.map(|it| Position(it.0 as usize, it.1 as usize))
|
||||||
.collect()
|
.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 {
|
impl PartialOrd for Position {
|
||||||
@@ -134,7 +145,7 @@ impl Game {
|
|||||||
if let Some((_, best)) = input
|
if let Some((_, best)) = input
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(delta, start)| {
|
.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) {
|
if let Some(path) = map.shortest_path(*start, to) {
|
||||||
Some((delta + path.len() * 10, *path.first().unwrap_or(start)))
|
Some((delta + path.len() * 10, *path.first().unwrap_or(start)))
|
||||||
} else {
|
} else {
|
||||||
@@ -170,14 +181,14 @@ impl Game {
|
|||||||
self.units[curr].position,
|
self.units[curr].position,
|
||||||
self.units[curr].warrior_type.enemy_type(),
|
self.units[curr].warrior_type.enemy_type(),
|
||||||
) {
|
) {
|
||||||
|
if self.units[curr].position != next_target_position {
|
||||||
if let Some(next_position) =
|
if let Some(next_position) =
|
||||||
self.next_position(self.units[curr].position, next_target_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;
|
self.units[curr].position = next_position;
|
||||||
} else {
|
} else {
|
||||||
panic!("We have a reachable target but no path to it!");
|
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
|
.units
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
|
.filter(|(_, it)| it.warrior_type == self.units[curr].warrior_type.enemy_type())
|
||||||
.filter(|(_, it)| neighbors.contains(&it.position))
|
.filter(|(_, it)| neighbors.contains(&it.position))
|
||||||
.map(|(i, _)| i)
|
.map(|(i, _)| i)
|
||||||
.collect();
|
.collect();
|
||||||
@@ -200,6 +212,13 @@ impl Game {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if let Some(closest_index) = close_enemies.first() {
|
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];
|
let enemy = &mut self.units[*closest_index];
|
||||||
enemy.health -= ATTACK_POWER;
|
enemy.health -= ATTACK_POWER;
|
||||||
if enemy.health <= 0 {
|
if enemy.health <= 0 {
|
||||||
@@ -327,11 +346,14 @@ impl Map {
|
|||||||
for y in 0..game.height {
|
for y in 0..game.height {
|
||||||
new.push(match &game.tiles[x][y] {
|
new.push(match &game.tiles[x][y] {
|
||||||
Tile::Empty => MapTile::Empty,
|
Tile::Empty => MapTile::Empty,
|
||||||
_ => MapTile::Occupied,
|
Tile::Wall => MapTile::Occupied,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
fields.push(new);
|
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;
|
fields[clear.0][clear.1] = MapTile::Empty;
|
||||||
Map {
|
Map {
|
||||||
fields: fields,
|
fields: fields,
|
||||||
@@ -356,6 +378,9 @@ impl Map {
|
|||||||
if curr_pos == to {
|
if curr_pos == to {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if self.fields[curr_pos.0][curr_pos.1] != MapTile::Empty {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for pos in curr_pos.neighbors(self.width, self.height) {
|
for pos in curr_pos.neighbors(self.width, self.height) {
|
||||||
if !predecessors.contains_key(&pos) && !open.iter().any(|it| it.1 == pos) {
|
if !predecessors.contains_key(&pos) && !open.iter().any(|it| it.1 == pos) {
|
||||||
open.push_back((Some(curr_pos), 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
|
// all others would have a higher distance and therefore are not relevant
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if self.fields[curr_pos.0][curr_pos.1] == MapTile::Occupied {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for pos in curr_pos.neighbors(self.width, self.height) {
|
for pos in curr_pos.neighbors(self.width, self.height) {
|
||||||
if !visited.contains(&pos) && !open.iter().any(|it| it.1 == pos) {
|
if !visited.contains(&pos) && !open.iter().any(|it| it.1 == pos) {
|
||||||
open.push_back((curr_dist + 1, pos));
|
open.push_back((curr_dist + 1, pos));
|
||||||
|
|||||||
Reference in New Issue
Block a user