Weekend Programming Challenge – Week #37 – Snake Retro Game

Image

Problem:

Make your own snake game!

Do you remember the Nokia phones Snake game? You move the snake with 4 keys and it eats apples on the screen and gets bigger, collision with walls or snake body ends the game.

The rules:

You can code the solution in any programming language during the weekend and have to submit it to info@olimex.com latest on Sunday December 15th.

On Monday we will upload the solutions on GitHub https://github.com/OLIMEX/WPC

You can play with your real name or with nick if you want to be anonymous, we will not disclosure your personal info if you do not want to.

DuinoMite – retro Snake game written in Basic

I will admit that I didn’t wrote computer games since I was 14, but recently user of The Back Shed forum named Darthmite inspired me when he wrote two games in MM Basic – Bricks and Space Invaders.

This weekend I had some free time and decided to try code some of the old time retro games in Basic.
Snake was good candidate as it’s very easy as concept and would not take much time, so I started:

1. had to define the game constants as I wanted it to make it flexible as much as possible

10 ESC = 27: LF = 130: RG = 131: UP =128: DN = 129 ‘keyboard keys to play Esc-exit and the arrows
20 OPTION BASE 0
30 MAXSNAKE = 14 ‘max length of the snake to go to upper level
40 MAXSTAGE = 5 ‘max number of levels actually anything above stage 2 is very hard to complete
50 DIM SNAKEX(MAXSNAKE),SNAKEY(MAXSNAKE) ‘here we will keep snake body coordinates
60 MAXX = 40 ‘playfield X size
70 MAXY = 30 ‘playfield Y size
80 SIZEX=5 ‘snake body X size
90 SIZEY=10 ‘snake body Y size
100 BLOCKS = 4 ‘snake body initial length
110 STAGE = 1 ‘start from stage 1
120 DIRECTION = 2 ‘initial move direction
130 POINT = 0 ‘number of points
140 SPEED = 100 ‘speed delay

then we have to display the game rules:

150 CLS
160 PRINT “SNAKE GAME 1.0 15.01.2011 OLIMEX LTD http://www.olimex.com”
170 PRINT “MAX SNAKE LENGHT “;MAXSNAKE
180 PRINT “MAX STAGES “;MAXSTAGE
190 PRINT “PLAYFIELD SIZE “;MAXX;” x “;MAXY
200 PRINT “USE UP-DOWN-LEFT-RIGHT KEYS TO MOVE SNAKE DIRECTION”
210 PRINT “PRESS ANY KEY TO START”
220 IF INKEY$=”” THEN 220

and we can start the game:

230 ‘START
240 CLS ‘clear screen and draw the play field
250 LINE (0,0)-(MAXX*SIZEX+SIZEX,0): LINE -(MAXX*SIZEX+SIZEX,MAXY*SIZEY+SIZEY)
260 LINE -(0,MAXY*SIZEY+SIZEY): LINE -(0,0)
270 LOCATE MAXX*SIZEX+10,0 : PRINT “POINTS: “;POINT
280 LOCATE MAXX*SIZEX+10,12 : PRINT “STAGE : “;STAGE
290 FOR I = 0 TO BLOCKS: SNAKEX(I) = MAXX \ 2: SNAKEY(I) = MAXY \ 2 – I: NEXT I ‘init snake body
300 X = SNAKEX(0): Y = SNAKEY(0)
310 DIRECTION = 2
320 FOR I = 0 TO BLOCKS ‘draw snake body
330 LINE (SNAKEX(I)*SIZEX+1,SNAKEY(I)*SIZEY+1)-(SNAKEX(I)*SIZEX+SIZEX-1,SNAKEY(I)*SIZEY+SIZEY-1),1,BF
340 NEXT I

now let’s draw some food for the snake:

350 RANDOMIZE = TIMER
360 TARGETX = CINT(RND*MAXX) : TARGETY = CINT(RND*MAXY)
370 CIRCLE (TARGETX*SIZEX+SIZEX\2,TARGETY*SIZEY+5)+SIZEY\2,SIZEX\2,1,F

and we start the main game loop:

380 ‘MAINLOOP
390 KEY$=INKEY$ ‘get keyboard input and handle the keys
400 IF KEY$=CHR$(ESC) THEN CLS: END
410 IF KEY$=CHR$(UP) THEN IF DIRECTION <>1 THEN DIRECTION = 0
420 IF KEY$=CHR$(DN) THEN IF DIRECTION <>0 THEN DIRECTION = 1
430 IF KEY$=CHR$(RG) THEN IF DIRECTION <>3 THEN DIRECTION = 2
440 IF KEY$=CHR$(LF) THEN IF DIRECTION <>2 THEN DIRECTION = 3
450 IF DIRECTION = 0 THEN Y = Y-1
460 IF DIRECTION = 1 THEN Y = Y+1
470 IF DIRECTION = 2 THEN X = X+1
480 IF DIRECTION = 3 THEN X = X-1

