forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 1
/
design-snake-game.py
61 lines (53 loc) · 2.04 KB
/
design-snake-game.py
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
# Time: O(1) per move
# Space: O(s), s is the current length of the snake.
from collections import defaultdict, 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.__width = width
self.__height = height
self.__score = 0
self.__food = deque(food)
self.__snake = deque([(0, 0)])
self.__direction = {"U": (-1, 0), "L": (0, -1), "R": (0, 1), "D": (1, 0)}
self.__lookup = defaultdict(int)
self.__lookup[(0, 0)] += 1
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
"""
def valid(x, y):
return 0 <= x < self.__height and \
0 <= y < self.__width and \
(x, y) not in self.__lookup
d = self.__direction[direction]
x, y = self.__snake[-1][0] + d[0], self.__snake[-1][1] + d[1]
tail = self.__snake[-1]
self.__lookup[self.__snake[0]] -= 1
if self.__lookup[self.__snake[0]] == 0:
self.__lookup.pop(self.__snake[0])
self.__snake.popleft()
if not valid(x, y):
return -1
elif self.__food and (self.__food[0][0], self.__food[0][1]) == (x, y):
self.__score += 1
self.__food.popleft()
self.__snake.appendleft(tail)
self.__lookup[tail] += 1
self.__snake += (x, y),
self.__lookup[(x, y)] += 1
return self.__score