rem cs snake program rem copyright 2016 rem Catsfolly ' We need some important constants. include "constants.bas" const maxlen = 600 const maxIndex = maxlen-1 const dirup = 0 const dirright = 1 const dirdown = 2 const dirleft = 3 const screen_width = 40 const screen_height = 24 REM ------------------------------------------------------------------------- REM Variables. REM ------------------------------------------------------------------------- dim xx(2) ' Array to hold start/end X coordinates for the line. dim yy(2) ' Array to hold start/end Y coordinates for the line. colour = 0 dim snake(maxlen/4) ' snake data (direction to move to next snake piece) WAIT DEFINE 0,10,game_tiles wait start: dir = dirright sprite 0,0,0,0 sprite 1,0,0,0 cls ' clear the screen print "CS Snake S:00000" rem fill the screen with border pixels colour = 1 for y = 2 to (screen_height-1) for x = 0 to (screen_width-1) xx(0) = x yy(0) = y gosub CsPlot next x next y rem now clear out the center colour = 0 for x = 0 to 19 for y = 3 to (screen_height-2) xx(0) = 20 -x yy(0) = y gosub CsPlot next y for y = 3 to (screen_height-2) xx(0) = 19 + x yy(0) = y gosub CsPlot next y next x food = 0 ' food position. 0 means no food on screen #score = 0 ' score wait wait wait rem init snake snake(0) = $55 sx = 20 sy = 12 tx = 19 ty = 12 #slen = 2 #head_i = 1 #tail_i = 0 xx(0) = sx yy(0) = sy colour = 2 gosub CsPlot xx(0) = tx yy(0) = ty gosub CsPlot loop: wait rem if there is no food then try a random number. If the random number < 240 and the location at backtab rem + the number is blank, then draw the food there and set food to the random number rem if food = 0 then food = RAND : if (food > 240) OR (peek(backtab + food) <> 0) then food = 0 else poke backtab+food,greenF if food = 0 then fx = random(37) + 1 fy = random(19) + 3 xx(0) = fx yy(0) = fy gosub CSReadPixel if (pixelValue = 0) then colour = 5 gosub CsPlot food = 1 atefood = 0 sprite 1, (fx * 4) + 8 + VISIBLE, (fy * 4) + 9,SPR_WHITE + GRAM + (2 * 8) end if end if rem set the direction variable based on the controls (uses exact directions, so probably unplayable with a rem real intelliision controller if cont1.left then dir = dirleft else if cont1.right then dir = dirright else if cont1.up then dir = dirup else if cont1.down then dir = dirdown if (frame AND $07) = 2 then print at 14, <5> #score : goto loop if (frame AND $07) <> 0 then goto loop ' slow down the action gosub SaveDir sx = sx + xinc(dir) sy = sy + yinc(dir) gosub putFace xx(0) = sx yy(0) = sy gosub CsReadPixel if pixelValue = 5 then atefood = 1 else if pixelValue <> 0 then goto game_over colour = 2 gosub CsPlot rem if we ate the food, add to the score and set food to zero if atefood > 0 then food = 0 #score = #score + 1 sprite 1,0,0,0 end if rem if we ate food and the snake is less than max length, make it longer if (atefood > 0) and (#slen < maxlen) then #slen = #slen + 1 else ' erase the tail of the snake xx(0) = tx yy(0) = ty colour = 0 gosub CsPlot gosub updateTail end if atefood = 0 goto loop game_over: print at 0, "Game Over" rem print at 44, "score = " rem print <3> score game_over_loop: wait if cont.key = 12 then goto game_over_loop else goto start xinc: data 0,1,0,-1 yinc: data -1,0,1,0 REM ------------------------------------------------------------------------- REM CsPlot - Plot a pixel in coloured squares mode. REM ------------------------------------------------------------------------- REM REM Input: REM xx(0) - X coordinate (in the range 0 to 39). REM yy(0) - Y coordinate (in the range 0 to 23). REM colour - Colour of the pixel (in the range 0 to 6). REM REM Trashes: REM #newPixel, #oldPixelMask, where, #what REM REM ------------------------------------------------------------------------- CsPlot: procedure ' Pick the colour of the pixel from the right table based on whether ' the X and Y coordinates are odd or even. if yy(0) AND 1 then if xx(0) AND 1 then #newPixel=CsColourPix3Table(colour) #oldPixelMask=NOT CS_PIX3_BACKGROUND else #newPixel=CsColourPix2Table(colour) #oldPixelMask=NOT CS_PIX2_BACKGROUND end if else if xx(0) AND 1 then #newPixel=CsColourPix1Table(colour) #oldPixelMask=NOT CS_PIX1_BACKGROUND else #newPixel=CsColourPix0Table(colour) #oldPixelMask=NOT CS_PIX0_BACKGROUND end if end if ' Compute an index into BACKTAB from the coordinates. where=SCREENPOS(xx(0)/2,yy(0)/2) ' Get the card from BACKTAB and mask out anything we don't need. #what=#BACKTAB(where) AND #oldPixelMask ' Update BACKTAB with the new pixel colour (and coloured squares mode enabled). #BACKTAB(where)=#what OR #newPixel end ' Colour table for pixel 0. CsColourPix0Table: data CS_COLOUR_SQUARES_ENABLE+CS_PIX0_BLACK data CS_COLOUR_SQUARES_ENABLE+CS_PIX0_BLUE data CS_COLOUR_SQUARES_ENABLE+CS_PIX0_RED data CS_COLOUR_SQUARES_ENABLE+CS_PIX0_TAN data CS_COLOUR_SQUARES_ENABLE+CS_PIX0_DARKGREEN data CS_COLOUR_SQUARES_ENABLE+CS_PIX0_GREEN data CS_COLOUR_SQUARES_ENABLE+CS_PIX0_YELLOW ' Colour table for pixel 1. CsColourPix1Table: data CS_COLOUR_SQUARES_ENABLE+CS_PIX1_BLACK data CS_COLOUR_SQUARES_ENABLE+CS_PIX1_BLUE data CS_COLOUR_SQUARES_ENABLE+CS_PIX1_RED data CS_COLOUR_SQUARES_ENABLE+CS_PIX1_TAN data CS_COLOUR_SQUARES_ENABLE+CS_PIX1_DARKGREEN data CS_COLOUR_SQUARES_ENABLE+CS_PIX1_GREEN data CS_COLOUR_SQUARES_ENABLE+CS_PIX1_YELLOW ' Colour table for pixel 2. CsColourPix2Table: data CS_COLOUR_SQUARES_ENABLE+CS_PIX2_BLACK data CS_COLOUR_SQUARES_ENABLE+CS_PIX2_BLUE data CS_COLOUR_SQUARES_ENABLE+CS_PIX2_RED data CS_COLOUR_SQUARES_ENABLE+CS_PIX2_TAN data CS_COLOUR_SQUARES_ENABLE+CS_PIX2_DARKGREEN data CS_COLOUR_SQUARES_ENABLE+CS_PIX2_GREEN data CS_COLOUR_SQUARES_ENABLE+CS_PIX2_YELLOW ' Colour table for pixel 3. CsColourPix3Table: data CS_COLOUR_SQUARES_ENABLE+CS_PIX3_BLACK data CS_COLOUR_SQUARES_ENABLE+CS_PIX3_BLUE data CS_COLOUR_SQUARES_ENABLE+CS_PIX3_RED data CS_COLOUR_SQUARES_ENABLE+CS_PIX3_TAN data CS_COLOUR_SQUARES_ENABLE+CS_PIX3_DARKGREEN data CS_COLOUR_SQUARES_ENABLE+CS_PIX3_GREEN data CS_COLOUR_SQUARES_ENABLE+CS_PIX3_YELLOW REM ------------------------------------------------------------------------- REM CsPlot - END REM ------------------------------------------------------------------------- REM ;; Display format word layout in Colored Squares Mode: ;; REM ;; ;; REM ;; 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ;; REM ;; +----+----+----+----+----+----+----+----+----+----+----+----+----+----+ ;; REM ;; |Pix3| 1 | 0 | Pix. 3 | Pix. 2 color | Pix. 1 color | Pix. 0 color | ;; REM ;; |Bit2| | | bit 0-1 | (0-7) | (0-7) | (0-7) | ;; REM ;; +----+----+----+----+----+----+----+----+----+----+----+----+----+----+ ;; REM ;; ;; REM ;; Pixels are display like so: +-----+-----+ ;; REM ;; |Pixel|Pixel| ;; REM ;; | 0 | 1 | ;; REM ;; +-----+-----+ ;; REM ;; |Pixel|Pixel| ;; REM ;; | 2 | 3 | ;; REM ;; +-----+-----+ ;; REM ------------------------------------------------------------------------- REM CsReadPixel - Read a pixel in coloured squares mode. REM ------------------------------------------------------------------------- REM REM Input: REM xx(0) - X coordinate (in the range 0 to 39). REM yy(0) - Y coordinate (in the range 0 to 23). REM REM Output: REM pixelValue - a value from 0 to 7 REM REM Trashes: REM where, #what,pixelnum REM REM ------------------------------------------------------------------------- CsReadPixel: procedure ' Compute an index into BACKTAB from the coordinates. where=SCREENPOS(xx(0)/2,yy(0)/2) ' Get the card from BACKTAB #what=#BACKTAB(where) ' which pixel do we want pixelnum = ((yy(0) *2) AND 2) + (xx(0) AND 1) on pixelnum goto csr_1, csr_2,csr_3,csr_4 csr_1: pixelValue = #what AND 7 : return csr_2: pixelValue = (#what/8) AND 7 : return csr_3: pixelValue = (#what/64) AND 7 : return csr_4: #what = #what/ 256 pixelValue = ((#what/2) AND 3) + ((#what/8) AND 4) end REM ------------------------------------------------------------------------- REM CsReadPixel - END REM ------------------------------------------------------------------------- REM ------------------------------------------------------------------------- REM SaveDir - Save the direction to move to get to the next pixel REM ------------------------------------------------------------------------- REM REM Input: REM #head_i = index to the head of the snake direction data REM in the snake array REM REM Output: REM changes data in snake array REM advances #head_i REM REM Trashes: REM where, curval, pos REM REM ------------------------------------------------------------------------- SaveDir: procedure where = #head_i/4 curval = snake(where) subpos = #head_i AND 3 curval = curval and dirClearMask(subpos) curval = curval + (dirtable(dir) AND dirSetMask(subpos)) snake(where) = curval #head_i = #head_i + 1 if #head_i > maxIndex then #head_i = 0 end dirClearMask: data $3f,$cf,$F3,$fc dirSetMask: data $C0,$30,$0c,$03 dirtable: data $00,$55,$aa,$ff REM ------------------------------------------------------------------------- REM saveDir - END REM ------------------------------------------------------------------------- REM ------------------------------------------------------ REM ------------------------------------------------------------------------- REM UpdateTail - Save the direction to move to get to the next pixel REM ------------------------------------------------------------------------- REM REM Input: REM #tail_i = index to the tail of the snake direction data REM tx,ty = tail position REM in the snake array REM REM Output: REM updates tx,ty REM advances #tail_i REM REM Trashes: REM where, curval, subpos REM REM ------------------------------------------------------------------------- UpdateTail: procedure where = #tail_i/4 curval = snake(where) subpos = #tail_i AND 3 on subpos goto ut_1,ut_2,ut_3,ut_4 ut_1: curval = curval/64 : goto ut_4 ut_2: curval = curval/16 : goto ut_4 ut_3: curval = curval/4 : goto ut_4 ut_4: uti = curval AND 3 tx = tx + xinc(uti) ty = ty + yinc(uti) #tail_i = #tail_i + 1 if #tail_i > maxIndex then #tail_i = 0 end REM ------------------------------------------------------------------------- REM saveDir - END REM ------------------------------------------------------------------------- REM ------------------------------------------------------ rem put face rem put a face on the snakes head putFace: procedure sprite 0, (sx * 4) + 6 + HIT + VISIBLE, (sy * 4) + 6 + ZOOMY2 + faceflags(dir) ,SPR_LIGHTBLUE + GRAM + ((1 -(dir AND 1)) * 8) end faceflags: data 0, 0, FLIPX + FLIPY, FLIPX game_tiles: rem char 0 rem smile right BITMAP " " BITMAP " ##### " BITMAP " # # " BITMAP " # # # " BITMAP " # # " BITMAP " # # " BITMAP " ##### " BITMAP " " rem char 1 rem smile up BITMAP " " BITMAP " #### " BITMAP " # # " BITMAP " # # # " BITMAP " # # " BITMAP " # # " BITMAP " ###### " BITMAP " " rem char 2 rem F BITMAP "#### " BITMAP "# " BITMAP "### " BITMAP "# " BITMAP "# " BITMAP " " BITMAP " " BITMAP " "