home *** CD-ROM | disk | FTP | other *** search
- PROC Nibbles:
- rem
- rem Original game design and program by Microsoft
- rem Ported to psion by Luke Gilbert
- rem Comments/Complaints welcome!
- rem email: lgilbert@prairienet.com
- rem
- rem Obligatory Disclaimer: Use this program at
- rem your own risk. I am not responsible for any
- rem damage or loss caused by this program.
- rem
- global speed% rem speed
- global diff$(1) rem difficulty
- global snd$(1) rem sound effects
- global gspeed$(1) rem GameSpeed
- global CurLvl%
- global SstrRow%
-
- global ColrTbl%(10)
-
- global realRow%(2040) REM Maps the 80x50 point into the real 80x25
- global acolor%(2040) REM Stores the current color of the point
- global sister%(2040) REM Each char has 2 points in it. .SISTER is
- REM -1 if sister point is above, +1 if below
-
-
- Rem CONSTANTS
- global TRUE%
- global FALSE%
- global MAXLEN% rem max snake length
- global STRTOVR% REM Parameters to 'Level' SUB
- global SAMELVL%
- global NEXTLVL%
-
- TRUE% = -1
- FALSE% = NOT TRUE%
- MAXLEN% = 1000
- STRTOVR% = 1 REM Parameters to 'Level' SUB
- SAMELVL% = 2
- NEXTLVL% = 3
-
- RANDOMIZE SECOND
- DO
- AT 15, 16
- PRINT "Sound effects (Y or N)";
- snd$ = Upper$(get$)
- UNTIL snd$ = "Y" OR snd$ = "N"
- Intro:
- GetInp:
- SetColr:
- DrawScr:
- InitClr:
-
- DO
- Play:(diff$)
- UNTIL NOT PlayAgn:
-
- CLS
- ENDP
-
- PROC Intro:
- REM Displays game introduction
-
- CLS
- center:( 4, "Q B a s i c N i b b l e s")
- center:( 6, "Copyright (C) Microsoft Corporation 1990")
- center:( 8, "Nibbles is a game for one player. Navigate your snake")
- center:( 9, "around the screen trying to eat up numbers while avoiding")
- center:( 10, "running into walls. The more numbers you eat up,")
- center:( 11, "the more points you gain and the longer your snake grows.")
- center:( 14, "Press any key to continue")
- if snd$="Y"
- beep 5, 600
- beep 5, 650
- beep 5, 700
- beep 5, 750
- beep 5, 800
- beep 5, 750
- beep 5, 700
- beep 5, 650
- beep 5, 600
- endif
- SprkPse:
-
- CLS
- center:( 5, " GAME CONTROLS ")
- center:( 7, " (Up) ")
- center:( 8, " P - Pause " + CHR$(24) + " ")
- center:( 9, " (Left) " + CHR$(27) + " " + CHR$(26) + " (Right)")
- center:( 10, " " + CHR$(25) + " ")
- center:( 11, " (Down) ")
- center:( 14, "Press any key to continue")
- SprkPse:
- ENDP
-
- PROC GetInp:
- REM Gets player inputs
- local StrtTim%, StopTim%
- local i%
- CLS
-
- AT 22,9 : PRINT "1 = Novice"
- AT 22,10 : PRINT "8 = Expert"
- AT 22,11 : PRINT "9 = Twiddle Fingers"
- AT 15,12 : PRINT "(Computer speed may affect your skill level)"
- DO
- AT 22,8 : PRINT "Skill level (1 to 9)";
- gspeed$=GET$
- UNTIL ASC(gspeed$) > ASC("0") AND ASC(gspeed$) <= ASC("9")
- speed% = VAL(gspeed$)
-
- speed% = 10 - speed%
-
- DO
- AT 15, 14
- PRINT "Increase game speed during play (Y or N)";
- diff$=get$
- diff$ = Upper$(diff$)
- UNTIL diff$ = "Y" OR diff$ = "N"
-
- ENDP
-
- PROC SetColr:
- ColrTbl%(1)=7 rem snake
- ColrTbl%(3)=7 rem walls
- ColrTbl%(4)=0 rem bkgrd
- ENDP
-
- PROC DrawScr:
- REM Draws playing field
- local r%, c%
- local rr%, ss%
- local rowcol%
-
- REM initialize screen
- CLS
-
- REM Print title & message
- center:( 1, "Nibbles!")
- center:( 11, "Initializing Playing Field...")
-
- REM Initialize arena array
- r%=0
- do
- r%=r%+1
- rr% = INT((r% + 1) / 2)
- ss% = mod:(r%, 2) * 2 - 1
- c%=0
- do
- c%=c%+1
- rowcol%=r%*60+c%-60
- realRow%(rowcol%) = rr%
- sister%(rowcol%) = ss%
- until c%=60
- until r%=34
- ENDP
-
- PROC Play:(diff$) REM Main routine that controls game play
- local rowcol%
- local k%
- local i%
- global tail%
-
- rem TYPE snakeBody
- global bodyrow%(1000)
- global bodycol%(1000)
-
- rem TYPE snaketype
- global head%
- global length%
- global row%
- global col%
- global dir%
- global lives%
- global score%
- global scolor%
- global alive%
-
- global CurSpd%
- global GameOvr%
- global Numbr%
- global nonum%
- global Died%
- global NumRow%
- global NumCol%
-
- REM Initialize Snake
- lives% = 5
- score% = 0
- scolor% = ColrTbl%(1)
-
- Level:(STRTOVR%, ColrTbl%(3))
-
- CurSpd% = speed%
-
- REM play Nibbles until finished
- SpcPse:( "Level " + NUM$(CurLvl%,2) + ". Push Space.")
-
- GameOvr% = FALSE%
- DO
- Numbr% = 1 REM Current number that snake is trying to run into
- NoNum% = TRUE% REM nonum = TRUE if a number is not on the screen
-
- Died% = FALSE%
- PrtScor: (score%, lives%)
- if snd$="Y"
- beep 5, 650
- pause 7
- beep 5, 600
- beep 20, 570
- endif
- DO REM Print number if no number exists
- IF NoNum% = TRUE%
- DO
- NumRow% = INT(RND * 29 + 3)
- NumCol% = INT(RND * 58 + 2)
- rowcol%=NumRow%*60+NumCol%-60
- SstrRow% = NumRow% + Sister%(Rowcol%)
- UNTIL NOT PtsTher:(NumRow%, NumCol%, ColrTbl%(4)) AND NOT PtsTher:(SstrRow%, NumCol%, ColrTbl%(4))
- NumRow% = RealRow%(Rowcol%)
- NoNum% = FALSE%
-
- AT NumCol%, NumRow%
- PRINT NUM$(Numbr%, 2);
- ENDIF
-
- REM Delay game
- i%=0
- do
- i%=i%+1
- until i%=CurSpd%*CurSpd%*CurSpd%
-
- REM Get keyboard input & Change direction accordingly
- k%=key
- if k%
- if k%=256 and dir%<>2
- dir%=1 rem up
- elseif k%=257 and dir%<>1
- dir%=2 rem down
- elseif k%=258 and dir%<>3
- dir%=4 rem right
- elseif k%=259 and dir%<>4
- dir%=3 rem left
- elseif k%=%p
- SpcPse:( "Paused. Push Space.")
- elseif k%=%x and kmod=8
- stop
- endif
- endif
-
- if dir%=1
- row% = row% - 1
- elseif dir%=2
- row% = row% + 1
- elseif dir%=3
- col% = col% - 1
- elseif dir%=4
- col% = col% + 1
- endif
-
- REM If snake hits number, respond accordingly
- IF NumRow% = INT((row% + 1) / 2) AND NumCol% = col%
- if snd$="Y"
- beep 4, 550
- beep 4, 450
- endif
- IF length% < (MAXLEN% - 30)
- rem Need a challenge? Try: length% = length% + Numbr% * 7
- length% = length% + Numbr% * 5
- ENDIF
- score% = Score% + Numbr%
- PrtScor: (score%, lives%)
- Numbr% = Numbr% + 1
- IF Numbr% = 10
- AT NumCol%, NumRow%
- PRINT " "
- Erase:
- Level:( SAMELVL%, ColrTbl%(4))
- Level:( NEXTLVL%, ColrTbl%(3))
- PrtScor: (score%, lives%)
- SpcPse: ("Level " + num$(CurLvl%,2) + ". Push Space.")
- Numbr% = 1
- IF diff$ = "Y"
- speed%=speed%-1
- IF speed% < 1
- Speed% = 1
- ENDIF
- CurSpd% = speed%
- ENDIF
- ENDIF
- NoNum% = TRUE%
- ENDIF
-
- REM If player runs into any point, or the head of the other snake, it dies.
- IF PtsTher:(row%, col%, ColrTbl%(4))
- if snd$="Y"
- beep 10,700
- beep 10, 850
- beep 10, 1100
- endif
- AT NumCol%, NumRow%
- PRINT " "
- Died% = TRUE%
- alive% = FALSE%
- lives% = lives% - 1
- ELSE REM Otherwise, move the snake, and erase the tail
- Head% = MOD:(Head% + 1, MAXLEN%)
- BodyRow%(Head%) = row%
- BodyCol%(Head%) = col%
- tail% = MOD:(Head% + MAXLEN% - length%, MAXLEN%)+1
- Set:(BodyRow%(tail%), BodyCol%(tail%), ColrTbl%(4))
- BodyRow%(tail%) = 0
- Set:(row%, col%, scolor%)
- ENDIF
- UNTIL Died%
-
- CurSpd% = speed% REM reset speed to initial value
-
- REM If dead, then erase snake in really cool way
- Erase:
-
- IF alive% = FALSE%
- REM Update score
- Score% = Score% - 10
- PrtScor: (score%, lives%)
- SpcPse: ("Died! Push Space.")
- ENDIF
-
- Level:( SAMELVL%, ColrTbl%(3))
- PrtScor: (score%, lives%)
-
- UNTIL lives% = 0 REM Play next round until lives have run out.
- Level:( SAMELVL%, ColrTbl%(4))
- ENDP
-
- PROC InitClr:
- REM Initializes playing field colors
- local row%
- local col%
-
- row%=0
- do
- row%=row%+1
- col%=0
- do
- col%=col%+1
- acolor%(row%*60+col%-60) = ColrTbl%(4)
- until col%=60
- until row%=34
-
- CLS
-
- col%=0
- do
- col%=col%+1
- Set:( 3, col%, ColrTbl%(3))
- Set:( 34, col%, ColrTbl%(3))
- until col%=60
-
-
- row%=3
- do
- row%=row%+1
- Set:( row%, 1, ColrTbl%(3))
- Set:( row%, 60, ColrTbl%(3))
- until row%=34
- ENDP
-
- PROC Level: (DoThis%, Colr%)
- REM Sets game level
- local i%
-
- if DoThis%=STRTOVR%
- CurLvl% = 1
- elseif DoThis%=NEXTLVL%
- CurLvl% = CurLvl% + 1
- endif
-
- REM Initialize Snake
- head% = 1
- length% = 3
- alive% = TRUE%
-
- VECTOR CurLvL%
- case1, case2, case3, case4, case5, case6, case7, case8, case9
- ENDV
-
- REM If CurrentLevel > 9 then do this
- i%=2
- do
- i%=i%+2
- Set:( i%, 10, Colr%)
- Set:( i% + 1, 20, Colr%)
- Set:( i%, 30, Colr%)
- Set:( i% + 1, 40, Colr%)
- Set:( i%, 50, Colr%)
- until i%=32
- row% = 7
- col% = 58
- dir% = 2
- RETURN
-
- CASE1::
- row% = 25
- col% = 50
- dir% = 3
- RETURN
-
- CASE2::
- i%=9
- do
- i%=i%+1
- set:(19, i%, Colr%)
- until i%=50
- row% = 7
- col% = 50
- dir% = 3
- RETURN
-
- CASE3::
- i%=7
- do
- i%=i%+1
- set:(i%, 15, Colr%)
- set:(i%, 45, Colr%)
- until i%=29
- row% = 25
- col% = 50
- dir% = 1
- RETURN
-
- CASE4::
- i%=3
- do
- i%=i%+1
- set:(i%, 20, Colr%)
- set:(37-i%, 40, Colr%)
- until i%=20
- i%=1
- do
- i%=i%+1
- set:(25, i%, Colr%)
- set:(12, 61-i%, Colr%)
- until i%=36
- row% = 7
- col% = 55
- dir% = 3
- RETURN
-
- CASE5::
- i%=13
- do
- i%=i%+1
- set:(i%, 19, Colr%)
- set:(i%, 47, Colr%)
- until i%=23
- i%=20
- do
- i%=i%+1
- set:(12, i%, Colr%)
- set:(25, i%, Colr%)
- until i%=45
- row% = 25
- col% = 50
- dir% = 1
- RETURN
-
- CASE6::
- i% = 3
- do
- i%=i%+1
- IF i% > 21 OR i% < 17
- Set: (i%, 10, Colr%)
- Set: (i%, 20, Colr%)
- Set: (i%, 30, Colr%)
- Set: (i%, 40, Colr%)
- Set: (i%, 50, Colr%)
- ENDIF
- until i%=33
- row% = 7
- col% = 55
- dir% = 2
- RETURN
-
- CASE7::
- i%=3
- do
- i%=i%+2
- Set:( i%, 30, Colr%)
- until i%=33
- row% = 7
- col% = 55
- dir% = 2
- RETURN
-
- CASE8::
- i%=3
- do
- i%=i%+1
- Set:( i%, 10, Colr%)
- Set:( 37 - i%, 20, Colr%)
- Set:( i%, 30, Colr%)
- Set:( 37 - i%, 40, Colr%)
- Set:( i%, 50, Colr%)
- until i%=28
- row% = 7
- col% = 55
- dir% = 2
- RETURN
-
- CASE9::
- i%=5
- do
- i%=i%+1
- Set:( i%, i%, Colr%)
- Set:( i%, i% + 24, Colr%)
- until i%=31
- row% = 32
- col% = 58
- dir% = 1
- RETURN
-
- ENDP
-
- PROC PrtScor: (score1%, lives1%)
- REM Prints scores and number of lives remaining
- AT 10,1
- PRINT "SAMMY--> Lives:"+num$(lives1%,3)+" "+num$(score1%,7)
- ENDP
-
- PROC Erase: REM Erases snake after its died
- local c%, b%
- c%=0
- do
- b%=length%-c%
- do
- tail% = ((Head%+MAXLEN%-b%)-(Head%+MAXLEN%-b%)/MAXLEN%*MAXLEN%)+1
- Set:(BodyRow%(tail%), BodyCol%(tail%), ColrTbl%(4))
- b%=b%-10
- until b%<=0
- c%=c%+1
- until c%=10
- ENDP
-
- PROC PlayAgn:
- REM Determines if users want to play game again.
- local k$(2)
-
- center:( 10, "█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█")
- center:( 11, "█ G A M E O V E R █")
- center:( 12, "█ █")
- center:( 13, "█ Play Again? (Y/N) █")
- center:( 14, "█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█")
-
- DO
- k$ = UPPER$(KEY$)
- UNTIL k$ = "Y" OR k$ = "N"
-
- center:( 10, " ")
- center:( 11, " ")
- center:( 12, " ")
- center:( 13, " ")
- center:( 14, " ")
-
- IF k$ = "Y"
- RETURN TRUE%
- ELSE
- RETURN FALSE%
- CLS
- ENDIF
-
- ENDP
-
- PROC SprkPse:
- REM Creates flashing border for intro screen
- local a$(90)
- local k%
- local i%, j%, c%
-
- a$ = "* * * * * * * * * * * * * * * * * "
- do
- i%=1
- REM print horizontal sparkles
- do
- AT 1, 1 :PRINT MID$(a$, i%, 60);
- AT 1,17 :PRINT MID$(a$, 5 - i%, 60);
- j%=2
- REM Print Vertical sparkles
- do
- k%=key
- c% = mod:(i% + j%, 4)
- IF c% = 1
- AT 60,j%
- PRINT "*";
- AT 1, 17 - j%
- PRINT "*";
- ELSE
- AT 60,j%
- PRINT " ";
- AT 1, 17 - j%
- PRINT " ";
- ENDIF
- j%=j%+1
- until j%=17 or k%
- i%=i%+1
- until i%=5 or k%
- until k%
- ENDP
-
- PROC Center: (row%, text$)
- REM Centers text on given row
- IF LEN(text$) >60
- giprint "Line skipped"
- get
- ELSE
- AT 31 - int(LEN(text$) / 2.0), row%
- PRINT text$;
- ENDIF
- ENDP
-
- PROC SpcPse:(text$)
- REM Pauses game play and waits for space bar to be pressed before continuing
- local k$(1)
-
- busy left$(text$,19),1
- do
- k$=key$
- until k$=" "
- busy off
- ENDP
-
- PROC PtsTher: (r%, c%, color%)
- REM Checks the global arena array to see if the boolean flag is set
- IF r% <> 0
- IF acolor%(r%*60+c%-60) <> color%
- RETURN TRUE%
- ELSE
- RETURN FALSE%
- ENDIF
- ENDIF
- ENDP
-
- PROC Set: (r%, c%, color%)
- REM Sets row and column on playing field to given color to facilitate moving
- REM of snake around the field.
- local rowcol%
- local TopFlag%
- local SstrClr%
- local rrow%
-
- IF r% <> 0
- rowcol%=r%*60+c%-60
- acolor%(rowcol%) = color% REM assign color to arena
- RRow% = RealRow%(rowcol%) REM Get real row of pixel
- TopFlag% = sister%(rowcol%) + 1 REM Deduce whether pixel
- REM is on top▀, or bottom▄
- SstrRow% = r% + sister%(rowcol%) REM Get row of sister point
- SstrClr% =acolor%(SstrRow%*60+c%-60) REM Determine sister's color
-
- AT c%, Rrow%
-
- IF color% = SstrClr% REM If both points are same
- if color% > 6
- PRINT CHR$(219);
- else
- PRINT " ";
- endif
- ELSE
- IF TopFlag%
- IF color% > 6
- PRINT CHR$(223);
- ELSE
- PRINT CHR$(220);
- ENDIF
- ELSE
- IF color% > 6
- PRINT CHR$(220);
- ELSE
- PRINT CHR$(223);
- ENDIF
- ENDIF
- ENDIF
- ENDIF
- ENDP
-
- PROC Mod:(x%, y%)
- return x% - x% / y% * y%
- ENDP
-
-
-