353. Design Snake Game

Văn bản bài toán được dịch từ tiếng Nga theo ngôn ngữ giao diện. Mã không thay đổi.

Разработайте игру "Змейка", которая играется на устройстве с экраном размером height x width. Поиграйте в игру онлайн, если вы не знакомы с ней.

Змейка изначально находится в верхнем левом углу (0, 0) с длиной в 1 единицу.

Вам дан mảng food, где food[i] = (ri, ci) представляет собой строку и столбец позиции пищи, которую змейка может съесть. Когда змейка съедает кусочек пищи, ее длина и очки игры увеличиваются на 1.

Каждый кусочек пищи появляется по очереди на экране, то есть второй кусочек пищи не появится, пока змейка не съест первый кусочек пищи.

Когда кусочек пищи появляется на экране, гарантируется, что он не появится на блоке, занятом змейкой.

Игра заканчивается, если змейка Đầu raит за пределы экрана (врезается в стену) или если ее голова занимает пространство, которое занимает ее тело после движения (наVí dụ, змейка длиной 4 не может врезаться в себя).

Реализуйте класс SnakeGame:

SnakeGame(int width, int height, int[][] food) Инициализирует объект с экраном размером height x width и позициями пищи.

int move(String direction) returns счет игры после Applications одного движения змейки в направлении. Если игра окончена, return -1.

Ví dụ:

Input

["SnakeGame", "move", "move", "move", "move", "move", "move"]

[[3, 2, [[1, 2], [0, 1]]], ["R"], ["D"], ["R"], ["U"], ["L"], ["U"]]

Output

[null, 0, 0, 1, 1, 2, -1]

C# lời giải

đã khớp/gốc
using System;
using System.Collections.Generic;
public class SnakeGame {
    private int width;
    private int height;
    private int[][] food;
    private int score;
    private LinkedList<int[]> snake;
    private HashSet<string> snakeSet;
    private int foodIndex;
    public SnakeGame(int width, int height, int[][] food) {
        this.width = width;
        this.height = height;
        this.food = food;
        this.score = 0;
        this.snake = new LinkedList<int[]>();
        this.snake.AddFirst(new int[] { 0, 0 });
        this.snakeSet = new HashSet<string>();
        this.snakeSet.Add("0,0");
        this.foodIndex = 0;
    }
    public int Move(string direction) {
        int[] head = snake.First.Value;
        int[] newHead = (int[])head.Clone();
        
        switch (direction) {
            case "U":
                newHead[0]--;
                break;
            case "D":
                newHead[0]++;
                break;
            case "L":
                newHead[1]--;
                break;
            case "R":
                newHead[1]++;
                break;
        }
        if (newHead[0] < 0 || newHead[0] >= height || newHead[1] < 0 || newHead[1] >= width) {
            return -1;
        }
        string newHeadStr = $"{newHead[0]},{newHead[1]}";
        if (snakeSet.Contains(newHeadStr) && !newHeadStr.Equals($"{snake.Last.Value[0]},{snake.Last.Value[1]}")) {
            return -1;
        }
        if (foodIndex < food.Length && newHead[0] == food[foodIndex][0] && newHead[1] == food[foodIndex][1]) {
            foodIndex++;
        } else {
            int[] tail = snake.Last.Value;
            snake.RemoveLast();
            snakeSet.Remove($"{tail[0]},{tail[1]}");
        }
        snake.AddFirst(newHead);
        snakeSet.Add(newHeadStr);
        return snake.Count - 1;
    }
}

C++ lời giải

bản nháp tự động, xem lại trước khi gửi
#include <bits/stdc++.h>
using namespace std;

// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
public class SnakeGame {
    private int width;
    private int height;
    private int[][] food;
    private int score;
    private LinkedList<int[]> snake;
    private HashSet<string> snakeSet;
    private int foodIndex;
    public SnakeGame(int width, int height, int[][] food) {
        this.width = width;
        this.height = height;
        this.food = food;
        this.score = 0;
        this.snake = new LinkedList<int[]>();
        this.snake.AddFirst(new int[] { 0, 0 });
        this.snakeSet = new HashSet<string>();
        this.snakeSet.push_back("0,0");
        this.foodIndex = 0;
    }
    public int Move(string direction) {
        vector<int>& head = snake.First.Value;
        vector<int>& newHead = (int[])head.Clone();
        
        switch (direction) {
            case "U":
                newHead[0]--;
                break;
            case "D":
                newHead[0]++;
                break;
            case "L":
                newHead[1]--;
                break;
            case "R":
                newHead[1]++;
                break;
        }
        if (newHead[0] < 0 || newHead[0] >= height || newHead[1] < 0 || newHead[1] >= width) {
            return -1;
        }
        string newHeadStr = $"{newHead[0]},{newHead[1]}";
        if (snakeSet.Contains(newHeadStr) && !newHeadStr.Equals($"{snake.Last.Value[0]},{snake.Last.Value[1]}")) {
            return -1;
        }
        if (foodIndex < food.size() && newHead[0] == food[foodIndex][0] && newHead[1] == food[foodIndex][1]) {
            foodIndex++;
        } else {
            vector<int>& tail = snake.Last.Value;
            snake.RemoveLast();
            snakeSet.Remove($"{tail[0]},{tail[1]}");
        }
        snake.AddFirst(newHead);
        snakeSet.push_back(newHeadStr);
        return snake.size() - 1;
    }
}

Java lời giải

đã khớp/gốc
class SnakeGame {

    HashMap<Pair<Integer, Integer>, Boolean> snakeMap;
    Deque<Pair<Integer, Integer>> snake;
    int[][] food;
    int foodIndex;
    int width;
    int height;

    public SnakeGame(int width, int height, int[][] food) {
        this.width = width;
        this.height = height;
        this.food = food;
        this.snakeMap = new HashMap<Pair<Integer, Integer>, Boolean>();
        this.snakeMap.put(new Pair<Integer, Integer>(0,0), true); // intially at [0][0]
        this.snake = new LinkedList<Pair<Integer, Integer>>();
        this.snake.offerLast(new Pair<Integer, Integer>(0,0));
    }
    
    public int move(String direction) {

        Pair<Integer, Integer> snakeCell = this.snake.peekFirst();
        int newHeadRow = snakeCell.getKey();
        int newHeadColumn = snakeCell.getValue();

        switch (direction) {
            case "U":
                newHeadRow--;
                break;
            case "D":
                newHeadRow++;
                break;
            case "L":
                newHeadColumn--;
                break;
            case "R":
                newHeadColumn++;
                break;
        }

        Pair<Integer, Integer> newHead = new Pair<Integer, Integer>(newHeadRow, newHeadColumn);
        Pair<Integer, Integer> currentTail = this.snake.peekLast();
        
        boolean crossesBoundary1 = newHeadRow < 0 || newHeadRow >= this.height;
        boolean crossesBoundary2 = newHeadColumn < 0 || newHeadColumn >= this.width;
        
        boolean bitesItself = this.snakeMap.containsKey(newHead) && !(newHead.getKey() == currentTail.getKey() && newHead.getValue() == currentTail.getValue());
        
        if (crossesBoundary1 || crossesBoundary2 || bitesItself) {
            return -1;
        }

        if ((this.foodIndex < this.food.length)
                && (this.food[this.foodIndex][0] == newHeadRow)
                && (this.food[this.foodIndex][1] == newHeadColumn)) {
            this.foodIndex++;
        } else {
            this.snake.pollLast();
            this.snakeMap.remove(currentTail);
        }
        
        this.snake.addFirst(newHead);
        
        this.snakeMap.put(newHead, true);

        return this.snake.size() - 1;
    }
}

JavaScript lời giải

đã khớp/gốc
class SnakeGame {
    constructor(width, height, food) {
        this.width = width;
        this.height = height;
        this.food = food;
        this.score = 0;
        this.snake = [[0, 0]];
        this.snakeSet = new Set(["0,0"]);
        this.foodIndex = 0;
    }

