mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
Implement day 13 part 2.
This commit is contained in:
@@ -4,10 +4,16 @@ project(aoc2019)
|
|||||||
|
|
||||||
find_package(GTest REQUIRED)
|
find_package(GTest REQUIRED)
|
||||||
|
|
||||||
|
option(ANIMATE_DAY13 "Animate the Arkanoid game in day 13." Off)
|
||||||
|
|
||||||
file(GLOB DAYS_FILES src/day*.cpp)
|
file(GLOB DAYS_FILES src/day*.cpp)
|
||||||
add_library(AoCSolutions src/implementations.cpp "${DAYS_FILES}" src/point.hpp src/utils.cpp src/utils.hpp)
|
add_library(AoCSolutions src/implementations.cpp "${DAYS_FILES}" src/point.hpp src/utils.cpp src/utils.hpp)
|
||||||
target_compile_features(AoCSolutions PUBLIC cxx_std_17)
|
target_compile_features(AoCSolutions PUBLIC cxx_std_17)
|
||||||
|
|
||||||
|
if (ANIMATE_DAY13)
|
||||||
|
target_compile_definitions(AoCSolutions ANIMATE_DAY13)
|
||||||
|
endif ()
|
||||||
|
|
||||||
add_executable(runner src/runner.cpp)
|
add_executable(runner src/runner.cpp)
|
||||||
target_compile_features(runner PUBLIC cxx_std_17)
|
target_compile_features(runner PUBLIC cxx_std_17)
|
||||||
target_link_libraries(runner AoCSolutions)
|
target_link_libraries(runner AoCSolutions)
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#ifdef ANIMATE_DAY13
|
||||||
|
#include <chrono>
|
||||||
|
#include <thread>
|
||||||
|
#endif
|
||||||
#include "days.hpp"
|
#include "days.hpp"
|
||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
#include "point.hpp"
|
#include "point.hpp"
|
||||||
@@ -13,28 +17,128 @@ namespace {
|
|||||||
PADDLE,
|
PADDLE,
|
||||||
BALL,
|
BALL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef std::unordered_map<point_t, Tile> Screen;
|
||||||
|
|
||||||
|
std::optional<std::int64_t> update_screen(std::deque<std::int64_t> &output_buffer, Screen &screen) {
|
||||||
|
std::optional<std::int64_t> score;
|
||||||
|
while (!output_buffer.empty()) {
|
||||||
|
auto x = output_buffer.front(); output_buffer.pop_front();
|
||||||
|
auto y = output_buffer.front(); output_buffer.pop_front();
|
||||||
|
auto type = output_buffer.front(); output_buffer.pop_front();
|
||||||
|
|
||||||
|
if (x == -1 && y == 0) {
|
||||||
|
score = type;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
screen[{x, y}] = static_cast<Tile>(type);
|
||||||
|
}
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_screen(const Screen &screen, std::ostream& output) {
|
||||||
|
// Determine bounding box
|
||||||
|
using limits = std::numeric_limits<int>;
|
||||||
|
|
||||||
|
std::int64_t left_edge = limits::max(), right_edge = limits::min(), top_edge = limits::max(), bottom_edge = limits::min();
|
||||||
|
for (auto& entry : screen) {
|
||||||
|
left_edge = std::min(entry.first[0], left_edge);
|
||||||
|
right_edge = std::max(entry.first[0], right_edge);
|
||||||
|
top_edge = std::min(entry.first[1], top_edge);
|
||||||
|
bottom_edge = std::max(entry.first[1], bottom_edge);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto y = top_edge; y <= bottom_edge; ++y) {
|
||||||
|
for (auto x = left_edge; x <= right_edge; ++x) {
|
||||||
|
char c = ' ';
|
||||||
|
if (auto it = screen.find({x, y}); it != screen.end()) {
|
||||||
|
switch (it->second) {
|
||||||
|
case Tile::EMPTY:
|
||||||
|
c = ' ';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Tile::BALL:
|
||||||
|
c = '*';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Tile::BLOCK:
|
||||||
|
c = '=';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Tile::PADDLE:
|
||||||
|
c = '_';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Tile::WALL:
|
||||||
|
c = '#';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output << c;
|
||||||
|
}
|
||||||
|
|
||||||
|
output << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto find_pos(const Screen &screen, Tile to_find) {
|
||||||
|
return std::find_if(screen.begin(), screen.end(), [to_find](const auto& x) {
|
||||||
|
return x.second == to_find;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void aoc2019::day13_part1(std::istream &input, std::ostream &output) {
|
void aoc2019::day13_part1(std::istream &input, std::ostream &output) {
|
||||||
|
Screen screen;
|
||||||
aoc2019::IntCodeComputer computer(aoc2019::IntCodeComputer::read_intcode(input));
|
aoc2019::IntCodeComputer computer(aoc2019::IntCodeComputer::read_intcode(input));
|
||||||
std::deque<std::int64_t> output_buffer;
|
std::deque<std::int64_t> output_buffer;
|
||||||
|
|
||||||
computer.connectOutput(output_buffer);
|
computer.connectOutput(output_buffer);
|
||||||
computer.run();
|
computer.run();
|
||||||
|
update_screen(output_buffer, screen);
|
||||||
|
|
||||||
std::unordered_map<point_t, Tile> drawn;
|
output << std::count_if(screen.begin(), screen.end(), [](const auto &x) { return x.second == Tile::BLOCK; })
|
||||||
|
<< std::endl;
|
||||||
while (!output_buffer.empty()) {
|
|
||||||
auto x = output_buffer.front(); output_buffer.pop_front();
|
|
||||||
auto y = output_buffer.front(); output_buffer.pop_front();
|
|
||||||
auto type = output_buffer.front(); output_buffer.pop_front();
|
|
||||||
|
|
||||||
drawn[{x, y}] = static_cast<Tile>(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
output << std::count_if(drawn.begin(), drawn.end(), [](const auto& x) { return x.second == Tile::BLOCK; })<< std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void aoc2019::day13_part2(std::istream &input, std::ostream &output) {
|
void aoc2019::day13_part2(std::istream &input, std::ostream &output) {
|
||||||
output << "Not implemented\n";
|
auto program = aoc2019::IntCodeComputer::read_intcode(input);
|
||||||
|
program[0] = 2;
|
||||||
|
|
||||||
|
aoc2019::IntCodeComputer computer(std::move(program));
|
||||||
|
std::deque<std::int64_t> output_buffer;
|
||||||
|
computer.connectOutput(output_buffer);
|
||||||
|
computer.run();
|
||||||
|
|
||||||
|
Screen screen;
|
||||||
|
|
||||||
|
std::int64_t score = 0;
|
||||||
|
|
||||||
|
while (!computer.isTerminated()) {
|
||||||
|
computer.run();
|
||||||
|
auto new_score = update_screen(output_buffer, screen);
|
||||||
|
if (new_score) {
|
||||||
|
score = *new_score;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ANIMATE_DAY13
|
||||||
|
output << "Score: " << score << std::endl;
|
||||||
|
draw_screen(screen, output);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(40));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto ball_pos = find_pos(screen, Tile::BALL)->first;
|
||||||
|
auto paddle_pos = find_pos(screen, Tile::PADDLE)->first;
|
||||||
|
|
||||||
|
if (ball_pos[0] < paddle_pos[0]) {
|
||||||
|
computer.sendInput(-1);
|
||||||
|
} else if (ball_pos[0] > paddle_pos[0]) {
|
||||||
|
computer.sendInput(1);
|
||||||
|
} else {
|
||||||
|
computer.sendInput(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output << score << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user