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
|
use std::collections::{VecDeque, HashSet};
struct Solution {
w: i32,
h: i32,
score: i32,
food_idx: usize,
food: Vec<Vec<i32>>,
snake: VecDeque<(i32, i32)>,
body: HashSet<i32>,
}
impl Solution {
fn encode(&self, x: i32, y: i32) -> i32 { x * self.w + y }
fn new(width: i32, height: i32, food: Vec<Vec<i32>>) -> Self {
let mut snake = VecDeque::new();
snake.push_back((0, 0));
let mut body = HashSet::new();
body.insert(0);
Self { w: width, h: height, score: 0, food_idx: 0, food, snake, body }
}
fn move_(&mut self, direction: String) -> i32 {
let (dx, dy) = match direction.as_str() {
"U" => (-1, 0),
"D" => (1, 0),
"L" => (0, -1),
_ => (0, 1),
};
let (hx, hy) = *self.snake.back().unwrap();
let (nx, ny) = (hx + dx, hy + dy);
if nx < 0 || nx >= self.h || ny < 0 || ny >= self.w { return -1; }
let tail = self.encode(self.snake.front().unwrap().0, self.snake.front().unwrap().1);
self.body.remove(&tail);
if self.body.contains(&self.encode(nx, ny)) { return -1; }
self.snake.push_back((nx, ny));
self.body.insert(self.encode(nx, ny));
if self.food_idx < self.food.len() && nx == self.food[self.food_idx][0] && ny == self.food[self.food_idx][1] {
self.score += 1;
self.food_idx += 1;
self.body.insert(tail);
} else {
self.snake.pop_front();
}
self.score
}
}
|