forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
design-snake-game.cpp
62 lines (57 loc) · 2.03 KB
/
design-snake-game.cpp
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
// Time: O(1) per move
// Space: O(s), s is the current length of the snake.
class SnakeGame {
public:
/** Initialize your data structure here.
@param width - screen width
@param height - screen height
@param food - A list of food positions
E.g food = [[1,1], [1,0]] means the first food is positioned at [1,1], the second is at [1,0]. */
SnakeGame(int width, int height, vector<vector<int>>& food)
: food_(food)
, f_{0}
, width_{width}
, height_{height}
, score_{0}
, snake_{{0, 0}}
, lookup_{{0}} {
}
/** Moves the snake.
@param direction - 'U' = Up, 'L' = Left, 'R' = Right, 'D' = Down
@return The game's score after the move. Return -1 if game over.
Game over when snake crosses the screen boundary or bites its body. */
int move(string direction) {
const auto x = snake_.back()[0] + direction_[direction].first;
const auto y = snake_.back()[1] + direction_[direction].second;
const auto tail = snake_.front();
lookup_.erase(hash(tail[0], tail[1]));
snake_.pop_front();
if (!valid(x, y)) {
return -1;
} else if (f_ != size(food_) && food_[f_][0] == x && food_[f_][1] == y) {
++score_;
++f_;
snake_.push_front(tail);
lookup_.emplace(hash(tail[0], tail[1]));
}
snake_.push_back({x, y});
lookup_.emplace(hash(x, y));
return score_;
}
private:
bool valid(int x, int y) {
if (x < 0 || x >= height_ || y < 0 || y >= width_) {
return false;
}
return !lookup_.count(hash(x, y));
}
int hash(int x, int y) {
return x * width_ + y;
}
const vector<vector<int>>& food_;
int f_, width_, height_, score_;
deque<vector<int>> snake_;
unordered_set<int> lookup_;
unordered_map<string, pair<int, int>> direction_ = {{"U", {-1, 0}}, {"L", {0, -1}},
{"R", {0, 1}}, {"D", {1, 0}}};
};