' ' Q B a s i c N i b b l e s ' ' Copyright (C) Microsoft Corporation 1990 ' ' Nibbles is a game for one or two players. Navigate your snakes ' around the game board trying to eat up numbers while avoiding ' running into walls or other snakes. The more numbers you eat up, ' the more points you gain and the longer your snake becomes. ' ' To run this game, press Shift+F5. ' ' To exit QBasic, press Alt, F, X. ' ' To get help on a BASIC keyword, move the cursor to the keyword and press ' F1 or click the right mouse button. ' 'Set default data type to integer for faster game play DEFINT A-Z 'User-defined TYPEs TYPE snakeBody row AS INTEGER col AS INTEGER END TYPE 'This type defines the player's snake TYPE snaketype head AS INTEGER length AS INTEGER row AS INTEGER col AS INTEGER direction AS INTEGER lives AS INTEGER score AS INTEGER scolor AS INTEGER alive AS INTEGER END TYPE 'This type is used to represent the playing screen in memory 'It is used to simulate graphics in text mode, and has some interesting, 'and slightly advanced methods to increasing the speed of operation. 'Instead of the normal 80x25 text graphics using chr$(219) "", we will be 'using chr$(220)"" and chr$(223) "" and chr$(219) "" to mimic an 80x50 'pixel screen. 'Check out sub-programs SET and POINTISTHERE to see how this is implemented 'feel free to copy these (as well as arenaType and the DIM ARENA stmt and the 'initialization code in the DrawScreen subprogram) and use them in your own 'programs TYPE arenaType realRow AS INTEGER 'Maps the 80x50 point into the real 80x25 acolor AS INTEGER 'Stores the current color of the point sister AS INTEGER 'Each char has 2 points in it. .SISTER is END TYPE '-1 if sister point is above, +1 if below 'Sub Declarations DECLARE SUB SpacePause (text$) DECL CASE "w", "W": IF sammy(2).direction <> 2 THEN sammy(2).direction = 1 CASE "s", "S": IF sammy(2).direction <> 1 THEN sammy(2).direction = 2 CASE "a", "A": IF sammy(2).direction <> 4 THEN sammy(2).direction = 3 CASE "d", "D": IF sammy(2).direction <> 3 THEN sammy(2).direction = 4 CASE CHR$(0) + "H": IF sammy(1).direction <> 2 THEN sammy(1).direction = 1 CASE CHR$(0) + "P": IF sammy(1).direction <> 1 THEN sammy(1).direction = 2 CASE CHR$(0) + "K": IF sammy(1).direction <> 4 THEN sammy(1).direction = 3 CASE CHR$(0) + "M": IF sammy(1).direction <> 3 THEN sammy(1).direction = 4 CASE "p", "P": SpacePause " Game Paused ... Push Space " CASE ELSE END SELECT FOR a = 1 TO NumPlayers 'Move Snake SELECT CASE sammy(a).direction CASE 1: sammy(a).row = sammy(a).row - 1 CASE 2: sammy(a).row = sammy(a).row + 1 CASE 3: sammy(a).col = sammy(a).col - 1 CASE 4: sammy(a).col = sammy(a).col + 1 END SELECT 'If snake hits number, respond accordingly IF numberRow = INT((sammy(a).row + 1) / 2) AND NumberCol = sammy(a).col THEN PLAY "MBO0L16>CCCE" IF sammy(a).length < (MAXSNAKELENGTH - 30) THEN sammy(a).length = sammy(a).length + number * 4 END IF sammy(a).score = sammy(a).score + number PrintScore NumPlayers, sammy(1).score, sammy(2).score, sammy(1).lives, sammy(2).lives number = number + 1 IF number = 10 THEN EraseSnake sammy(), sammyBody(), 1 EraseSnake sammy(), sammyBody(), 2 LOCATE numberRow, NumberCol: PRINT " " Level NEXTLEVEL, sammy() PrintScore NumPlayers, sammy(1).score, sammy(2).score, sammy(1).lives, sammy(2).lives SpacePause " Level" + STR$(curLevel) + ", Push Space" IF NumPlayers = 1 THEN sammy(2).row = 0 number = 1 IF diff$ = "P" THEN speed = speed - 10: curSpeed = speed END IF nonum = TRUE IF curSpeed < 1 THEN curSpeed = 1 END IF NEXT a FOR a = 1 TO NumPlayers 'If player runs into any point, or the head of the other snake, it dies. IF PointIsThere(sammy(a).row, sammy(a).col, colorTable(4)) OR (sammy(1).row = sammy(2).row AND sammy(1).col = sammy(2).col) THEN PLAY "MBO0L32EFGEFDC" COLOR , colorTable(4) LOCATE numberRow, NumberCol PRINT " " playerDied = TRUE sammy(a).alive = FALSE sammy(a).lives = sammy(a).lives - 1 'Otherwise, move the snake, and erase the tail ELSE sammy(a).head = (sammy(a).head + 1) MOD MAXSNAKELENGTH sammyBody(sammy(a).head, a).row = sammy(a).row sammyBody(sammy(a).head, a).col = sammy(a).col tail = (sammy(a).head + MAXSNAKELENGTH - sammy(a).length) MOD MAXSNAKELENGTH Set sammyBody(tail, a).row, sammyBody(tail, a).col, colorTable(4) sammyBody(tail, a).row = 0 Set sammy(a).row, sammy(a).col, sammy(a).scolor END IF NEXT a LOOP UNTIL playerDied curSpeed = speed ' reset speed to initial value FOR a = 1 TO NumPlayers EraseSnake sammy(), sammyBody(), a 'If dead, then erase snake in really cool way IF sammy(a).alive = FALSE THEN 'Update score sammy(a).score = sammy(a).score - 10 PrintScore NumPlayers, sammy(1).score, sammy(2).score, sammy(1).lives, sammy(2).lives IF a = 1 THEN SpacePause " Sammy Dies! Push Space! --->" ELSE SpacePause " <---- Jake Dies! Push Space " END IF END IF NEXT a Level SAMELEVEL, sammy() PrintScore NumPlayers, sammy(1).score, sammy(2).score, sammy(1).lives, sammy(2).lives 'Play next round, until either of snake's lives have run out. LOOP UNTIL sammy(1).lives = 0 OR sammy(2).lives = 0 END SUB 'PointIsThere: ' Checks the global arena array to see if the boolean flag is set FUNCTION PointIsThere (row, col, acolor) IF row <> 0 THEN IF arena(row, col).acolor <> acolor THEN PointIsThere = TRUE ELSE PointIsThere = FALSE END IF END IF END FUNCTION 'PrintScore: ' Prints players scores and number of lives remaining SUB PrintScore (NumPlayers, score1, score2, lives1, lives2) COLOR 15, colorTable(4) IF NumPlayers = 2 THEN LOCATE 1, 1 PRINT USING "#,###,#00 Lives: # <--JAKE"; score2; lives2 END IF LOCATE 1, 49 PRINT USING "SAMMY--> Lives: # #,###,#00"; lives1; score1 END SUB 'Set: ' Sets row and column on playing field to given color to facilitate moving ' of snakes around the field. SUB Set (row, col, acolor) IF row <> 0 THEN arena(row, col).acolor = acolor 'assign color to arena realRow = arena(row, col).realRow 'Get real row of pixel topFlag = arena(row, col).sister + 1 / 2 'Deduce whether pixel 'is on top, or bottom sisterRow = row + arena(row, col).sister 'Get arena row of sister sisterColor = arena(sisterRow, col).acolor 'Determine sister's color LOCATE realRow, col IF acolor = sisterColor THEN 'If both points are same COLOR acolor, acolor 'Print chr$(219) "" PRINT CHR$(219); ELSE IF topFlag THEN 'Since you cannot have IF acolor > 7 THEN 'bright backgrounds COLOR acolor, sisterColor 'determine best combo PRINT CHR$(223); 'to use. ELSE COLOR sisterColor, acolor PRINT CHR$(220); END IF ELSE IF acolor > 7 THEN COLOR acolor, sisterColor PRINT CHR$(220); ELSE COLOR sisterColor, acolor PRINT CHR$(223); END IF END IF END IF END IF END SUB 'SpacePause: ' Pauses game play and waits for space bar to be pressed before continuing SUB SpacePause (text$) COLOR colorTable(5), colorTable(6) Center 11, "" Center 12, " " + LEFT$(text$ + SPACE$(29), 29) + " " Center 13, "" WHILE INKEY$ <> "": WEND WHILE INKEY$ <> " ": WEND COLOR 15, colorTable(4) FOR i = 21 TO 26 ' Restore the screen background FOR j = 24 TO 56 Set i, j, arena(i, j).acolor NEXT j NEXT i END SUB 'SparklePause: ' Creates flashing border for intro screen SUB SparklePause COLOR 4, 0 a$ = "* * * * * * * * * * * * * * * * * " WHILE INKEY$ <> "": WEND 'Clear keyboard buffer WHILE INKEY$ = "" FOR a = 1 TO 5 LOCATE 1, 1 'print horizontal sparkles PRINT MID$(a$, a, 80); LOCATE 22, 1 PRINT MID$(a$, 6 - a, 80); FOR b = 2 TO 21 'Print Vertical sparkles c = (a + b) MOD 5 IF c = 1 THEN LOCATE b, 80 PRINT "*"; LOCATE 23 - b, 1 PRINT "*"; ELSE LOCATE b, 80 PRINT " "; LOCATE 23 - b, 1 PRINT " "; END IF NEXT b NEXT a WEND END SUB 'StillWantsToPlay: ' Determines if users want to play game again. FUNCTION StillWantsToPlay COLOR colorTable(5), colorTable(6) Center 10, "" Center 11, " G A M E O V E R " Center 12, " " Center 13, " Play Again? (Y/N) " Center 14, "" WHILE INKEY$ <> "": WEND DO kbd$ = UCASE$(INKEY$) LOOP UNTIL kbd$ = "Y" OR kbd$ = "N" COLOR 15, colorTable(4) Center 10, " " Center 11, " " Center 12, " " Center 13, " " Center 14, " " IF kbd$ = "Y" THEN StillWantsToPlay = TRUE ELSE StillWantsToPlay = FALSE COLOR 7, 0 CLS END IF END FUNCTION uEYS[Y부>EuquEJAJ1@uEJAJ2(uEJAJ3EJAJ4EWFEtElEPNEES.h[S"^[S\T[S[J[S]@[S+6[jTb=tE( +sE>EtE8\<\O\3ۊEEGEWEO& _Ëq&ÃWSE6EE߉EE[_E26E=t+KKQKQKQKQIu)AAAAAE