请你设计一个 贪吃蛇游戏,该游戏将会在一个 屏幕尺寸 = 宽度 x 高度 的屏幕上运行。如果你不熟悉这个游戏,可以 点击这里 在线试玩。
起初时,蛇在左上角的 (0, 0) 位置,身体长度为 1 个单位。
你将会被给出一个数组形式的食物位置序列 food ,其中 food[i] = (ri, ci) 。当蛇吃到食物时,身子的长度会增加 1 个单位,得分也会 +1 。
食物不会同时出现,会按列表的顺序逐一显示在屏幕上。比方讲,第一个食物被蛇吃掉后,第二个食物才会出现。
当一个食物在屏幕上出现时,保证 不会 出现在被蛇身体占据的格子里。
如果蛇越界(与边界相撞)或者头与 移动后 的身体相撞(即,身长为 4 的蛇无法与自己相撞),游戏结束。
实现 SnakeGame 类:
SnakeGame(int width, int height, int[][] food) 初始化对象,屏幕大小为 height x width ,食物位置序列为 food
int move(String direction) 返回蛇在方向 direction 上移动后的得分。如果游戏结束,返回 -1 。
示例 1:
输入:
[“SnakeGame”, “move”, “move”, “move”, “move”, “move”, “move”]
[[3, 2, [[1, 2], [0, 1]]], [“R”], [“D”], [“R”], [“U”], [“L”], [“U”]]
输出:
[null, 0, 0, 1, 1, 2, -1]
解释:
SnakeGame snakeGame = new SnakeGame(3, 2, [[1, 2], [0, 1]]);
snakeGame.move(“R”); // 返回 0
snakeGame.move(“D”); // 返回 0
snakeGame.move(“R”); // 返回 1 ,蛇吃掉了第一个食物,同时第二个食物出现在 (0, 1)
snakeGame.move(“U”); // 返回 1
snakeGame.move(“L”); // 返回 2 ,蛇吃掉了第二个食物,没有出现更多食物
snakeGame.move(“U”); // 返回 -1 ,蛇与边界相撞,游戏结束
提示:
1 <= width, height <= 104
1 <= food.length <= 50
food[i].length == 2
0 <= ri < height
0 <= ci < width
direction.length == 1
direction is ‘U’, ‘D’, ‘L’, or ‘R’.
最多调用 104 次 move 方法
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/design-snake-game
方法一:双端队列
C++提交内容:
class SnakeGame {
deque<pair<int, int>> q; // 双端队列,存放 <横坐标,纵坐标>
vector<vector<int>>& food;
int m, n, foodIdx = 0, score = 0;
public:
SnakeGame(int width, int height, vector<vector<int>>& food): m(height), n(width), food(food) {
q.emplace_front(0, 0);
}
int move(string direction) {
auto [x, y] = q.front();
int nx = x, ny = y;
if (direction == "U") nx -= 1;
else if (direction == "D") nx += 1;
else if (direction == "L") ny -= 1;
else ny += 1;
if (nx < 0 || nx >= m || ny < 0 || ny >= n) return -1; // 移动后越界
if (foodIdx != food.size() && nx == food[foodIdx][0] && ny == food[foodIdx][1]) {
++score; // 分数加1
++foodIdx; // 下一个食物出现
} else {
q.pop_back(); // 未吃到食物,队尾坐标弹出
}
for (auto &[r, c] : q) { // 检测蛇头是否与身体相撞
if (nx == r && ny == c) return -1;
}
q.emplace_front(nx, ny); // 将新坐标添加到队头
return score;
}
};
/**
* Your SnakeGame object will be instantiated and called as such:
* SnakeGame* obj = new SnakeGame(width, height, food);
* int param_1 = obj->move(direction);
*/