Design a Snake game that is played on a device with screen size height x width. The snake is initially positioned at the top left corner (0, 0) with a length of 1 unit.
You are given an array food where food[i] = (ri, ci) is the row and column position of a piece of food that the snake can eat. When a snake eats a piece of food, its length and the game's score both increase by 1.
Each piece of food appears one by one on the screen, meaning the second piece of food will not appear until the snake eats the first piece of food. When a piece of food appears on the screen, it is guaranteed that it will not appear on a block occupied by the snake.
The game is over if the snake goes out of bounds (hits a wall) or if its head occupies a space that its body occupies after moving (i.e. a snake of length 4 cannot run into itself).
Implement the SnakeGame class:
SnakeGame(int width, int height, int[][] food) Initializes the object with a screen of size height x width and the positions of the food.
int move(String direction) Returns the score of the game after applying one direction move by the snake. If the game is over, return -1.
💡 Note:Initialize 3×2 board with food at (1,2) and (0,1). Move right to (0,1): no food available yet (food appears one by one), score=0. Move down to (1,1): still no food at this position, score=0. Move right to (1,2): eat first food piece, score=1.
Example 2 — Hit Boundary
$Input:SnakeGame(3, 2, []), move("L")
›Output:[null, -1]
💡 Note:Snake starts at (0,0). Move left would go to (0,-1) which is out of bounds, so return -1.
The key insight is to use a queue to maintain snake body order and a hash set for O(1) collision detection. The optimal approach combines these data structures for efficient movement processing. Time: O(1) per move, Space: O(n) where n is snake length.
Common Approaches
✓
Brute Force with Array
⏱️ Time: O(n)
Space: O(n)
Use an array to store all snake body positions. For each move, iterate through the entire body to check for self-collision. This approach is straightforward but inefficient for collision detection.
Queue + Hash Set
⏱️ Time: O(1)
Space: O(n)
Combine a queue to maintain snake body order with a hash set for instant collision detection. This eliminates the need to iterate through all body positions when checking for self-collision.
Brute Force with Array — Algorithm Steps
Store snake body positions in array
Move head in given direction
Check bounds and self-collision by iterating array
Handle food consumption and growth
Visualization
Tap to expand
Step-by-Step Walkthrough
1
Initial State
Snake at (0,0) with food at (1,2)
2
Move Right
Check all body positions for collision
3
Result
New position added, score updated if food eaten
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
static int snake[10000][2]; // Snake body coordinates
static int snakeLen;
static int food[50][2]; // Food coordinates
static int foodLen;
static int foodIndex;
static int score;
static int width, height;
static bool gameOver;
void initSnakeGame(int w, int h, int foodArray[][2], int fLen) {
width = w;
height = h;
foodLen = fLen;
for (int i = 0; i < fLen; i++) {
food[i][0] = foodArray[i][0];
food[i][1] = foodArray[i][1];
}
foodIndex = 0;
score = 0;
snakeLen = 1;
snake[0][0] = 0; // row
snake[0][1] = 0; // col
gameOver = false;
}
int move(char* direction) {
if (gameOver) {
return -1;
}
int newHead[2];
newHead[0] = snake[0][0];
newHead[1] = snake[0][1];
if (strcmp(direction, "U") == 0) {
newHead[0]--;
} else if (strcmp(direction, "D") == 0) {
newHead[0]++;
} else if (strcmp(direction, "L") == 0) {
newHead[1]--;
} else { // "R"
newHead[1]++;
}
// Check bounds
if (newHead[0] < 0 || newHead[0] >= height ||
newHead[1] < 0 || newHead[1] >= width) {
gameOver = true;
return -1;
}
// Check if eating food
bool ateFood = (foodIndex < foodLen &&
newHead[0] == food[foodIndex][0] &&
newHead[1] == food[foodIndex][1]);
// Remove tail if not eating food
if (!ateFood) {
snakeLen--;
}
// Check self collision (after removing tail)
for (int i = 0; i < snakeLen; i++) {
if (snake[i][0] == newHead[0] && snake[i][1] == newHead[1]) {
gameOver = true;
return -1;
}
}
// Move snake body and add new head
for (int i = snakeLen; i > 0; i--) {
snake[i][0] = snake[i-1][0];
snake[i][1] = snake[i-1][1];
}
snake[0][0] = newHead[0];
snake[0][1] = newHead[1];
snakeLen++;
if (ateFood) {
score++;
foodIndex++;
}
return score;
}
int parseInt(char* str) {
int result = 0;
int sign = 1;
int i = 0;
while (str[i] == ' ') i++;
if (str[i] == '-') {
sign = -1;
i++;
}
while (str[i] >= '0' && str[i] <= '9') {
result = result * 10 + (str[i] - '0');
i++;
}
return sign * result;
}
int main() {
char line1[1000], line2[2000];
fgets(line1, sizeof(line1), stdin);
fgets(line2, sizeof(line2), stdin);
// Parse operations
char operations[10][20];
int opCount = 0;
char* token = strtok(line1, "[],\"\n ");
while (token != NULL && opCount < 10) {
strcpy(operations[opCount], token);
opCount++;
token = strtok(NULL, "[],\"\n ");
}
// Results array
int results[10];
int resultCount = 0;
// Parse parameters and execute
int opIndex = 0;
char* ptr = line2;
while (opIndex < opCount) {
if (strcmp(operations[opIndex], "SnakeGame") == 0) {
// Find parameter set
while (*ptr && *ptr != '[') ptr++;
ptr++; // Skip '['
// Parse width
int w = parseInt(ptr);
while (*ptr && *ptr != ',') ptr++;
ptr++; // Skip ','
// Parse height
int h = parseInt(ptr);
while (*ptr && *ptr != ',') ptr++;
ptr++; // Skip ','
// Parse food array
int foodArray[50][2];
int fLen = 0;
while (*ptr && *ptr != '[') ptr++;
if (*ptr == '[') {
ptr++; // Skip '['
if (*ptr != ']') {
while (fLen < 50) {
while (*ptr && *ptr != '[') ptr++;
ptr++; // Skip '['
foodArray[fLen][0] = parseInt(ptr);
while (*ptr && *ptr != ',') ptr++;
ptr++; // Skip ','
foodArray[fLen][1] = parseInt(ptr);
while (*ptr && *ptr != ']') ptr++;
ptr++; // Skip ']'
fLen++;
while (*ptr && (*ptr == ',' || *ptr == ' ')) ptr++;
if (*ptr == ']') break;
}
}
while (*ptr && *ptr != ']') ptr++;
ptr++; // Skip ']'
}
initSnakeGame(w, h, foodArray, fLen);
results[resultCount++] = -999; // null placeholder
} else {
// Parse direction
while (*ptr && *ptr != '"') ptr++;
ptr++; // Skip opening quote
char direction[10];
int i = 0;
while (*ptr && *ptr != '"' && i < 9) {
direction[i++] = *ptr++;
}
direction[i] = '\0';
ptr++; // Skip closing quote
int result = move(direction);
results[resultCount++] = result;
}
opIndex++;
while (*ptr && (*ptr == ',' || *ptr == ' ')) ptr++;
}
// Print results
printf("[");
for (int i = 0; i < resultCount; i++) {
if (i > 0) printf(",");
if (results[i] == -999) {
printf("null");
} else {
printf("%d", results[i]);
}
}
printf("]\n");
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
O(n)
Each move requires checking all n body positions for collision
n
2n
✓ Linear Growth
Space Complexity
O(n)
Array stores all n body positions of the snake
n
2n
⚡ Linearithmic Space
28.4K Views
MediumFrequency
~25 minAvg. Time
892 Likes
Ln 1, Col 1
Smart Actions
💡Explanation
AI Ready
💡 SuggestionTabto acceptEscto dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen
Algorithm Visualization
Pinch to zoom • Tap outside to close
Test Cases
0 passed
0 failed
3 pending
Select Compiler
Choose a programming language
Compiler list would appear here...
AI Editor Features
Header Buttons
💡
Explain
Get a detailed explanation of your code. Select specific code or analyze the entire file. Understand algorithms, logic flow, and complexity.
🔧
Fix
Automatically detect and fix issues in your code. Finds bugs, syntax errors, and common mistakes. Shows you what was fixed.
💡
Suggest
Get improvement suggestions for your code. Best practices, performance tips, and code quality recommendations.
💬
Ask AI
Open an AI chat assistant to ask any coding questions. Have a conversation about your code, get help with debugging, or learn new concepts.
Smart Actions (Slash Commands)
🔧
/fix Enter
Find and fix issues in your code. Detects common problems and applies automatic fixes.
💡
/explain Enter
Get a detailed explanation of what your code does, including time/space complexity analysis.
🧪
/tests Enter
Automatically generate unit tests for your code. Creates comprehensive test cases.
📝
/docs Enter
Generate documentation for your code. Creates docstrings, JSDoc comments, and type hints.
⚡
/optimize Enter
Get performance optimization suggestions. Improve speed and reduce memory usage.
AI Code Completion (Copilot-style)
👻
Ghost Text Suggestions
As you type, AI suggests code completions shown in gray text. Works with keywords like def, for, if, etc.
Tabto acceptEscto dismiss
💬
Comment-to-Code
Write a comment describing what you want, and AI generates the code. Try: # two sum, # binary search, # fibonacci
💡
Pro Tip: Select specific code before using Explain, Fix, or Smart Actions to analyze only that portion. Otherwise, the entire file will be analyzed.