1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
use std::cmp::max;
pub const SCREEN_WIDTH: usize = 7;
pub const SCREEN_HEIGHT: usize = 100000;
pub struct Screen {
pub cell: [[bool; SCREEN_WIDTH]; SCREEN_HEIGHT],
pub top: usize
}
#[derive(Debug)]
pub struct Rock {
pub a: Vec<(usize, usize)>,
pub h: usize
}
pub fn get_rocks() -> Vec<Rock> {
vec![
Rock { a: vec![(0, 0), (0, 1), (0, 2), (0, 3)], h: 1 },
Rock { a: vec![(0, 1), (1, 0), (1, 1), (1, 2), (2, 1)], h: 3 },
Rock { a: vec![(0, 0), (0, 1), (0, 2), (1, 2), (2, 2)], h: 3 },
Rock { a: vec![(0, 0), (1, 0), (2, 0), (3, 0)], h: 4 },
Rock { a: vec![(0, 0), (0, 1), (1, 0), (1, 1)], h: 2 }
]
}
fn in_bounds(position: (i32, i32)) -> bool {
position.0 >= 0 && position.1 >= 0 && position.1 < SCREEN_WIDTH as i32
}
impl Screen {
pub fn new() -> Screen {
Screen {
cell: [[false; SCREEN_WIDTH]; SCREEN_HEIGHT],
top: 0
}
}
fn allowed(&self, rock: &Rock, p: (i32, i32)) -> bool {
for r in &rock.a {
let (i, j) = (r.0 as i32 + p.0, r.1 as i32 + p.1);
if !in_bounds((i, j)) || self.cell[i as usize][j as usize] {
return false;
}
}
true
}
fn draw(&mut self, rock: &Rock, p: (usize, usize), b: bool) {
for r in &rock.a {
self.cell[r.0 + p.0][r.1 + p.1] = b;
}
}
fn move_rock(&mut self, r: &Rock, p: (usize, usize), d: (i32, i32)) -> (usize, usize) {
let newpos = (p.0 as i32 + d.0, p.1 as i32 + d.1);
if !self.allowed(r, newpos) { return p; }
let newpos = (newpos.0 as usize, newpos.1 as usize);
newpos
}
pub fn drop_rock(&mut self, r: &Rock, t: &mut usize, gas: &str) {
let mut p = (self.top + 3, 2);
loop {
let d = gas.chars().nth(*t % gas.len()).unwrap();
let d = if d == '>' { (0, 1) } else { (0, -1) };
p = self.move_rock(r, p, d);
*t += 1;
let q = self.move_rock(r, p, (-1, 0));
if p == q { break; } else { p = q; }
}
self.draw(r, p, true);
self.top = max(self.top, p.0 + r.h);
}
#[allow(dead_code)]
pub fn print(&self) {
for i in (0..=self.top).rev() {
for j in 0..SCREEN_WIDTH {
print!("{}", if self.cell[i][j] { '#' } else { '.' })
}
println!(" {i}");
}
}
}
|