How to Create a Snake Game in Batch Script
Building classic arcade games like Snake inside the Windows Command Prompt pushes the absolute limits of Batch scripting. Unlike a simple text adventure where the script waits endlessly for the user to type a command (set /p), a Snake game requires real-time execution. The snake must continue moving across the screen even if the user isn't pressing any keys, and the screen must redraw itself rapidly without flickering.
Because natively pulling non-blocking keyboard input and generating 60-FPS redraws is nearly impossible in pure Batch, we must rely on the choice command's timeout feature and simulate an X/Y coordinate grid.
In this guide, we will demonstrate the core concepts required to build a functional, grid-based Snake game natively.
The Strategy: Real-Time Movement
- Grid System: The game board is an invisible coordinate plane (e.g., 20x10). The Snake's head is defined by an
XandYvariable. - The Apple: A piece of food exists at a randomized
appleXandappleYlocation. - Non-Blocking Input: We use the
choicecommand with a/t 1timeout. If the user presses W, A, S, or D, the snake changes direction. If they press nothing within 1 second, it remembers its last direction and moves automatically. - Drawing the Frame: The script clears the screen (
cls) and draws the entire board row-by-row, printing a body segment if the current coordinate matches the Snake's location, or a blank space if it doesn't.
Implementation Script (Core Engine)
A true, fully-featured Snake game with a growing tail array requires hundreds of lines of complex buffer management and array shifting. This script provides the foundational moving-head and apple-eating engine to demonstrate the core concepts.
@echo off
setlocal EnableDelayedExpansion
:: Configure Terminal Window (Width=40, Height=25)
mode con: cols=40 lines=25
title Batch Snake Engine
color 0A
:NewGame
:: 1. Initialize Game Variables
set "width=20"
set "height=10"
:: Snake starting position (center of board)
set "headX=10"
set "headY=5"
set "direction=D"
set "score=0"
:: Generate first Apple (ensure it does not spawn on the snake)
call :SpawnApple
:: 2. The Main Game Loop
:GameLoop
:: 3. Non-Blocking Input via CHOICE
:: Wait 1 second for W/A/S/D. Defaults to current direction if no key is pressed.
choice /c WASD /n /t 1 /d !direction! >nul
:: Capture errorlevel immediately before any other command can alter it.
:: choice sets errorlevel 1-4 corresponding to the character position in /c.
:: Must check from highest to lowest because "if errorlevel N" means >= N.
set "newDir=!direction!"
if errorlevel 4 (
set "newDir=D"
) else if errorlevel 3 (
set "newDir=S"
) else if errorlevel 2 (
set "newDir=A"
) else if errorlevel 1 (
set "newDir=W"
)
set "direction=!newDir!"
:: 4. Move the Snake Coordinates
if "!direction!"=="W" set /a "headY-=1"
if "!direction!"=="S" set /a "headY+=1"
if "!direction!"=="A" set /a "headX-=1"
if "!direction!"=="D" set /a "headX+=1"
:: 5. Boundary Collision (Wall Hit)
if !headX! lss 1 goto GameOver
if !headX! gtr !width! goto GameOver
if !headY! lss 1 goto GameOver
if !headY! gtr !height! goto GameOver
:: 6. Check if Apple was eaten
if !headX! equ !appleX! if !headY! equ !appleY! (
set /a "score+=1"
call :SpawnApple
)
:: 7. Render the Screen
cls
echo ============================
echo SCORE: !score!
echo ============================
:: Loop through every row and column
for /l %%Y in (1,1,!height!) do (
set "row="
for /l %%X in (1,1,!width!) do (
set "cell=."
:: Draw Apple
if %%X equ !appleX! if %%Y equ !appleY! set "cell=O"
:: Draw Snake Head (drawn after apple so head is visible if overlapping)
if %%X equ !headX! if %%Y equ !headY! set "cell=@"
:: Append to row string
set "row=!row!!cell!"
)
echo !row!
)
echo ============================
goto GameLoop
:: ------------------------------------------
:: Subroutines
:: ------------------------------------------
:SpawnApple
set /a "appleX=(!RANDOM! %% %width%) + 1"
set /a "appleY=(!RANDOM! %% %height%) + 1"
:: Prevent apple from spawning directly on the snake head
if !appleX! equ !headX! if !appleY! equ !headY! goto SpawnApple
exit /b
:GameOver
cls
echo ============================
echo GAME OVER^^!
echo ============================
echo You hit the wall^^!
echo Final Score: !score!
echo.
set "retry="
set /p "retry=Play Again? (Y/N): "
if /i "!retry!"=="Y" goto NewGame
echo Thanks for playing^^!
pause
exit /b
How It Works
- Grid Rendering: The double
FOR /Lloops create the visual board. It iterates Row 1 through 10, Columns 1 through 20. Every coordinate(X,Y)is evaluated. If the coordinate matchesappleX, appleY, anOis printed. If it matchesheadX, headY, an@is printed. Otherwise, a.is printed. choice /d /t: This is the mechanism that allows real-time movement.choice /c WASDrestricts input to those four keys. The/t 1parameter tells the prompt to only wait 1 second for input before giving up. The/d !direction!parameter tells it to automatically default back to the previous direction if the timer expires. Theerrorlevelvalues must be checked from highest to lowest becauseif errorlevel Nin Batch means "errorlevel is greater than or equal to N."- Coordinate Math: Pressing
W(Up) subtracts 1 from the Y-coordinate. PressingD(Right) adds 1 to the X-coordinate. The next time the grid renders, the@appears one space shifted in that direction.
Why is Full Snake so Difficult in Batch?
While the engine above works natively, adding the "trailing tail" requires storing an array (simulated via indexed variables) of historical X/Y coordinates for every snake segment, shifting them sequentially on every frame, and checking for self-collision gracefully. Additionally, utilizing cls for redrawing the screen causes noticeable screen flickering. Advanced batch developers often utilize ANSI escape codes (e.g., echo [H to reset the cursor to the top-left) to overwrite text in place without clearing the screen, significantly reducing flicker.
Conclusion
Building real-time games stretches Batch far beyond its intended administrative design by utilizing the asynchronous capabilities of the choice command. Constructing a basic Snake engine proves you comprehend coordinate math, high-speed iteration rendering, and variable preservation across continuous loops natively inside the Windows Terminal.