aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.rs152
1 files changed, 89 insertions, 63 deletions
diff --git a/src/main.rs b/src/main.rs
index a8e6819..0b51282 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -192,6 +192,77 @@ enum ProgramState {
NEEDINPUT,
}
+struct Screen {
+ screen: HashMap<(isize, isize), isize>,
+ tiles_map_ascii: HashMap<isize, char>,
+ tiles_map_color: HashMap<isize, (u8, u8, u8)>,
+}
+
+impl Screen {
+ fn new() -> Screen {
+ Screen {
+ screen: HashMap::new(),
+ tiles_map_ascii: HashMap::new(),
+ tiles_map_color: HashMap::new(),
+ }
+ }
+
+ fn set_pixel(&mut self, posx: isize, posy: isize, val: isize) {
+ self.screen.insert((posx, posy), val);
+ }
+
+ fn dump_screen(&self, index: Option<isize>) {
+ if self.screen.is_empty() {
+ return;
+ }
+ let mut min_x = isize::max_value();
+ let mut min_y = isize::max_value();
+ let mut max_x = isize::min_value();
+ let mut max_y = isize::min_value();
+ for (x, y) in self.screen.keys() {
+ min_x = cmp::min(min_x, *x);
+ min_y = cmp::min(min_y, *y);
+ max_x = cmp::max(max_x, *x);
+ max_y = cmp::max(max_y, *y);
+ }
+ let mut screen_vec = Vec::new();
+ for _ in 0..=(max_y - min_y) {
+ let mut row = Vec::new();
+ row.resize((max_x - min_x + 1) as usize, 0);
+ screen_vec.push(row);
+ }
+ for (x, y) in self.screen.keys() {
+ let mut tile = self.screen.get(&(*x,*y));
+ if tile.is_none() {
+ tile = Some(&0);
+ }
+ screen_vec[(y - min_y) as usize][(x - min_x) as usize] = *tile.unwrap();
+ }
+ if let Some(idx) = index {
+ /* write to file */
+ let mut file = File::create(format!("screen{:05}.ppm", idx)).expect("can't open file for writing");
+ file.write_all(format!("P6\n{} {} 255\n", screen_vec[0].len(), screen_vec.len()).as_bytes()).unwrap();
+ for row in screen_vec {
+ for tile in row {
+ let (r, g, b) = self.tiles_map_color.get(&tile).unwrap();
+ file.write_all(&[*r, *g, *b]).unwrap();
+ }
+ }
+ } else {
+ /* dump to stdout */
+ for row in screen_vec {
+ for tile in row {
+ match self.tiles_map_ascii.get(&tile) {
+ Some(x) => print!("{}", x),
+ None => print!("{}", tile),
+ }
+ }
+ println!();
+ }
+ }
+ }
+}
+
struct IntComputer {
ip : usize,
mem : Vec<isize>,
@@ -199,6 +270,7 @@ struct IntComputer {
input : VecDeque<isize>,
output : VecDeque<isize>,
suspend_on_output : bool,
+ screen: Screen,
}
impl IntComputer {
@@ -210,6 +282,7 @@ impl IntComputer {
input : VecDeque::new(),
output : VecDeque::new(),
suspend_on_output : false,
+ screen: Screen::new(),
}
}
@@ -1060,21 +1133,29 @@ fn day12() {
struct Arcade {
computer: IntComputer,
- screen: HashMap<(isize, isize), isize>,
score: isize,
}
impl Arcade {
fn new(program: &[isize]) -> Arcade {
+ let mut tiles_map = HashMap::new();
+ tiles_map.insert(0, (255, 255, 255)); /* empty */
+ tiles_map.insert(1, ( 32, 32, 32)); /* wall */
+ tiles_map.insert(2, (127, 127, 127)); /* block */
+ tiles_map.insert(3, (255, 0, 0)); /* paddle */
+ tiles_map.insert(4, ( 0, 0, 255)); /* ball */
+
+ let mut computer = IntComputer::new(&program);
+ computer.screen.tiles_map_color = tiles_map;
+
Arcade {
- computer: IntComputer::new(&program),
- screen: HashMap::new(),
+ computer,
score: 0,
}
}
fn find_tile(&self, search: isize) -> (isize, isize) {
- for (pos, tile) in &self.screen {
+ for (pos, tile) in &self.computer.screen.screen {
if *tile == search {
return *pos;
}
@@ -1121,7 +1202,7 @@ impl Arcade {
if posx == -1 && posy == 0 {
self.score = new_tile;
} else {
- self.screen.insert((posx,posy), new_tile);
+ self.computer.screen.set_pixel(posx, posy, new_tile);
}
x = None;
y = None;
@@ -1129,61 +1210,6 @@ impl Arcade {
}
}
}
-
- fn dump_screen(&self, index: Option<isize>) {
- if self.screen.is_empty() {
- return;
- }
- let mut min_x = isize::max_value();
- let mut min_y = isize::max_value();
- let mut max_x = isize::min_value();
- let mut max_y = isize::min_value();
- for (x, y) in self.screen.keys() {
- min_x = cmp::min(min_x, *x);
- min_y = cmp::min(min_y, *y);
- max_x = cmp::max(max_x, *x);
- max_y = cmp::max(max_y, *y);
- }
- let mut screen_vec = Vec::new();
- for _ in 0..=(max_y - min_y) {
- let mut row = Vec::new();
- row.resize((max_x - min_x + 1) as usize, 0);
- screen_vec.push(row);
- }
- for (x, y) in self.screen.keys() {
- let mut tile = self.screen.get(&(*x,*y));
- if tile.is_none() {
- tile = Some(&0);
- }
- screen_vec[(y - min_y) as usize][(x - min_x) as usize] = *tile.unwrap();
- }
- if let Some(idx) = index {
- /* write to file */
- let mut file = File::create(format!("screen{:05}.ppm", idx)).expect("can't open file for writing");
- file.write_all(format!("P6\n{} {} 255\n", screen_vec[0].len(), screen_vec.len()).as_bytes()).unwrap();
- for row in screen_vec {
- for tile in row {
- let value: (u8, u8, u8) = match tile {
- 0 => (255, 255, 255), /* empty */
- 1 => ( 32, 32, 32), /* wall */
- 2 => (127, 127, 127), /* block */
- 3 => (255, 0, 0), /* paddle */
- 4 => ( 0, 0, 255), /* ball */
- _ => panic!("invalid tile")
- };
- file.write_all(&[value.0, value.1, value.2]).unwrap();
- }
- }
- } else {
- /* dump to stdout */
- for row in screen_vec {
- for tile in row {
- print!("{}", tile);
- }
- println!();
- }
- }
- }
}
fn day13() {
@@ -1196,9 +1222,9 @@ fn day13() {
let mut arcade = Arcade::new(&program);
arcade.computer.suspend_on_output = true;
arcade.run_arcade();
- let blocks = arcade.screen.values()
- .filter(|&tile| *tile == 2)
- .count();
+ let blocks = arcade.computer.screen.screen.values()
+ .filter(|&tile| *tile == 2)
+ .count();
println!("13a: {}", blocks);