Skip to content

feat: add snake game example#718

Open
shaktipy wants to merge 3 commits into
Karanjot786:mainfrom
shaktipy:feat/snake-game-example
Open

feat: add snake game example#718
shaktipy wants to merge 3 commits into
Karanjot786:mainfrom
shaktipy:feat/snake-game-example

Conversation

@shaktipy
Copy link
Copy Markdown

@shaktipy shaktipy commented Jun 4, 2026

Overview

This PR adds a classic Snake Game as a new example in the examples/snake-game directory. It demonstrates how to build an interactive terminal game using TermUI's widget system.

Features

  • 🎮 Movement – Arrow keys or WASD
  • 🍎 Food collection – Eat food to grow and increase score
  • 💥 Collision detection – Walls and self-collision end the game
  • 🔁 Restart – Press R after game over
  • 🚪 Exit – Press Q to quit

Technical Implementation

  • Custom SnakeBoard widget renders the game grid
  • SnakeGame widget manages game state and logic
  • Uses TermUI lifecycle methods: onMount, onUnmount, handleKey, _renderSelf
  • Game loop with setInterval at 150ms tick rate
  • Fully typed TypeScript

How to Run

cd examples/snake-game
bun install
bun run dev

## Fixes #522 

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Added a playable Snake game example with keyboard controls (WASD/arrow keys), real-time score, food consumption, and restart on game-over.
  * Includes collision detection for walls and self-intersections and a centered fullscreen demo with graceful exit keys.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

@shaktipy shaktipy requested a review from Karanjot786 as a code owner June 4, 2026 16:23
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 4, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b1b04728-9463-4977-97bb-ea2d8d4d20b7

📥 Commits

Reviewing files that changed from the base of the PR and between 5f0657f and fbc91c4.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (1)
  • examples/snake-game/src/index.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • examples/snake-game/src/index.tsx

📝 Walkthrough

Walkthrough

Adds a new playable Snake example under examples/snake-game/ with package/tsconfig, a SnakeBoard renderer, SnakeGame state and tick loop (movement, collisions, food, scoring), keyboard input handling, and a main() bootstrap to mount the App.

Changes

Snake Game Example

Layer / File(s) Summary
Project configuration and dependencies
examples/snake-game/package.json, examples/snake-game/tsconfig.json
Package metadata defines the example as a private ESM module with dev, build, and typecheck scripts; TypeScript config targets ES2022 with JSX via @termuijs/jsx, strict settings, and workspace deps on core and widgets.
Game board constants and rendering
examples/snake-game/src/index.tsx (constants, SnakeBoard)
Grid dimensions and tick interval constants; SnakeBoard widget renders snake and food onto a character grid and reacts to state updates.
Game state initialization
examples/snake-game/src/index.tsx (SnakeGame constructor)
SnakeGame initializes title, score, board, snake position/direction/score and generates initial food avoiding the snake body.
Game mechanics and lifecycle
examples/snake-game/src/index.tsx (moveSnake, endGame, restart, mount/unmount)
moveSnake advances the snake, detects wall/self collisions, handles food consumption and scoring, endGame halts the tick and shows game-over, restart resets state; lifecycle hooks manage the interval.
Input handling and application bootstrap
examples/snake-game/src/index.tsx (handleKey, main)
handleKey processes WASD/arrow keys with opposite-direction prevention, restart on r, quit on q or Ctrl+C; main() mounts the centered fullscreen App, wires key events, requests renders, and exits on quit.

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped to the terminal, keys in paw,
A snake on the grid that I watched in awe,
Pellets to munch and walls to avoid,
Press r to retry when fate is deployed,
Play, quit, restart — a tiny bundle of joy.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning Description covers overview, features, technical implementation, and how to run. However, it lacks several required template sections: Related Issue link, Which package(s), Type of Change checkboxes, and Checklist items. Complete the PR description with: explicit 'Closes #522' in Related Issue section, package identification (@termuijs/examples or similar), checked Type of Change box (Feature), and verification of all Checklist items.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed Title clearly and specifically summarizes the main change: adding a snake game example, which is the primary objective of the PR.
Linked Issues check ✅ Passed PR implementation aligns with issue #522 requirements: creates snake-game example with Grid, movement, food, collision detection, restart on R, quit on Q/Ctrl+C, uses TermUI lifecycle methods, and includes proper config files.
Out of Scope Changes check ✅ Passed All changes are confined to examples/snake-game/ directory. No modifications to packages/ or other areas outside scope. Changes include package.json, tsconfig.json, and index.tsx as specified.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added needs-star PR author has not starred the repo. type:feature +10 pts. New feature. labels Jun 4, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 4, 2026

Hi @shaktipy 👋

Star this repo before your PR merges.

Why? GSSoC 2026 contributors who star get priority review and points credit. After you star, push any commit (or re-run this check). The needs-star label lifts automatically.

Thanks for your contribution to TermUI.

@github-actions github-actions Bot added the area:examples Example apps. label Jun 4, 2026
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 Thanks for your first PR to TermUI, @shaktipy.

Before your PR merges:

  1. Star the repo. Required. The star-check job blocks your merge otherwise.
  2. ✅ All checks green: build, test, typecheck.
  3. 🏷 PR title follows type: short description. Example: fix: handle empty list.
  4. 🔗 Link your closing issue in the description.

GSSoC 2026 points come from labels after merge:

  • gssoc:approved. +50 base points.
  • level:beginner / intermediate / advanced / critical. +20 / +35 / +55 / +80.
  • quality:clean / exceptional. x 1.2 / x 1.5.
  • type:*. Stackable bonus.

Your reviewer responds within 48 hours. Ping @Karanjot786 on Discord for urgent help.

🚀 Welcome to the cohort.

@github-actions github-actions Bot removed the needs-star PR author has not starred the repo. label Jun 4, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/snake-game/src/index.tsx`:
- Around line 96-105: The generateRandomFood() function can infinite-loop if the
snake fills the whole GRID_SIZE*GRID_SIZE board; update generateRandomFood to
first check if this.snake.length >= GRID_SIZE * GRID_SIZE and handle the "board
full" case by returning null (or throwing a clear BoardFullError) instead of
looping forever, change its return type to {x:number;y:number}|null (or keep
throwing) and then update callers (notably the food-spawn after eating in the
move/eat handler) to handle the null/board-full result by ending the game or
skipping spawning new food. Ensure references to generateRandomFood, the
food-spawn logic after eating, and the game-over/end-game handler are updated to
handle the new behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f120a034-baae-4980-97a7-5e2324e169ec

📥 Commits

Reviewing files that changed from the base of the PR and between 142e1e3 and 5f0657f.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • examples/snake-game/package.json
  • examples/snake-game/src/index.tsx
  • examples/snake-game/tsconfig.json

Comment thread examples/snake-game/src/index.tsx Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:examples Example apps. type:feature +10 pts. New feature.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant