Line data Source code
1 : #include "Grid2d.h"
2 : #include "Intcode.h"
3 : #include "PuzzleImpl.h"
4 :
5 : #include <absl/container/flat_hash_map.h>
6 :
7 : #include <chrono>
8 : #include <iostream>
9 : #include <thread>
10 :
11 : namespace {
12 :
13 : using Coord = Grid2d<char>::Coord;
14 :
15 : static constexpr std::array<char, 5u> tiles = {' ', '#', 'X', '-', 'o'};
16 :
17 1 : Grid2d<char> initialGrid(std::string_view const input) {
18 1 : Computer c(input);
19 :
20 1 : std::vector<int64_t> output;
21 2394 : c.registerOutput([&](int64_t v) { output.push_back(v); });
22 1 : ASSERT(c.run() == Computer::HALTED);
23 :
24 1 : Coord max;
25 799 : for (size_t i = 0; i < output.size(); i += 3) {
26 798 : max.x() = std::max(max.x(), integerCast<Coord::ElementType>(output[i]));
27 798 : max.y() = std::max(max.y(), integerCast<Coord::ElementType>(output[i + 1]));
28 798 : }
29 :
30 1 : Grid2d<char> screen(max.x() + 1, max.y() + 1, ' ');
31 :
32 799 : for (size_t i = 0; i < output.size(); i += 3)
33 798 : screen[output[i], max.y() - output[i + 1]] = tiles[output[i + 2]];
34 :
35 1 : return screen;
36 1 : }
37 :
38 : constexpr int64_t NEUTRAL = 0;
39 : constexpr int64_t LEFT = -1;
40 : constexpr int64_t RIGHT = 1;
41 :
42 : } // namespace
43 :
44 1 : template <> size_t part1<2019, 13>(std::string_view const input) {
45 1 : Grid2d<char> screen = initialGrid(input);
46 :
47 : // std::cout << "\n" << screen << "\n\n";
48 :
49 1 : return screen.count('X');
50 1 : }
51 :
52 1 : template <> size_t part2<2019, 13>(std::string_view const input) {
53 : // Grid2d<char> screen = initialGrid(input);
54 : // screen.fill(' ');
55 :
56 1 : Computer c(input);
57 1 : c.writeMemory(0, 2);
58 :
59 1 : int64_t joystickPos = NEUTRAL;
60 1 : int64_t score = 0;
61 1 : int64_t paddleX = 0;
62 1 : Vec2<int64_t> ballPos(0, 0);
63 :
64 52893 : auto outputFunc = [&, buffer = std::vector<int64_t>{}](int64_t v) mutable {
65 52893 : buffer.push_back(v);
66 52893 : if (buffer.size() == 3u) {
67 17631 : if (buffer[0] == -1 && buffer[1] == 0) {
68 229 : score = buffer[2];
69 17402 : } else {
70 : // screen[buffer[0], screen.ySize() - buffer[1] - 1] = tiles[buffer[2]];
71 17402 : switch (buffer[2]) {
72 4095 : case 3:
73 4095 : paddleX = buffer[0];
74 4095 : break;
75 4095 : case 4:
76 4095 : ballPos[0] = buffer[0];
77 4095 : ballPos[1] = buffer[1];
78 4095 : break;
79 9212 : default:
80 9212 : break;
81 17402 : }
82 17402 : }
83 17631 : buffer.clear();
84 17631 : }
85 52893 : };
86 :
87 1 : c.registerOutput(outputFunc);
88 :
89 : // constexpr int FPS = 60;
90 : // constexpr std::chrono::duration<double> frameTime{1.0 / FPS};
91 4096 : while (c.run() != Computer::HALTED) {
92 : // auto const start = std::chrono::steady_clock::now();
93 4095 : if (ballPos.x() < paddleX)
94 2052 : joystickPos = LEFT;
95 2043 : else if (ballPos.x() > paddleX)
96 2042 : joystickPos = RIGHT;
97 1 : else
98 1 : joystickPos = NEUTRAL;
99 4095 : c.queueInput(joystickPos);
100 : // std::cout << "\n\n\n\n\n\nScore: " << score << "\n" << screen << "\n";
101 : // std::this_thread::sleep_until(start + frameTime);
102 4095 : }
103 :
104 1 : return score;
105 1 : }
|