边工作边刷题:70天一遍leetcode: day 96
Design Snake Game
要点:
- representation:给了grid,坐标放list里表示蛇身。
- api和data structure更新的关系:就一个function: move(direction)
- 具体的data structure
- snake:需要随机查找碰撞检测,还要支持顺序入蛇头,简化用deque,同时用in检测是否在集合里
- snake的移动比较tricky:如果没吃的,那么tail要pop,否则没变化,而两种情况都要加入新的head:所以deque里head在尾而tail在前
- 碰撞检测:发生在tail pop之后(如果pop的话)
- 很容易把food给忘了,另外food是一个一个出现,而不是同时在map上,所以可以用deque表示
- score: 比snake长度-1
from collections import deque
class SnakeGame(object):
def __init__(self, width,height,food):
"""
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].
:type width: int
:type height: int
:type food: List[List[int]]
"""
self.food = deque(food)
self.snake = deque([(0,0)])
self.height = height
self.width = width
def move(self, direction):
"""
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.
:type direction: str
:rtype: int
"""
dirmap = {'U':(-1,0), 'L':(0,-1), 'R':(0,1), 'D':(1,0)}
x0,y0 = self.snake[-1]
x,y = x0+dirmap[direction][0],y0+dirmap[direction][1]
if x<0 or x>=self.height or y<0 or y>=self.width:
return -1
# print x,y, self.food
if self.food and [x,y]==self.food[0]: # error 3: check if there is food in
self.food.popleft()
else:
self.snake.popleft()
if (x,y) in self.snake:
return -1
self.snake.append((x,y))
return len(self.snake)-1 # error 2: score should be len-1
# Your SnakeGame object will be instantiated and called as such:
# obj = SnakeGame(width, height, food)
# param_1 = obj.move(direction)
obj = SnakeGame(3,2,[[1,2],[0,1]])
assert [obj.move("R"), obj.move("D"), obj.move("R"), obj.move("U"), obj.move("L"), obj.move("U")]==[0,0,1,1,2,-1], "scores = [0,0,1,1,2,-1]"