How it's built
Snake is pure Kiste. It uses only the built-in modules gui,
klang, liste, zufall, wert,
datei and text. Here are the most interesting parts.
1 · The snake is two lists
No object, no grid — the snake is simply a sequence of cells. Segment number i
sits in schlange_x[i] / schlange_y[i], the head right at the
back. Two numbers dx/dy remember the direction.
// The snake lives in two parallel lists — segment i has its
// position in schlange_x[i] / schlange_y[i]. The head is at the back.
nimm schlange_x = [10, 11, 12]
nimm schlange_y = [15, 15, 15]
nimm dx = 1 // direction: to the right
nimm dy = 0 2 · Growing and crawling in four lines
The whole movement trick: every tick a new head grows at the front. If it eats food, the tail stays — the snake gets longer. Otherwise a segment drops off the back — it crawls on. Append at the front, remove at the back, done.
// Every tick: move the head by (dx, dy) …
nimm kopf_x = glied_x(n - 1) + dx
nimm kopf_y = glied_y(n - 1) + dy
liste.hänge_an(schlange_x, kopf_x) // head grows forward …
liste.hänge_an(schlange_y, kopf_y)
wenn kopf_x == futter_x und kopf_y == futter_y {
punkte = punkte + 1 // … ate food: the snake stays longer
neues_futter()
} sonst {
liste.entferne(schlange_x, 0) // … otherwise the tail follows
liste.entferne(schlange_y, 0)
} 3 · Food on a free cell
New food must not land on the snake. So we roll a position and re-roll as long as it's occupied — simple and perfectly enough.
// Roll food onto a free cell — never onto the snake.
funktion neues_futter() {
futter_x = zufall.ganz(0, 39)
futter_y = zufall.ganz(0, 29)
solange auf_schlange(futter_x, futter_y) == 1 {
futter_x = zufall.ganz(0, 39)
futter_y = zufall.ganz(0, 29)
}
} 4 · The forbidden turn
A classic Snake bug: the snake drives back into itself. A small condition forbids the 180-degree turn — going right only works if you're not currently heading left.
// The 180-degree turn is forbidden — the snake can't drive
// back into itself.
wenn taste == "links" und dx != 1 { dx = -1
dy = 0 }
wenn taste == "rechts" und dx != -1 { dx = 1
dy = 0 } 5 · A high-score list without a sort function
Two parallel lists hold scores and names. Instead of sorting, we insert each new result at the right spot straight away — so the list stays ordered. It's saved as a text file and survives a restart.
// INSERT each result at the right spot — the list stays sorted
// at all times, with no sort function at all.
funktion sortiert_einfügen(p, name) {
nimm pos = 0
für i = 0 bis liste.länge(rang_punkte) - 1 {
wenn rang(i) < p { pos = i + 1 }
}
liste.füge_ein(rang_punkte, pos, p)
liste.füge_ein(rang_namen, pos, name)
} 6 · The name — typed after the game
Like the old arcade machines, the player types their name after the round, straight onto the game-over screen. No text field that disrupts the controls during play — the key handler reads the letters itself.
// The name is typed AFTER the game — straight onto the game-over
// screen, no text field that steals the keys during play.
sonstwenn taste == "BackSpace" {
eingabe_name = text.erste_n(eingabe_name, länge(eingabe_name) - 1)
} sonstwenn länge(taste) == 1 {
wenn länge(eingabe_name) < 14 { eingabe_name = "{eingabe_name}{taste}" }
} That's all of it: two lists, one timer, a bit of randomness. The full source is included in the download above — make the field bigger, the snake faster, or build your own game from it.