    move(direction) {
        let head = this.snake[0].slice();
        switch (direction) {
            case "U":
                head[0]--;
                break;
            case "D":
                head[0]++;
                break;
            case "L":
                head[1]--;
                break;
            case "R":
                head[1]++;
                break;
        }

        if (head[0] < 0 || head[0] >= this.height || head[1] < 0 || head[1] >= this.width) {
            return -1;
        }

        let newHeadStr = head.toString();
        if (this.snakeSet.has(newHeadStr) && newHeadStr !== this.snake[this.snake.length - 1].toString()) {
            return -1;
        }

        if (this.foodIndex < this.food.length && head[0] === this.food[this.foodIndex][0] && head[1] === this.food[this.foodIndex][1]) {
            this.foodIndex++;
        } else {
            let tail = this.snake.pop();
            this.snakeSet.delete(tail.toString());
        }

        this.snake.unshift(head);
        this.snakeSet.add(newHeadStr);

        return this.snake.length - 1;
    }
}

Python lời giải

đã khớp/gốc
class SnakeGame:
    def __init__(self, width, height, food):
        self.width = width
        self.height = height
        self.food = food
        self.score = 0
        self.snake = [(0, 0)]
        self.snake_set = set([(0, 0)])
        self.food_index = 0

    def move(self, direction):
        head = self.snake[0]
        new_head = list(head)

        if direction == "U":
            new_head[0] -= 1
        elif direction == "D":
            new_head[0] += 1
        elif direction == "L":
            new_head[1] -= 1
        elif direction == "R":
            new_head[1] += 1

        new_head = tuple(new_head)

        if new_head[0] < 0 or new_head[0] >= self.height or new_head[1] < 0 or new_head[1] >= self.width:
            return -1

        if new_head in self.snake_set and new_head != self.snake[-1]:
            return -1

        if self.food_index < len(self.food) and new_head == tuple(self.food[self.food_index]):
            self.food_index += 1
        else:
            tail = self.snake.pop()
            self.snake_set.remove(tail)

        self.snake.insert(0, new_head)
        self.snake_set.add(new_head)

        return len(self.snake) - 1

Go lời giải

đã khớp/gốc
package main

type SnakeGame struct {
    width, height, score, foodIndex int
    food                            [][]int
    snake                           []pair
    snakeSet                        map[pair]bool
}

type pair struct {
    x, y int
}

func Constructor(width int, height int, food [][]int) SnakeGame {
    return SnakeGame{
        width:    width,
        height:   height,
        food:     food,
        score:    0,
        foodIndex: 0,
        snake:    []pair{{0, 0}},
        snakeSet: map[pair]bool{{0, 0}: true},
    }
}

func (this *SnakeGame) Move(direction string) int {
    head := this.snake[0]
    newHead := head

    switch direction {
    case "U":
        newHead.x--
    case "D":
        newHead.x++
    case "L":
        newHead.y--
    case "R":
        newHead.y++
    }

    if newHead.x < 0 || newHead.x >= this.height || newHead.y < 0 || newHead.y >= this.width {
        return -1
    }

    if this.snakeSet[newHead] && (newHead != this.snake[len(this.snake)-1]) {
        return -1
    }

    if this.foodIndex < len(this.food) && newHead.x == this.food[this.foodIndex][0] && newHead.y == this.food[this.foodIndex][1] {
        this.foodIndex++
    } else {
        tail := this.snake[len(this.snake)-1]
        this.snake = this.snake[:len(this.snake)-1]
        delete(this.snakeSet, tail)
    }

    this.snake = append([]pair{newHead}, this.snake...)
    this.snakeSet[newHead] = true

    return len(this.snake) - 1
}

Algorithm

Инициализируйте объекты игры, такие как экран, еда, положение змейки и счетчик, в конструкторе.

Реализуйте функцию для вычисления нового положения головы змейки на основе направления движения.

Обновите положение змейки и проверьте условия завершения игры. return текущий счет или -1, если игра закончена.

😎

Vacancies for this task

việc làm đang hoạt động with overlapping task tags are đã hiển thị.

Tất cả việc làm
Chưa có việc làm đang hoạt động.