then check for game over – if the snake crash to walls or bit itself

490 IF X<0 OR Y<0 OR X>MAXX OR Y>MAXY THEN 810
500 FOR I = 1 TO BLOCKS
510 IF SNAKEX(0)=SNAKEX(I) AND SNAKEY(0)=SNAKEY(I) THEN 810
520 NEXT I

then check if snake hit some food and increase snake size in this case:

530 IF SNAKEX(0) = TARGETX AND SNAKEY(0) = TARGETY THEN
540 SOUND 700,100: PAUSE 100
550 CIRCLE (TARGETX*SIZEX+SIZEX\2,TARGETY*SIZEY+5)+SIZEY\2,SIZEX\2,0,F
560 LINE (TARGETX*SIZEX+1,TARGETY*SIZEY+1)-((TARGETX+1)*SIZEX-1,(TARGETY+1)*SIZEY-1),1,BF
570 TARGETX = CINT(RND*MAXX) : TARGETY = CINT(RND*MAXY)
580 CIRCLE (TARGETX*SIZEX+SIZEX\2,TARGETY*SIZEY+5)+SIZEY\2,SIZEX\2,1,F
590 POINT = POINT+10
600 BLOCKS = BLOCKS+1
610 LOCATE MAXX*SIZEX+10,0 : PRINT “POINTS: “;POINT
620 ENDIF

if the snake grow to max length move to new stage:

630 IF BLOCKS = MAXSNAKE THEN
640 STAGE = STAGE + 1
650 IF STAGE = MAXSTAGE THEN 850
660 BLOCKS = 4
670 SPEED = 100 \ STAGE
680 LOCATE MAXX*SIZEX+10,22: PRINT “STAGE : “;STAGE-1;” CLEAR”
690 PAUSE 2000
700 LOCATE MAXX*SIZEX+10,22: PRINT ” “
710 GOTO 230
720 ENDIF

if no walls, no self bite nor hit food then just move the snake

730 LINE (X*SIZEX+1,Y*SIZEY+1)-((X+1)*SIZEX-1,(Y+1)*SIZEY-1),1,BF
740 PAUSE SPEED
750 LINE (SNAKEX(BLOCKS)*SIZEX+1,SNAKEY(BLOCKS)*SIZEY+1)-(SNAKEX(BLOCKS)*SIZEX+SIZEX-1,SNAKEY(BLOCKS)*SIZEY+SIZEY-1),0,BF
760 FOR I = BLOCKS TO 1 STEP -1
770 SNAKEX(I) = SNAKEX(I-1): SNAKEY(I) = SNAKEY(I-1)
780 NEXT I
790 SNAKEX(0)=X: SNAKEY(0)=Y

then close the main loop:

800 GOTO 380

or handle the Game Over:

810 FOR I = 700 TO 100 STEP -100: SOUND I,100: PAUSE 100: NEXT I
820 LOCATE MAXX*SIZEX+10,22: PRINT “GAME OVER”
830 PAUSE 2000
840 RUN

