classSnakeGame{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(intwidth,intheight,vector<vector<int>>&food):width(width),height(height),food(food){lookup.insert(getId(0,0));body.push_back(getId(0,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. */intmove(stringdirection){// Old head's positioninti=body.front()/width;intj=body.front()%width;// Update head's position and check if out of boundif(direction=="U"&&--i<0)return-1;if(direction=="L"&&--j<0)return-1;if(direction=="R"&&++j==width)return-1;if(direction=="D"&&++i==height)return-1;constintnewHead=getId(i,j);// Case 1: eat food and increase size by 1if(k<food.size()&&i==food[k][0]&&j==food[k][1]){lookup.insert(newHead);body.push_front(newHead);++k;return++score;}// Case 2: new head != old tail and eat body!if(newHead!=body.back()&&lookup.count(newHead))return-1;// Case 3: normal case// Remove old tail first (important), then add new head// Because new head may be in old tail's positionlookup.erase(body.back());lookup.insert(newHead);body.pop_back();body.push_front(newHead);returnscore;}private:intwidth;intheight;intscore=0;intk=0;// food's indexvector<vector<int>>food;unordered_set<int>lookup;deque<int>body;// snake's bodyintgetId(inti,intj){returni*width+j;}};
classSnakeGame{/** * 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]. */publicSnakeGame(intwidth,intheight,int[][]food){this.width=width;this.height=height;this.food=food;lookup.add(getId(0,0));body.offerLast(getId(0,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. */publicintmove(Stringdirection){// Old head's positioninti=body.peekFirst()/width;intj=body.peekFirst()%width;// Update head's position and check if out of boundif(direction.equals("U")&&--i<0)return-1;if(direction.equals("L")&&--j<0)return-1;if(direction.equals("R")&&++j==width)return-1;if(direction.equals("D")&&++i==height)return-1;finalintnewHead=getId(i,j);// Case 1: eat food and increase size by 1if(k<food.length&&i==food[k][0]&&j==food[k][1]){lookup.add(newHead);body.offerFirst(newHead);++k;return++score;}// Case 2: new head != old tail and eat body!if(newHead!=body.peekLast()&&lookup.contains(newHead))return-1;// Case 3: normal case// Remove old tail first (important), then add new head// Because new head may be in old tail's positionlookup.remove(body.peekLast());lookup.add(newHead);body.pollLast();body.offerFirst(newHead);returnscore;}privateintwidth;privateintheight;privateintscore=0;privateintk=0;// food's indexprivateint[][]food;privateSet<Integer>lookup=newHashSet<>();privateDeque<Integer>body=newArrayDeque<>();// snake's bodyprivateintgetId(inti,intj){returni*width+j;}}
classSnakeGame:def__init__(self,width:int,height:int,food:List[List[int]]):""" 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]. """self.width=widthself.height=heightself.food=foodself.score=0self.k=0# food's indexself.lookup=set([self.getId(0,0)])self.body=deque([self.getId(0,0)])# snake's bodydefmove(self,direction:str)->int:""" 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. """# Old head's positioni=self.body[0]//self.widthj=self.body[0]%self.width# Update head's position and check if out of boundifdirection=="U":i-=1ifi<0:return-1ifdirection=="L":j-=1ifj<0:return-1ifdirection=="R":j+=1ifj==self.width:return-1ifdirection=="D":i+=1ifi==self.height:return-1newHead=self.getId(i,j)# Case 1: eat food and increase size by 1ifself.k<len(self.food)andi==self.food[self.k][0]andj==self.food[self.k][1]:self.lookup.add(newHead)self.body.appendleft(newHead)self.k+=1self.score+=1returnself.score# Case 2: new head != old tail and eat body!ifnewHead!=self.body[-1]andnewHeadinself.lookup:return-1# Case 3: normal case# Remove old tail first(important), then add new head# Because new head may be in old tail's positionself.lookup.remove(self.body[-1])self.lookup.add(newHead)self.body.pop()self.body.appendleft(newHead)returnself.scoredefgetId(self,i:int,j:int)->int:returni*self.width+j