Browse Source

Completed day 13 part 2

Tyler Hallada 4 years ago
parent
commit
f8e836f780
1 changed files with 57 additions and 32 deletions
  1. 57 32
      day13/src/main.rs

+ 57 - 32
day13/src/main.rs

@@ -1,8 +1,8 @@
1 1
 use std::collections::HashMap;
2 2
 use std::convert::TryFrom;
3 3
 use std::error::Error;
4
-use std::result;
5 4
 use std::fmt;
5
+use std::result;
6 6
 
7 7
 use num_enum::TryFromPrimitive;
8 8
 
@@ -32,17 +32,53 @@ struct Coordinate {
32 32
 
33 33
 #[derive(Debug)]
34 34
 struct Game {
35
+    intcode: Intcode,
35 36
     tiles: HashMap<Coordinate, Tile>,
37
+    ball: Option<Coordinate>,
38
+    paddle: Option<Coordinate>,
36 39
     score: i64,
37 40
 }
38 41
 
39 42
 impl Game {
40
-    fn new() -> Game {
43
+    fn new(intcode: Intcode) -> Game {
41 44
         Game {
45
+            intcode,
42 46
             tiles: HashMap::new(),
47
+            ball: None,
48
+            paddle: None,
43 49
             score: 0,
44 50
         }
45 51
     }
52
+
53
+    fn update(&mut self, output: Vec<i64>) -> Result<()> {
54
+        for index in (0..output.len()).step_by(3) {
55
+            if output[index] == -1 {
56
+                self.score = output[index + 2];
57
+            } else {
58
+                let x = output[index];
59
+                let y = output[index + 1];
60
+                let coord = Coordinate { x, y };
61
+                let tile = Tile::try_from(output[index + 2] as u8)?;
62
+
63
+                if tile == Tile::Ball {
64
+                    self.ball = Some(coord);
65
+                } else if tile == Tile::HorizontalPaddle {
66
+                    self.paddle = Some(coord);
67
+                }
68
+
69
+                self.tiles.insert(Coordinate { x, y }, tile);
70
+            }
71
+        }
72
+        Ok(())
73
+    }
74
+
75
+    fn step(&mut self, input: Option<i64>) -> Result<()> {
76
+        let output = self
77
+            .intcode
78
+            .execute(&[input.unwrap_or(0)])
79
+            .expect("Failed to execute intcode");
80
+        self.update(output)
81
+    }
46 82
 }
47 83
 
48 84
 impl fmt::Display for Game {
@@ -80,11 +116,7 @@ impl fmt::Display for Game {
80 116
         for y in up_left_corner.y..=down_right_corner.y {
81 117
             let mut row_string = String::new();
82 118
             for x in up_left_corner.x..=down_right_corner.x {
83
-                row_string += match self
84
-                    .tiles
85
-                    .get(&Coordinate { x, y })
86
-                    .unwrap_or(&Tile::Empty)
87
-                {
119
+                row_string += match self.tiles.get(&Coordinate { x, y }).unwrap_or(&Tile::Empty) {
88 120
                     Tile::Empty => " ",
89 121
                     Tile::Wall => "|",
90 122
                     Tile::Block => "#",
@@ -99,41 +131,34 @@ impl fmt::Display for Game {
99 131
 }
100 132
 
101 133
 fn solve_part1() -> Result<i64> {
102
-    let mut intcode = read_intcode(INPUT)?;
103
-    let output = intcode.execute(&[0]).expect("Failed to execute intcode");
104
-    let mut game = Game::new();
105
-    for index in (0..output.len()).step_by(3) {
106
-        let x = output[index];
107
-        let y = output[index + 1];
108
-        let tile = Tile::try_from(output[index + 2] as u8)?;
109
-        game.tiles.insert(Coordinate { x, y }, tile);
110
-    }
134
+    let intcode = read_intcode(INPUT)?;
135
+    let mut game = Game::new(intcode);
136
+    game.step(None)?;
111 137
     Ok(game.tiles.values().fold(0, |acc, tile| {
112 138
         if *tile == Tile::Block {
113
-            return acc + 1
139
+            return acc + 1;
114 140
         }
115 141
         acc
116 142
     }))
117 143
 }
118 144
 
119 145
 fn solve_part2() -> Result<i64> {
120
-    let mut intcode = read_intcode(INPUT)?;
121
-    let mut output = intcode.execute(&[]).expect("Failed to execute intcode");
122
-    let mut game = Game::new();
123
-    while !intcode.halted {
124
-        for index in (0..output.len()).step_by(3) {
125
-            if output[index] == -1 {
126
-                game.score = output[index + 2];
127
-            } else {
128
-                let x = output[index];
129
-                let y = output[index + 1];
130
-                let tile = Tile::try_from(output[index + 2] as u8)?;
131
-                game.tiles.insert(Coordinate { x, y}, tile);
146
+    let intcode = read_intcode(INPUT)?;
147
+    let mut game = Game::new(intcode);
148
+    let mut input;
149
+    while !game.intcode.halted {
150
+        input = 0;
151
+        if let Some(ball_coord) = game.ball {
152
+            if let Some(paddle_coord) = game.paddle {
153
+                if ball_coord.x > paddle_coord.x {
154
+                    input = 1;
155
+                } else if ball_coord.x < paddle_coord.x {
156
+                    input = -1;
157
+                }
132 158
             }
133 159
         }
134
-        print!("{}", game);
135
-        // TODO: move the joystick correctly
136
-        output = intcode.execute(&[0]).expect("Failed to execute intcode");
160
+
161
+        game.step(Some(input))?;
137 162
     }
138 163
     Ok(game.score)
139 164
 }