Design a Snake game that is played on a device with screen size = width x height. Play the game online if you are not familiar with the game.

The snake is initially positioned at the top left corner (0,0) with length = 1 unit.

You are given a list of food's positions in row-column order. When a snake eats the food, its length and the game's score both increase by 1.

Each food appears one by one on the screen. For example, the second food will not appear until the first food was eaten by the snake.

When a food does appear on the screen, it is guaranteed that it will not appear on a block occupied by the snake.

Example:
Given width = 3, height = 2, and food = [[1,2],[0,1]]. Snake snake = new Snake(width, height, food); Initially the snake appears at position (0,0) and the food at (1,2). |S| | |
| | |F| snake.move("R"); -> Returns 0 | |S| |
| | |F| snake.move("D"); -> Returns 0 | | | |
| |S|F| snake.move("R"); -> Returns 1 (Snake eats the first food and right after that, the second food appears at (0,1) ) | |F| |
| |S|S| snake.move("U"); -> Returns 1 | |F|S|
| | |S| snake.move("L"); -> Returns 2 (Snake eats the second food) | |S|S|
| | |S| snake.move("U"); -> Returns -1 (Game over because snake collides with border)

HashSet + Queue:

吃东西的时候保留尾巴,不吃的时候删去尾巴

one case to notice蛇转弯的时候,要先删去尾巴,再把新的点加进去。如果这个顺序不对的话,本来不会撞上尾巴的结果会判断会撞上

 public class SnakeGame {
int m;
int n;
int[][] foods;
Queue<Integer> queue;
HashSet<Integer> set;
int[] headPos;
int foodSeq; /** 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]. */
public SnakeGame(int width, int height, int[][] food) {
this.m = height;
this.n = width;
this.foods = food;
this.queue = new LinkedList<Integer>();
this.set = new HashSet<Integer>();
this.headPos = new int[]{0, 0};
this.foodSeq = 0;
queue.offer(0);
set.add(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. */
public int move(String direction) {
int[] dir;
switch(direction) {
case "U": dir = new int[]{-1, 0}; break;
case "L": dir = new int[]{0, -1}; break;
case "R": dir = new int[]{0, 1}; break;
case "D": dir = new int[]{1, 0}; break;
default: dir = new int[2];
}
int row = headPos[0] + dir[0]; // new position row
int col = headPos[1] + dir[1]; // new position col //delete tail first, before push into a new cell
if (foodSeq<foods.length && calcPosId(foods[foodSeq][0], foods[foodSeq][1]) == calcPosId(row, col)) {
foodSeq++;
}
else {
set.remove(queue.poll());
} if (row<0 || row>=m || col<0 || col>=n) return -1; // hit border
if (set.contains(calcPosId(row, col))) return -1; // hit its own body set.add(calcPosId(row, col));
queue.offer(calcPosId(row, col));
headPos[0] = row;
headPos[1] = col; return set.size()-1;
} public int calcPosId(int x, int y) {
return x*n+y;
}
} /**
* Your SnakeGame object will be instantiated and called as such:
* SnakeGame obj = new SnakeGame(width, height, food);
* int param_1 = obj.move(direction);
*/

如果没有39行,程序会说dir没有initialize,

其实更好的写法应该是

         int rowHead = body.peekFirst() / width;
int colHead = body.peekFirst() % width;
switch (direction) {
case "U" : rowHead--;
break;
case "D" : rowHead++;
break;
case "L" : colHead--;
break;
default : colHead++;
}

Leetcode: Design Snake Game的更多相关文章

  1. [LeetCode] Design Snake Game 设计贪吃蛇游戏

    Design a Snake game that is played on a device with screen size = width x height. Play the game onli ...

  2. [Swift]LeetCode353. 设计贪吃蛇游戏 $ Design Snake Game

    Design a Snake game that is played on a device with screen size = width x height. Play the game onli ...

  3. LeetCode Design TinyURL

    原题链接在这里:https://leetcode.com/problems/design-tinyurl/description/ 题目: How would you design a URL sho ...

  4. [LeetCode] Design Phone Directory 设计电话目录

    Design a Phone Directory which supports the following operations: get: Provide a number which is not ...

  5. [LeetCode] Design Hit Counter 设计点击计数器

    Design a hit counter which counts the number of hits received in the past 5 minutes. Each function a ...

  6. [LeetCode] Design Twitter 设计推特

    Design a simplified version of Twitter where users can post tweets, follow/unfollow another user and ...

  7. [LeetCode] Design Tic-Tac-Toe 设计井字棋游戏

    Design a Tic-tac-toe game that is played between two players on a n x n grid. You may assume the fol ...

  8. LeetCode Design Hit Counter

    原题链接在这里:https://leetcode.com/problems/design-hit-counter/. 题目: Design a hit counter which counts the ...

  9. [LeetCode] Design Search Autocomplete System 设计搜索自动补全系统

    Design a search autocomplete system for a search engine. Users may input a sentence (at least one wo ...

随机推荐

  1. Xcode修改storyboard大小

    1: 2:

  2. 09 Request/Response

         Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象      request和response对象即然代表 ...

  3. 自己写了一个无缝滚动的插件(jQuery)

    效果图: html代码: 1 <h1>无缝滚动,向右滚动</h1> 2 <ul id="guoul1"> 3 <li><img ...

  4. js 无缝滚动效果学习

    <!DOCTYPE html> <html> <head> <title>无缝滚动测试</title> <meta http-equi ...

  5. innerHTML 与 innerText 的区别

    innerHTML指的是从对象的起始位置到终止位置的全部内容,包括Html标签.innerText 指的是从起始位置到终止位置的内容,但它去除Html标签.同时,innerHTML 是所有浏览器都支持 ...

  6. html()、text()、val()、innerHTML、value()的区分

    以上的方法可用于一般的html标签(div)与input中分别进行讨论 1.html(): jQuery方法,用于一般标签中,可读写,可以获得写入html标签. 2.text(): jQuery方法, ...

  7. iOS CoreAnimation 核心动画

    一 介绍 一组非常强大的动画处理API 直接作用在CALAyer上,并非UIView(UIView动画) CoreAnimation是所有动画的父类,但是不能直接使用,应该使用其子类 属性: dura ...

  8. JAVA中的TreeSet

    TreeSet简介 TreeSet是一个有序的集合,它的作用是提供一个有序的Set集合,它继承于AbstractSet抽象类实现了NavigableSet<E>, Cloneable, j ...

  9. FAT32文件系统

  10. PyCharm2016.2专业版注册码

    43B4A73YYJ-eyJsaWNlbnNlSWQiOiI0M0I0QTczWVlKIiwibGljZW5zZWVOYW1lIjoibGFuIHl1IiwiYXNzaWduZWVOYW1lIjoiI ...