Completed day 13 part 2

This commit is contained in:
Tyler Hallada 2020-01-13 23:18:37 -05:00
parent b2a0d408b5
commit f8e836f780

View File

@ -1,8 +1,8 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::error::Error; use std::error::Error;
use std::result;
use std::fmt; use std::fmt;
use std::result;
use num_enum::TryFromPrimitive; use num_enum::TryFromPrimitive;
@ -32,17 +32,53 @@ struct Coordinate {
#[derive(Debug)] #[derive(Debug)]
struct Game { struct Game {
intcode: Intcode,
tiles: HashMap<Coordinate, Tile>, tiles: HashMap<Coordinate, Tile>,
ball: Option<Coordinate>,
paddle: Option<Coordinate>,
score: i64, score: i64,
} }
impl Game { impl Game {
fn new() -> Game { fn new(intcode: Intcode) -> Game {
Game { Game {
intcode,
tiles: HashMap::new(), tiles: HashMap::new(),
ball: None,
paddle: None,
score: 0, score: 0,
} }
} }
fn update(&mut self, output: Vec<i64>) -> Result<()> {
for index in (0..output.len()).step_by(3) {
if output[index] == -1 {
self.score = output[index + 2];
} else {
let x = output[index];
let y = output[index + 1];
let coord = Coordinate { x, y };
let tile = Tile::try_from(output[index + 2] as u8)?;
if tile == Tile::Ball {
self.ball = Some(coord);
} else if tile == Tile::HorizontalPaddle {
self.paddle = Some(coord);
}
self.tiles.insert(Coordinate { x, y }, tile);
}
}
Ok(())
}
fn step(&mut self, input: Option<i64>) -> Result<()> {
let output = self
.intcode
.execute(&[input.unwrap_or(0)])
.expect("Failed to execute intcode");
self.update(output)
}
} }
impl fmt::Display for Game { impl fmt::Display for Game {
@ -80,11 +116,7 @@ impl fmt::Display for Game {
for y in up_left_corner.y..=down_right_corner.y { for y in up_left_corner.y..=down_right_corner.y {
let mut row_string = String::new(); let mut row_string = String::new();
for x in up_left_corner.x..=down_right_corner.x { for x in up_left_corner.x..=down_right_corner.x {
row_string += match self row_string += match self.tiles.get(&Coordinate { x, y }).unwrap_or(&Tile::Empty) {
.tiles
.get(&Coordinate { x, y })
.unwrap_or(&Tile::Empty)
{
Tile::Empty => " ", Tile::Empty => " ",
Tile::Wall => "|", Tile::Wall => "|",
Tile::Block => "#", Tile::Block => "#",
@ -99,41 +131,34 @@ impl fmt::Display for Game {
} }
fn solve_part1() -> Result<i64> { fn solve_part1() -> Result<i64> {
let mut intcode = read_intcode(INPUT)?; let intcode = read_intcode(INPUT)?;
let output = intcode.execute(&[0]).expect("Failed to execute intcode"); let mut game = Game::new(intcode);
let mut game = Game::new(); game.step(None)?;
for index in (0..output.len()).step_by(3) {
let x = output[index];
let y = output[index + 1];
let tile = Tile::try_from(output[index + 2] as u8)?;
game.tiles.insert(Coordinate { x, y }, tile);
}
Ok(game.tiles.values().fold(0, |acc, tile| { Ok(game.tiles.values().fold(0, |acc, tile| {
if *tile == Tile::Block { if *tile == Tile::Block {
return acc + 1 return acc + 1;
} }
acc acc
})) }))
} }
fn solve_part2() -> Result<i64> { fn solve_part2() -> Result<i64> {
let mut intcode = read_intcode(INPUT)?; let intcode = read_intcode(INPUT)?;
let mut output = intcode.execute(&[]).expect("Failed to execute intcode"); let mut game = Game::new(intcode);
let mut game = Game::new(); let mut input;
while !intcode.halted { while !game.intcode.halted {
for index in (0..output.len()).step_by(3) { input = 0;
if output[index] == -1 { if let Some(ball_coord) = game.ball {
game.score = output[index + 2]; if let Some(paddle_coord) = game.paddle {
} else { if ball_coord.x > paddle_coord.x {
let x = output[index]; input = 1;
let y = output[index + 1]; } else if ball_coord.x < paddle_coord.x {
let tile = Tile::try_from(output[index + 2] as u8)?; input = -1;
game.tiles.insert(Coordinate { x, y}, tile);
} }
} }
print!("{}", game); }
// TODO: move the joystick correctly
output = intcode.execute(&[0]).expect("Failed to execute intcode"); game.step(Some(input))?;
} }
Ok(game.score) Ok(game.score)
} }