Snake

This is a remake of a popular microcomputer game SNAKE. I do not know who originally came up with the idea for the game (or, even, on what microcomputer it appeared first). The implementation I saw was 30-something lines of code, which was amazingly short for such a nice and seemingly complex game.

Rules

Control snake that crawls across the screen. Avoid walls, stones ('#') and biting own body. Eat digits that randomly appear on the screen. Each eaten digit causes snake to grow. The goal is to grow as much as you can.

There is a way to clear stones from the way: press space bar when snake's head is right before stone and stone will disappear. Timing is crucial: too early or too late and you will hit the stone, causing game over.

Code and comments


Download the SNAKE.NSG code.

Original 30-something line code was not terribly complicated or awfully long. It did have, however, quite a few "IF"s -- more than would comfortably fit into 3 lines. Some of those ifs seemed inevitable. How would you read keyboard input and assign new direction without at least 4 "IF"s?

Below is unfolded, spaceified and commented code.
'1
WIDTH 40
FOR I=1 TO 10
  KEY I,""
NEXT
     This clears function key hints, so they are not displayed. Easier way would be to use KEY OFF operator, but I needed them on, so I could youse hint for "F8" to display current score.
DEFINT A-Z
G=1+RND(-TIME)
CLS
DIM A(800)
A(0)=41
     Initialize G (direction) with 1 ("to the right") and also randomize random seed using timer at the same time. Since DEFINT A-Z is in action, G will remain 1.
FOR I=0 TO 39
  VPOKE I,42
  VPOKE I+880,42
NEXT
     Horizotal walls -- one on top, one on bottom.
FOR I=40 TO 880 STEP40
  VPOKE I,42
  VPOKE I+39,42
NEXT
     Vertical walls -- one on left, one on right. Walls are composed of "*" character and cannot be wiped with a space bar.
FOR X=1 TO 15
  FOR Y=1 TO 3
    FOR Z=1 TO 20
     Main loop
      F=A(C)+G
'2
      E=VPEEK(F)
      H=ASC(INKEY$+"!")
    
      E=-(H=32)*(ABS(-(E><35)*E-16)+16)-(H><32)*E
     ' if h=" " and e="#" then e=" "
' if h=28 then g=1 else if h=29 then g=-1 else if h=30 then g=-40 else if g=31 then g=40 else if h=33 or h=32 then g=g else g=0
      G=-(28=H)+(29=H)-40*(31=H)+40*(30=H)-G*(H=33ORH=32)
      C=(C+1) MOD 800
      A(C)=F
      VPOKE F,37
      IF E<48 AND E>32 THEN
    
        X=15
        Y=3
        Z=20
     Exit main loop
      ELSE
        D=D+ABS(SGN(E-32)*E-24)-24
        IF D>0 THEN
          D=D-1
          S=S+10
        ELSE
          B=(B+1) MOD 800
          VPOKEA(B),32
        [endif]
      [endif]
'3
      KEY 8,STR$(S)
    NEXT
    D=D+1
    E=RND(1)*960
    F=VPEEK(E)
    VPOKE E,ABS((1-SGN(F-32))*(INT(RND(1)*9+1)+48)-F/2)+F/2
  NEXT
  E=RND(1)*960
  F=VPEEK(E)
  VPOKE E,ABS((1-SGN(F-32))*35-F/2)+F/2
NEXT X
LOCATE 0,24
PRINT
PRINT"Score :"S
IF S>500 THEN
  FOR I=0 TO 999
  NEXT
  RUN
ELSE
  END
[endif]
This game layed groundwork for the rest of the series. For the first time here I used comparison and logical operators in arithmetic expressions, which allowed significantly simplify program structure and reduce size. Without this tecnique most of the following would not be possible.


[ MSX BASIC | << Previous | Next >> | Feedback ]