if all sgates are complete (which I highly doubt as speed become terrible after Stage 2:

850 LOCATE MAXX*SIZEX+10,22: PRINT ” YOU ARE GENIUS!”
860 END

—————————–

the complete code is below:

10 ESC = 27: LF = 130: RG = 131: UP =128: DN = 129
20 OPTION BASE 0
30 MAXSNAKE = 14
40 MAXSTAGE = 5
50 DIM SNAKEX(MAXSNAKE),SNAKEY(MAXSNAKE)
60 MAXX = 40
70 MAXY = 30
80 SIZEX=5
90 SIZEY=10
100 BLOCKS = 4
110 STAGE = 1
120 DIRECTION = 2
130 POINT = 0
140 SPEED = 100
150 CLS
160 PRINT “SNAKE GAME 1.0 15.01.2011 OLIMEX LTD http://www.olimex.com&#8221;
170 PRINT “MAX SNAKE LENGHT “;MAXSNAKE
180 PRINT “MAX STAGES “;MAXSTAGE
190 PRINT “PLAYFIELD SIZE “;MAXX;” x “;MAXY
200 PRINT “USE UP-DOWN-LEFT-RIGHT KEYS TO MOVE SNAKE DIRECTION”
210 PRINT “PRESS ANY KEY TO START”
220 IF INKEY$=”” THEN 220
230 ‘START
240 CLS
250 LINE (0,0)-(MAXX*SIZEX+SIZEX,0): LINE -(MAXX*SIZEX+SIZEX,MAXY*SIZEY+SIZEY)
260 LINE -(0,MAXY*SIZEY+SIZEY): LINE -(0,0)
270 LOCATE MAXX*SIZEX+10,0 : PRINT “POINTS: “;POINT
280 LOCATE MAXX*SIZEX+10,12 : PRINT “STAGE : “;STAGE
290 FOR I = 0 TO BLOCKS: SNAKEX(I) = MAXX \ 2: SNAKEY(I) = MAXY \ 2 – I: NEXT I
300 X = SNAKEX(0): Y = SNAKEY(0)
310 DIRECTION = 2
320 FOR I = 0 TO BLOCKS
330 LINE (SNAKEX(I)*SIZEX+1,SNAKEY(I)*SIZEY+1)-(SNAKEX(I)*SIZEX+SIZEX-1,SNAKEY(I)*SIZEY+SIZEY-1),1,BF
340 NEXT I
350 RANDOMIZE = TIMER
360 TARGETX = CINT(RND*MAXX) : TARGETY = CINT(RND*MAXY)
370 CIRCLE (TARGETX*SIZEX+SIZEX\2,TARGETY*SIZEY+5)+SIZEY\2,SIZEX\2,1,F
380 ‘MAINLOOP
390 KEY$=INKEY$
400 IF KEY$=CHR$(ESC) THEN CLS: END
410 IF KEY$=CHR$(UP) THEN IF DIRECTION <>1 THEN DIRECTION = 0
420 IF KEY$=CHR$(DN) THEN IF DIRECTION <>0 THEN DIRECTION = 1
430 IF KEY$=CHR$(RG) THEN IF DIRECTION <>3 THEN DIRECTION = 2
440 IF KEY$=CHR$(LF) THEN IF DIRECTION <>2 THEN DIRECTION = 3
450 IF DIRECTION = 0 THEN Y = Y-1
460 IF DIRECTION = 1 THEN Y = Y+1
470 IF DIRECTION = 2 THEN X = X+1
480 IF DIRECTION = 3 THEN X = X-1
490 IF X<0 OR Y<0 OR X>MAXX OR Y>MAXY THEN 810
500 FOR I = 1 TO BLOCKS
510 IF SNAKEX(0)=SNAKEX(I) AND SNAKEY(0)=SNAKEY(I) THEN 810
520 NEXT I
530 IF SNAKEX(0) = TARGETX AND SNAKEY(0) = TARGETY THEN
540 SOUND 700,100: PAUSE 100
550 CIRCLE (TARGETX*SIZEX+SIZEX\2,TARGETY*SIZEY+5)+SIZEY\2,SIZEX\2,0,F
560 LINE (TARGETX*SIZEX+1,TARGETY*SIZEY+1)-((TARGETX+1)*SIZEX-1,(TARGETY+1)*SIZEY-1),1,BF
570 TARGETX = CINT(RND*MAXX) : TARGETY = CINT(RND*MAXY)
580 CIRCLE (TARGETX*SIZEX+SIZEX\2,TARGETY*SIZEY+5)+SIZEY\2,SIZEX\2,1,F
590 POINT = POINT+10
600 BLOCKS = BLOCKS+1
610 LOCATE MAXX*SIZEX+10,0 : PRINT “POINTS: “;POINT
620 ENDIF
630 IF BLOCKS = MAXSNAKE THEN
640 STAGE = STAGE + 1
650 IF STAGE = MAXSTAGE THEN 850
660 BLOCKS = 4
670 SPEED = 100 \ STAGE
680 LOCATE MAXX*SIZEX+10,22: PRINT “STAGE : “;STAGE-1;” CLEAR”
690 PAUSE 2000
700 LOCATE MAXX*SIZEX+10,22: PRINT ” “
710 GOTO 230
720 ENDIF
730 LINE (X*SIZEX+1,Y*SIZEY+1)-((X+1)*SIZEX-1,(Y+1)*SIZEY-1),1,BF
740 PAUSE SPEED
750 LINE (SNAKEX(BLOCKS)*SIZEX+1,SNAKEY(BLOCKS)*SIZEY+1)-(SNAKEX(BLOCKS)*SIZEX+SIZEX-1,SNAKEY(BLOCKS)*SIZEY+SIZEY-1),0,BF
760 FOR I = BLOCKS TO 1 STEP -1
770 SNAKEX(I) = SNAKEX(I-1): SNAKEY(I) = SNAKEY(I-1)
780 NEXT I
790 SNAKEX(0)=X: SNAKEY(0)=Y
800 GOTO 380
810 FOR I = 700 TO 100 STEP -100: SOUND I,100: PAUSE 100: NEXT I
820 LOCATE MAXX*SIZEX+10,22: PRINT “GAME OVER”
830 PAUSE 2000
840 RUN
850 LOCATE MAXX*SIZEX+10,22: PRINT ” YOU ARE GENIUS!”
860 END

Have fun :)

Next weekend if I have some more free will try to write TETRIS for DuinoMite

Follow

Get every new post delivered to your Inbox.

Join 528 other followers