Kids code with SHAPES (a gallery)

SHAPES is a programming interpreter for #coding colourful images.   SHAPES allows children to think about programming commands, coordinates and geometric shapes.  The following images were all coded by year 7 children.  In the interest of sanity and brevity, I will only provide the code for some of the images.

Apologies if you are viewing on Tumblr (you won't see any images).
Cute Pig
@@pig 
{
    [ ]
    fill green
    moveto (310, 65)
    colour hotpink
    border-thickness 8 
    border-colour black
    rectangle 75, 225
    moveto (1060, 75)
    colour hotpink
    border-thickness 8
    border-colour black
    rectangle 75, 225
    moveto (430, 112)
    colour hotpink
    border-thickness 8
    border-colour black
    rectangle 60, 120
    moveto (956, 112)
    colour hotpink
    border-thickness 8
    border-colour black
    rectangle 60, 120
    moveto (720, 576)
    colour hotpink
    border-thickness 15
    circle 500, 500
    moveto (718, 500)
    ellipse 200, 300
    moveto (724, 320)
    ellipse 350, 250
    moveto (654, 645)
    colour white
    border-thickness 4 
    ellipse 50, 100
    moveto (768, 646)
    colour white 
    border-thickness 4 
    ellipse 50, 100
    moveto (766, 644)
    colour black
    ellipse 25, 50
    moveto (656, 640)
    colour black
    ellipse 25, 50
    colour black
    moveto (714, 1064)
    line-thickness 3
    drawto (686, 1090)
    drawto (720, 1104)
    drawto (660, 1118)
    drawto (744, 1146)
    drawto (658, 1148)
    moveto (604, 314)
    colour pink
    circle medium
    moveto (840, 316)
    colour pink
    circle medium
    moveto (644, 776)
    colour hotpink
    border-thickness 15
    border-colour black
    triangleto (548, 854) (580, 708)
    moveto (778, 780)
    colour hotpink
    border-thickness 15
    border-colour black
    triangleto (884, 838) (844, 724)
    moveto (32, 1118)
    colour white
    print  A PIG!  BY GEORGIA P
}

An angry bird
@@angry bird
{
    [ ]
    fill blue
    moveto (800,950)
    colour red
    ellipse angle 50,150,150
    moveto (720,950)
    colour red
    ellipse 50,150
    moveto (640,950)
    colour red
    ellipse angle 50,150,40
    moveto (720,576)
    colour red
    circle huge
    moveto (720,370)
    colour white
    ellipse 310,194
    colour orange
    moveto (540,525)
    triangleto (715,430) (900,525)
    colour orange
    moveto (540,525)
    triangleto (715,630) (900,525)
    colour white
    moveby (25,200)
    circle medium
    colour white
    moveby (300,0)
    circle medium
    colour black
    circle tiny
    colour black
    moveby (-300,0)
    circle tiny
    colour 128,0,0
    moveto (1020,575)
    ellipse 50,70
    colour 128,0,0
    moveto (430,575)
    ellipse 50,70
    moveto (460,800)
    colour black
    rectangle 190,60
    moveto (770,800)
    colour black
    rectangle 190,60
    moveto (380,150)
    colour white
    border-colour black
    print Angry Bird for Competition By Ryan
}


A Smurfette

Festive

Pig

On the road again (this is a good example of an animated shapes project as the traffic lights change colour...)

Sunset from the beach

Say "CHEESE!"

Beautiful Giraffe

Queen Elizabeth II.  (Do let me know what you think of the portrait, if you are reading this, Your Majesty.)

Cute

Look at those eyes!

How I look in the morning

City scape

Got the time

Football mad

Spongebob

Very cute

Binary counter-upper

Binary counter-upper

A simple binary counter-upper.   Counts from 0 to over 4 billion in denary and binary.


BBC BASIC for Windows source code follows.

     REM binary counter-upper
     REM T Street
     REM 2015-02-23

     
MODE 12
     *font courier new, 20b
     OFF

     
REM main loop
     
FOR n% = 0 TO 256^4
       PRINTTAB(0,4)CHR$(17)CHR$(7)STR$(n%)" : " ,FN_hiliteBits(FN_toBinary(n%))
       WAIT 20
     NEXT

     END



     
DEF FN_hiliteBits( s$ )
     REM colours the string of bits
     REM with 1 and 0 having different colours
     
LOCAL zeroCol%   : zeroCol%   = 3
     LOCAL digitCol%  : digitCol%  = 6
     _CHAR_FOR_COLOUR% = 17
     LOCAL i%
     LOCAL a$, b$, col$
     FOR i% = 1 TO LEN(s$)
       b$ = MID$(s$,i%,1)
       CASE b$ OF
         WHEN 
"1"
           col$ = CHR$(_CHAR_FOR_COLOUR%)+CHR$(digitCol%)
         WHEN "0"
           col$ = CHR$(_CHAR_FOR_COLOUR%)+CHR$(zeroCol%)
         WHEN " "
           col$ =""
       ENDCASE
       
a$ = a$ + col$+b$
     NEXT
     
= a$



     DEF FN_toBinary( n% )
     REM converts a number to binary string
     
LOCAL a$ : REM answer
     
LOCAL b$ : REM copy of the answer
     
LOCAL b% : REM copy of parameter
     
LOCAL i% :
     b% = n% : REM defensive copying
     
a$ = FN_binary(b%)
     WHILE LEN(a$) MOD 8 <> 0
       a$ = "0"+a$
     ENDWHILE
     
b$ = a$
     IF LEN(b$) > 8 THEN
       
b$ = ""
       FOR i% = 1 TO LEN(a$)
         IF i%-1 MOD 8 <> 0 THEN
           
b$ = b$ + MID$(a$,i%,1)
         ELSE
           
b$ = b$ + " " + MID$(a$,i%,1)
         ENDIF
       NEXT
     ENDIF
     
= b$


     REM Convert to binary string:
     
DEF FN_binary(N%) = FN_tobase(N%,2,-32*(N%<0))
     :
     REM Convert N% to string in base B% with minimum M% digits:
     
DEF FN_tobase(N%,B%,M%)
     LOCAL D%,A$
     REPEAT
       
D% = N%MODB%
       N% DIV= B%
       IF D%<0 D% += B%:N% -= 1
       A$ = CHR$(48 + D% - 7*(D%>9)) + A$
       M% -= 1
     UNTIL (N%=FALSE OR N%=TRUEAND M%<=0
     =A$

CodeCombat

I've just discovered CodeCombat - a programming game that so far has impressed me greatly.

Each puzzle is solved by typing a script.
Code combat features puzzle-solving and combat, all completed by typing a script for your character to follow.  It has all the recognisable elements of any good rogue-like game, including powering-up your character with items.  New items provide access to new methods for your scripts, for example the sword provides access to the attack() method.

The basics of programming constructions are all here: sequence, selection, repetition, passing parameters etc.

The following code snippet will fend off waves of ogres:

    loop:
        enemy = self.findNearestEnemy()
        self.attack( enemy )


Needless to say, the findNearestEnemy() method can only be invoked once your hero has found a certain pair of magical spectacles.

The sound effects add to the experience, as well as helping to debug your code.  "But it's already dead", my hero says as my code attempts to kill a monster with cartoon violence again.

Each new programming element is introduced gradually, often with sample code partially written to help you out.  In this image I have just acquired a hammer that unlocks the buildXY() method allowing me to build fences.  That will keep those ogres from squashing me.

The start of a new puzzle.
The simple interface, problem-solving elements and cartoon graphics should appeal to boys and girls alike.  A perfect introduction to algorithms and coding for schools.  You don't need to create an account to play either.

Programming games are nothing new, though.  Here is my attempt at a similar idea from a few years ago - PoopScoop.

#codeCombat
#codinginschools

Assembly language hacked by 14-year-olds

The following two programs are very impressive examples of independent work produced by two 14-year-old boys using my Little Man Computer simulator.

The first one by Eric is an integer division program that can deal with both negative and positive integers and which returns both the whole number division and the remainder.  The second program, written by Will, is a general purpose calculator that can deal with addition, subtraction, multiplication, integer division, square roots and raising one number to power.

Not bad stuff for a program that can only ADD and SUBTRACT(!)

Eric's division program first.  Enter two numbers X and Y respectively and the program calculates X DIV Y and X MOD Y.


#DIVISION with remainders and negatives!

#By Eric
.
INP
STA TOP #Input the top part of the fraction, e.g. [8]/3
BRZ TOPZERO #If top zero simulate input and then
#output 0
INP
BRZ HALT #If zero, just go. DIVBYZERO
STA BOTTOM #Input the bottom part of the
#fraction, e.g. 8/[3]
BRA NCHKO
.
TOPZERO INP #sim input
LDA SWAP #load swap (0 by now)
OUT #outputs it
HLT #and stops!
.
NCHKO BRP NCHKT #check bottom for efficiency
SUB BOTTOM #use clever maths to realize that x-(x-x) = -x
SUB BOTTOM #if the numbers weren't positive it would
STA BOTTOM #mess the program up
LDA MINUSONE #negmult is now -1, so it's negative
STA NEGMULT
BRA NCHKT
.
NCHKT LDA TOP #check top now
BRP START #if not negative just go to setup
SUB TOP #same clever maths as before
SUB TOP
STA TOP
LDA NEGMULT #loads the negative multiplier
SUB NEGMULT
SUB NEGMULT
STA NEGMULT
#and uses SAME clever maths trick to invert, again
LDA TOP
BRA START
.
.
.
START SUB BOTTOM
#alright so I better explain
#the thing is that the way I divide is:
#I count how many times I subtract the bottom from the top
#When the top is negative it checks for a remainder
#by adding the bottom on again
#that is the remainder
#so example:
#14/3 - it subtracts 3 from 14 5 times
#and then adds 3 again, takes one away from the
#5 times (makes it 4) and the remainder is the result after
#adding 3. 4r2 which is the correct answer.
BRP NFINISH #if positive NotFINISHed
BRA FINISHUP#else finish all things up
NFINISH STA SWAP #stores current result in swap
LDA RESULT #loads the result
ADD ONE #increments
STA RESULT #stores result
LDA SWAP
BRA START #loads swap and removes and starts again
.
.
.
FINISHUP ADD BOTTOM #adds bottom to figure out remainder
STA REMAINDER #stores that as remainder
LDA NEGMULT #remember this?
BRP OUTPUT #if negmult is normal just output
LDA RESULT
SUB RESULT #else use my favourite maths trick
SUB RESULT
STA RESULT
OUTPUT LDA RESULT #easy peasy
OUT #output result
LDA REMAINDER
OUT #remainder
HALT HLT #cya 

#Variables
NEGMULT DAT 1 #Negative multiplier
MINUSONE DAT -1 #-1 [CONST]
ONE DAT 1 #1 [CONST]
TOP DAT 0 #The top part of fraction
BOTTOM DAT 0 #Botttom part
RESULT DAT 0 #Result
REMAI DAT 0 #Remainder
SWAP DAT 0

#Swap data used by program for general stuff




Here is Will's general purpose calculator.  The first number input is the menu option:
0: for square root
2: for division
3: for subtraction
4: for addition
5: for powers
6: for multiplication


#Will
#A general purpose calculator which works with the limitations of the little man computer
#
INP # Press zero for square root, two for divide, three for subtract, four for addition and five for power, six for multiply
STA D
INP #Enter the first number, this is the number that all the functions will be done to
STA A
INP #With square and power, due to limitations of little man computer size, does nothing but is the operating number
STA B
LDA D
BRZ SQUARE #Go to square function
SUB ONE
BRZ DIVIDE #Go to multiply function
SUB ONE
BRZ SUBTRACT #Go to subract function
SUB TWO
BRZ ADDITION #Go to addition function
SUB ONE
BRZ POWER #Go to Power

LDA B #Multiply Function
SUB ONE
STA B
LOOP LDA C
ADD A
STA C
LDA B
SUB ONE
STA B
BRP LOOP
LDA C
OUT
HLT

DIVIDE LDA A #Divide function
STA A
LOOPD LDA COUNT
ADD ONE
STA COUNT
LDA A
SUB B
STA A
BRZ ZERO
BRP LOOPD
ZERO LDA COUNT
OUT
HLT


ADDITION LDA A #Addition Function
ADD B
OUT
HLT

SUBTRACT LDA A #Subtract Function
SUB B
OUT
HLT



SQUARE LDA A #Square root function
STA A
LOOPS LDA COUNT
ADD ONE
STA COUNT
LDA A
SUB X
STA A
LDA X
ADD TWO
STA X
LDA A
BRP LOOPS
LDA COUNT
SUB ONE
OUT
HLT

POWER LDA A #Power function
STA COUNT
LDA COUNT
SUB ONE
STA COUNT
LOOPP LDA COUNT
SUB ONE
STA COUNT
LDA RESULT
ADD A
STA RESULT
LDA COUNT
BRP LOOPP
LDA RESULT
OUT
HLT


A DAT
B DAT
C DAT 000
COUNT DAT
X DAT 001
ONE DAT 001
TWO DAT 002
RESULT DAT


Linear search demo

This program demonstrates the linear search algorithm in BB4W.

The first job is to count the number of records in the input file.  Once we know this, we can set up an array of records to hold the data.  Once we have this array dimensioned we can read the data in from the file.

Once the array is populated with data, we ask the user to enter a search term.  The algorithm searches through the array linearly until the index to the required record is either found or the end of the array is reached.  We can then do useful things with this index number, for example: to display the distance from the sun.

The input file.

The output of the program.


     REM demonstrates
     REM (a) setting up a record structure
     REM (b) reading from a file
     REM (c) performing a linear search

     
INSTALL @lib$+"stringlib" : REM used by FN_removeCRLF()

     
file$ = @dir$+"planetsInput.txt"

     NumRecords% = FN_countRecordsInFile( file$  )


     REM now we know how many records there are
     REM we can set up a record structure
     
DIM Planet{(NumRecords%-1) name$, distance }

     PROC_readDataIn( file$, Planet{()}, NumRecords% )

     REM main loop
     
REPEAT
       INPUT 
"Enter planet name : " myplanet$
       index% = FN_search( Planet{()}, NumRecords%, myplanet$ )
       IF index%<>-999 THEN
         PRINT 
"Planet "Planet{(index%)}.name$
         PRINT "Distance from sun : " STR$( Planet{(index%)}.distance/1000 )" thousand km"
         PRINT "---------------------------------------------------"''
       ELSE
         PRINT 
"No record found"''
       ENDIF
     UNTIL FALSE


     STOP


     
DEFFN_countRecordsInFile( filepath$ )
     REM opens a file for reading and counts the number of records in the file
     
LOCAL file%
     LOCAL mycount%
     LOCAL dummy$
     file% = OPENIN( filepath$ )
     WHILE (NOT(EOF#file%))
       REM I know that each record has two fields
       
INPUT#file%, dummy$, dummy$
       mycount% += 1 : REM count one record
     
ENDWHILE
     
REM REMEMBER to close the file once we are done
     
CLOSE#file%
     = mycount%



     DEFPROC_readDataIn( filepath$, this{()}, n%)
     REM reads data from the file into a the data structure
     
LOCAL i%
     LOCAL file%
     LOCAL name$, distance$
     file% = OPENIN( filepath$ )
     FOR i% = 0 TO n% -1
       INPUT#file%, name$, distance$
       REM remove the Carriage returns/Linefeeds
       REM and store in the structure
       
this{(i%)}.name$ = FN_removeCRLF(name$)
       this{(i%)}.distance = VALFN_removeCRLF(distance$))
     NEXT
     
REM REMEMBER to close the file once we are done
     
CLOSE#file%
     ENDPROC



     
DEFFN_search( this{()}, n%, key$ )
     REM performs a linear search for the key in the
     REM array of records
     
LOCAL found%
     LOCAL i%
     LOCAL a%  : a% = -999 : REM assume record wont be found
     
WHILE NOT(found%) AND i% < n%
       REM is the current record the one with matching key?
       
IF this{(i%)}.name$ = key$ THEN
         
REM yes, then found it!
         
found% = TRUE
         
a% = i% : REM return the index for the found record
       
ELSE
         
REM no
         
i% += 1 : REM look for the next one
       
ENDIF
     ENDWHILE
     
= a%



     DEFFN_removeCRLF(t$)
     REM returns the text passed with carriage returns and line feeds removed
     
LOCAL dummy%
     dummy% = FN_findreplace(t$,CHR$(13),"",0)
     dummy% = FN_findreplace(t$,CHR$(10),"",0)
     = t$



#linearSearch
#algorithms
#computing

ASCII Bombman hacked by children

I asked a group of 10 to 12-year-old boys to download some source code and hack it. This is what they came up with.

You (the 'A') must run away from the Snakes ('S') and Kobolds ('k'), and collect the pink stars ('*').

ASCII Bombman is a simple ASCII-based maze game I wrote in 2012. Pretty soon all the boys were editing the levels. I've compiled some of them into a single file and presented them here.  Some of them changed the story line, as well, and even changed the sprites and other parameters.

I am becoming more convinced that the way to introduce programming to children is to give them pre-written code and ask the to 'hack it'.  Sure, they make a lot of mistakes along the way, very often breaking the code - but no matter - it is a learning experience to just fix it!


Download the Windows executable and source code. (works with BBC BASIC for Windows).

Here, a chain-reaction has started.
Download the Windows executable and source code.

#programmingforkids
#learningtocode

Here is the source code if you don't want to download.

     REM Bomb Man
     REM version 1
     REM by T Street
     REM 7/6/2012
     
_VERSION$ = "2.0a"
     MODE 10  : OFF
     MOUSE OFF
     
*escape off
     REMon error cls:error 0, "Ooops!  An error occurred : "+report$
     REM setup the colours
     
COLOUR 1, 200,190,180 : REM white
     
COLOUR 2, 60,60,60    : REM grey
     
COLOUR 3, 30,200,60   : REM green
     
COLOUR 4, 200,80,40   : REM red
     
COLOUR 5, 200,10,200 : REM Kobold
     
COLOUR 6, 00,100,200 : REM ghost
     
COLOUR 7, 200, 0 ,0  : REM dynamite
     
COLOUR 8, 200,200,0 : REM yellow
     
COLOUR 9, 0,200,180 : REM cyan

     REM data about the game
     REM the total number of levels
     REM make sure you change this number if you add new levels!
     
LEVELS% = 13
     REM -------------------------------------------------------
     
ROOM_DEPTH% = 17 : REM number of lines on each level
     
ROOM_WIDTH% = 30 : REM the width of the level in number of characters
     
MAX_MONSTERS% = 20 : REM the maximum snakes that can be on a level
     
MAX_KOBOLDS% = 10 : REM the maximum kobolds that can be on a level
     
MAX_GHOSTS% = 3   : REM the maximum ghosts that can be on each level
     REM -------------------------------------------------------
     REM scores values
     
KOBOLD_SCORE% = 5
     SNAKE_SCORE% = 3
     RUBBLE_SCORE% = 1
     GOLD_SCORE% = 2
     REM size of 'items'
     
AMMO_SIZE% = 6
     HEALTH_SIZE% = 5
     ARMOUR_SIZE% = 10
     REM sprites used
     
AMMO$ = "!"
     ARMOUR$ = "@"
     HEALTH$ = "+"
     GOLD$ = "*"
     BLANK$ = " "
     REM the number of BOMBS the game can handle
     REM 'dynamite' and 'bombs' are used synonymously throughout this program!
     
MAX_BOMBS% = 6
     REM messages
     
PAUSED_MESSAGE$ = "PAUSED"
     REM a template holds all the level information
     
DIM template{ name$( LEVELS% ),            \ list of names
     
\ map$( LEVELS%, ROOM_DEPTH% ),         \ list of maps
     
\ text$( LEVELS%),                      \
     
\ startx%(LEVELS%), starty%(LEVELS%),    \ start positions
     
\ noMonsters%( LEVELS% ),                \ number of monsters
     
\ monsterx%(LEVELS%, MAX_MONSTERS%),                \
     
\ monstery%(LEVELS%, MAX_MONSTERS%),                \
     
\ noKobolds%( LEVELS%),                  \ number of kobolds
     
\ koboldx%( LEVELS%, MAX_KOBOLDS%),      \
     
\ koboldy%( LEVELS%, MAX_KOBOLDS%),      \
     
\ noGhosts%( LEVELS%),                   \ number of ghosts
     
\ ghostx%( LEVELS%, MAX_KOBOLDS%),      \
     
\ ghosty%( LEVELS%, MAX_KOBOLDS%)      \
     
\ }

     REM a level is a copy of the template used at runtime
     
DIM level{} = template{}

     REM a player is the dude that runs around the screen
     
DIM player{ x%, y%, \
     
\ health%, armour%, score%,  \
     
\ sprite$,               \  character used for character
     
\ dynamite%,             \  number of sticks of dynamite
     
\ dynamiteTimer%(MAX_BOMBS%-1),        \  number of ticks left on dynamite clock
     
\ dynamiteLevel%(MAX_BOMBS%-1),        \  the current level for this stick of dynamite
     
\ dynamitex%(MAX_BOMBS%-1), dynamitey%(MAX_BOMBS%-1) \
     
\}

     REM read data in
     
PROC_readMapData( template{} )
     PROC_copyLevelData( template{}, level{} )

     REM set up the initial conditions
     
player.score% = 0
     level% = 1 :  REM player's starting level
     
player.dynamite% = 0
     player.health% = 30
     player.armour% = 0
     player.sprite$ = "A"

     paused% = FALSE
     
currentStick% = 0
     REM main loop
     
REPEAT
       PROC
_title
       PROC_menu
       PROC_nextLevelScreen( level% )
       REPEAT
         
player.x% = level.startx%( level% )
         player.y% = level.starty%( level% )
         :
         REM each 'turn'
         
REPEAT
           
gold% = FN_howManyGold( level{}, level%)
           :
           PROC_displayMap( level{}, level% )
           PROC_displayStats( player{} )
           PROC_displayPlayer( player{} )
           PROC_transformWalls( level{}, level% )
           PROC_displayDynamite( level{}, player{}, level%)
           PROC_moveMonsters( level{}, level%)
           PROC_displayMonsters( level{}, level% )
           PROC_moveKobolds( level{}, player{}, level% )
           PROC_displayKobolds( level{}, level% )
           PROC_moveGhosts( level{},player{}, level% )
           PROC_displayGhosts( level{}, level% )
           PROC_checkMonstersHit( level{}, player{}, level% )
           PROC_checkKoboldsHit( level{}, player{}, level% )
           PROC_checkGhostsHit( level{}, player{}, level% )
           PROC_checkForItems( level{}, player{}, level%, player.x%, player.y% )
           REM reduce timer on dynamite
           
PROC_dynamiteTimer( level{}, player{}, level% )
           :
           TIME = 0
           REM get user input
           
g% = INKEY(10)
           WAIT (10-TIME)
           REPEAT UNTIL INKEY(0) =-1
           REM process user input
           
CASE g% OF
             WHEN 
136 : REM left
               
IF FN_canMove(level{}, level%, player.x%,player.y%, 3) THEN
                 
player.x% -=1
               ENDIF

             WHEN 
137 : REM right
               
IF FN_canMove(level{}, level%, player.x%,player.y%, 1) THEN
                 
player.x% += 1
               ENDIF

             WHEN 
138 : REM down
               
IF FN_canMove(level{}, level%, player.x%,player.y%, 2) THEN
                 
player.y% += 1
               ENDIF

             WHEN 
139 : REM up
               
IF FN_canMove(level{}, level%, player.x%,player.y%, 0) THEN
                 
player.y% -= 1
               ENDIF

             WHEN 
32  : REM space

               
IF player.dynamite% AND NOTplayer.dynamiteTimer%(currentStick%) AND player.dynamiteLevel%(currentStick%)<> level% THEN
                 
player.dynamiteTimer%(currentStick%) = 12
                 player.dynamiteLevel%(currentStick%) = level%
                 player.dynamitex%(currentStick%) = player.x%
                 player.dynamitey%(currentStick%) = player.y%
                 player.dynamite% -= 1
                 currentStick% +=1
                 IF currentStick% >= MAX_BOMBS% THEN
                   
currentStick% = 0
                 ENDIF
               ENDIF

             WHEN 
112,80  : REM pause 'p'
               
IF NOTpaused% THEN
                 
paused% = TRUE
                 COLOUR 
3
                 PRINTTAB(16,9)PAUSED_MESSAGE$
               ENDIF

             WHEN 
115,83 : REM suicide
               
PROC_animateExplosion(level{}, level%, player.x%, player.y% )
               PROC_animateExplosion(level{}, level%, player.x%, player.y% )
               PROC_animateExplosion(level{}, level%, player.x%, player.y% )
               RUN

           ENDCASE

           
REM pause?
           
WHILE paused%
             g$ = GET$
             IF 
g$ = "P" OR g$ ="p" THEN
               
paused% = FALSE
             ENDIF
           ENDWHILE

         UNTIL 
gold% = 0 OR player.health% <=0 OR level%>LEVELS%


         REM check for end of level
         
IF gold%<=0 THEN
           
level%+=1

           REM check for end of game
           
IF level% > LEVELS% THEN
             CLS
:PRINT''"      That's all folks!"
             WAIT 300
             RUN

           ENDIF

           
REM cancel the last stick of dynamite
           
FOR n% = 0 TO MAX_BOMBS%-1
             IF player.dynamiteTimer%(n%) THEN
               
player.dynamiteTimer%(n%) = 0
               player.dynamiteLevel%(n%) = 0
               player.dynamitex%(n%) = -1
               player.dynamitey%(n%) = -1
               currentStick% = 0
             ENDIF
           NEXT

           PROC
_nextLevelScreen(level%)
         ENDIF

         
REM check for player death
         
IF player.health% <= 0 THEN
           CLS
:PRINT''"       GAME OVER!"
           WAIT 300
           RUN
         ENDIF

       UNTIL FALSE
     UNTIL FALSE


     END




     
REM --------------------------------------------------------------


     
DEFPROC_checkForItems( level{}, player{}, level%, x%, y% )
     REM looks for items at the location passed in x%, y%
     REM eg items that the player can pick up
     REM and updates the score accordingly
     
IF MID$( level.map$(level%, y%),x%,1) = GOLD$ THEN
       MID$( 
level.map$(level%, y%),x%,1) = BLANK$
       PROC_sound(1,-15,1200,4)
       player.score% += GOLD_SCORE%
     ENDIF
     
REM look for armour
     
IF MID$( level.map$(level%, y%),x%,1) = ARMOUR$ THEN
       MID$( 
level.map$(level%, y%),x%,1) = BLANK$
       PROC_sound(1,-15,300,4)
       player.armour% += ARMOUR_SIZE%
     ENDIF
     
REM look for AMMO BOX
     
IF MID$( level.map$(level%, y%),x%,1) = AMMO$ THEN
       MID$( 
level.map$(level%, y%),x%,1) = BLANK$
       PROC_sound(1,-15,300,2)
       player.dynamite% += AMMO_SIZE%
     ENDIF
     
REM look for health pack
     
IF MID$( level.map$(level%, y%),x%,1) = HEALTH$ THEN
       MID$( 
level.map$(level%, y%),x%,1) = BLANK$
       PROC_sound(1,-15,600,4)
       player.health% += HEALTH_SIZE%
     ENDIF
     ENDPROC



     
DEFFN_howManyGold( level{}, level% )
     REM counts the amount of gold on a level
     
LOCAL m%, n%, c% : REM iterators and counters
     
FOR m% = 1 TO ROOM_DEPTH%
       FOR n% = 1 TO ROOM_WIDTH%
         IF MID$( level.map$(level%, m%), n%, 1) = "*" c%+=1
       NEXT
     NEXT
     
= c%


     DEFPROC_transformWalls( level{}, level% )
     REM changes the characters used for boulders based on the current time
     
LOCAL n%, m% , target$
     CASE TIME MOD OF
       WHEN  
1 target$ = "0"
       WHEN 2 target$ = "O"
       OTHERWISE target$ = "o"
     ENDCASE
     FOR 
n% = 1 TO ROOM_DEPTH%
       FOR m% = 1 TO LEN(level.map$(level%, n% ))
         IF INSTR("0Oo"MID$(level.map$(level%,n%),m%,1)) AND MID$(level.map$(level%,n%),m%,1)<>target$ THEN
           MID$(
level.map$(level%,n%),m%,1) = target$
         ENDIF
       NEXT
     NEXT
     ENDPROC



     
DEFPROC_moveMonsters( level{}, level%)
     REM move the monsters
     REM the monsters (snakes move randomly)
     
LOCAL m%, ok% , heading%
     FOR m% = 1 TO level.noMonsters%(level%)
       IF level.monsterx%(level%, m%)<>-1 AND level.monstery%(level%, m%) <> -1 AND RND(18) <3 THEN
         
ok% = FALSE
         REPEAT
           
heading% = RND(4) -1
           IF FN_canMove( level{}, level%, level.monsterx%(level%,m%), level.monstery%(level%,m%), heading%) THEN
             CASE 
heading% OF
               WHEN 
0 level.monstery%(level%,m%) -=1
               WHEN 1 level.monsterx%(level%,m%) +=1
               WHEN 2 level.monstery%(level%,m%) +=1
               WHEN 3 level.monsterx%(level%,m%) -=1
             ENDCASE
             
ok% = TRUE
           ENDIF
         UNTIL 
ok%
       ENDIF
     NEXT
     ENDPROC




     
DEFPROC_checkExplodedMonsters( level{}, player{}, level%, x%, y%)
     REM checks whether any monsters were caught in the explosions
     
LOCAL m%
     FOR m% = 1 TO level.noMonsters%(level%)
       hit% = FALSE
       IF 
level.monsterx%(level%, m% ) = x% AND level.monstery%(level%, m% ) = y% THEN
         
hit% = TRUE
       ENDIF
       IF 
level.monsterx%(level%, m% )-1 = x% AND level.monstery%(level%, m% ) = y% THEN
         
hit% = TRUE
       ENDIF
       IF 
level.monsterx%(level%, m% )+1 = x% AND level.monstery%(level%, m% ) = y% THEN
         
hit% = TRUE
       ENDIF
       IF 
level.monsterx%(level%, m% ) = x% AND level.monstery%(level%, m% )+1 = y% THEN
         
hit% = TRUE
       ENDIF
       IF 
level.monsterx%(level%, m% ) = x% AND level.monstery%(level%, m% )-1 = y% THEN
         
hit% = TRUE
       ENDIF
       IF 
hit% THEN
         
level.monsterx%(level%, m% ) = -1
         level.monstery%(level%, m% ) = -1
         player.score% += SNAKE_SCORE%
       ENDIF
     NEXT
     ENDPROC



     
DEFPROC_checkMonstersHit( level{}, player{}, level% )
     REM checks whether the monsters (snakes) have hit the player
     
LOCAL m%
     FOR m% = 1 TO level.noMonsters%(level%)
       IF level.monsterx%(level%,m%)<>-1 AND level.monstery%(level%,m%)<>-1 THEN
         IF 
level.monsterx%(level%,m%)= player.x% AND level.monstery%(level%,m%)= player.y% THEN
           PROC
_hurt(player{},1)
         ENDIF
       ENDIF
     NEXT
     ENDPROC



     
DEFPROC_checkKoboldsHit( level{}, player{}, level% )
     REM checks whether the kobolds have hit the player
     
LOCAL m%
     FOR m% = 1 TO level.noKobolds%(level%)
       IF level.koboldx%(level%,m%)<>-1 AND level.koboldy%(level%,m%)<>-1 THEN
         IF 
level.koboldx%(level%,m%)= player.x% AND level.koboldy%(level%,m%)= player.y%  THEN
           PROC
_hurt(player{},2)
         ENDIF
       ENDIF
     NEXT
     ENDPROC



     
DEFPROC_checkGhostsHit( level{}, player{}, level% )
     REM checks whether the Ghosts have hit the player
     
LOCAL m%
     FOR m% = 1 TO level.noGhosts%(level%)
       IF level.ghostx%(level%,m%)<>-1 AND level.ghosty%(level%,m%)<>-1 THEN
         IF 
level.ghostx%(level%,m%)= player.x% AND level.ghosty%(level%,m%)= player.y%  THEN
           PROC
_hurtByGhost(player{},2)
         ENDIF
       ENDIF
     NEXT
     ENDPROC


     
DEFPROC_hurtByGhost( player{}, amount% )
     REM reduces players life by an amount
     REM his damage is caused by ghosts
     REM and dynamite
     REM it cannot be prevented using armour
     
player.health% -= amount%
     PROC_sound(0, -15, 52, 2)
     ENDPROC




     
DEFPROC_hurt( player{}, amount%)
     REM deals and amount of damage to player
     REM armour is spent before health
     
LOCAL n%
     PROC_sound(0, -15, 52, 2)
     FOR n% = 1 TO amount%
       IF player.armour% THEN
         
player.armour% -=1
       ELSE
         
player.health% -=1
       ENDIF
     NEXT
     ENDPROC



     
DEFPROC_moveKobolds( level{}, player{}, level% )
     REM move the kobolds towards the player
     
LOCAL m%, ok%, heading%, n%, s%, e%, w%, tries%, same%
     FOR m% = 1 TO level.noKobolds%(level%)
       IF level.koboldx%(level%, m%) <> -1 AND level.koboldy%(level%, m%) <>-1 THEN
         
same% = FALSE
         IF 
level.koboldx%(level%, m%) = player.x% AND level.koboldy%(level%, m%) = player.y% THEN
           
same% = TRUE
         ENDIF
         IF RND
(4) = 1 AND NOTsame% THEN
           
e% = FALSE: n% = FALSE:w% = FALSE : s% = FALSE
           
REM find direction to player
           
IF level.koboldx%( level%, m%) < player.x% THEN
             
e% = TRUE
           ELSE
             
w% = TRUE
           ENDIF
           IF 
level.koboldy%( level%, m%) < player.y% THEN
             
s% = TRUE
           ELSE
             
n% = TRUE
           ENDIF
           
REM now have preferred directions to player
           
ok% = FALSE

           IF 
n% AND FN_canMove( level{}, level%, level.koboldx%( level%, m%), level.koboldy%( level%, m%), 0) THEN
             
heading% = 0
             ok% = TRUE
           ENDIF
           IF 
s% AND FN_canMove( level{}, level%, level.koboldx%( level%, m%), level.koboldy%( level%, m%), 2) THEN
             
heading% = 2
             ok% = TRUE
           ENDIF
           IF 
e% AND FN_canMove( level{}, level%, level.koboldx%( level%, m%), level.koboldy%( level%, m%), 1) THEN
             
heading% = 1
             ok% = TRUE
             IF 
n% AND FN_canMove( level{}, level%, level.koboldx%( level%, m%), level.koboldy%( level%, m%), 0) AND RND(2) = 1 THEN
               
heading% = 0
               ok% = TRUE
             ENDIF
             IF 
s% AND FN_canMove( level{}, level%, level.koboldx%( level%, m%), level.koboldy%( level%, m%), 2) AND RND(2) = 1 THEN
               
heading% = 2
               ok% = TRUE
             ENDIF

           ENDIF
           IF 
w% AND FN_canMove( level{}, level%, level.koboldx%( level%, m%), level.koboldy%( level%, m%), 3) THEN
             
heading% = 3
             ok% = TRUE
             IF 
n% AND FN_canMove( level{}, level%, level.koboldx%( level%, m%), level.koboldy%( level%, m%), 0) AND RND(2) = 1 THEN
               
heading% = 0
               ok% = TRUE
             ENDIF
             IF 
s% AND FN_canMove( level{}, level%, level.koboldx%( level%, m%), level.koboldy%( level%, m%), 2) AND RND(2) = 1 THEN
               
heading% = 2
               ok% = TRUE
             ENDIF

           ENDIF
           
REM ok to move kobold
           
IF ok% THEN
             CASE 
heading% OF
               WHEN 
0 level.koboldy%(level%,m%) -=1
               WHEN 1 level.koboldx%(level%,m%) +=1
               WHEN 2 level.koboldy%(level%,m%) +=1
               WHEN 3 level.koboldx%(level%,m%) -=1
             ENDCASE
           ELSE
             
REM move it in a random direction
             
tries% = 0
             REPEAT
               
heading% = RND(4)-1
               tries% +=1
               IF FN_canMove( level{}, level%, level.koboldx%( level%, m%), level.koboldy%( level%, m%), heading%) THEN
                 
ok% = TRUE

               ENDIF
             UNTIL 
ok% OR tries% > 8
             IF ok% THEN
               CASE 
heading% OF
                 WHEN 
0 level.koboldy%(level%,m%) -=1
                 WHEN 1 level.koboldx%(level%,m%) +=1
                 WHEN 2 level.koboldy%(level%,m%) +=1
                 WHEN 3 level.koboldx%(level%,m%) -=1
               ENDCASE
             ENDIF
           ENDIF
         ENDIF
       ENDIF
     NEXT 
m%
     ENDPROC




     
DEFPROC_checkExplodedKobolds( level{}, player{}, level%, x%, y%)
     REM checks whether kobolds have been caught in the explosions
     
LOCAL m%
     FOR m% = 1 TO level.noKobolds%(level%)
       hit% = FALSE
       IF 
level.koboldx%(level%, m% ) = x% AND level.koboldy%(level%, m% ) = y% THEN
         
hit% = TRUE
       ENDIF
       IF 
level.koboldx%(level%, m% )-1 = x% AND level.koboldy%(level%, m% ) = y% THEN
         
hit% = TRUE
       ENDIF
       IF 
level.koboldx%(level%, m% )+1 = x% AND level.koboldy%(level%, m% ) = y% THEN
         
hit% = TRUE
       ENDIF
       IF 
level.koboldx%(level%, m% ) = x% AND level.koboldy%(level%, m% )+1 = y% THEN
         
hit% = TRUE
       ENDIF
       IF 
level.koboldx%(level%, m% ) = x% AND level.koboldy%(level%, m% )-1 = y% THEN
         
hit% = TRUE
       ENDIF
       IF 
hit% THEN
         
level.koboldx%(level%, m% ) = -1
         level.koboldy%(level%, m% ) = -1
         player.score% += KOBOLD_SCORE%
       ENDIF
     NEXT
     ENDPROC





     
DEFPROC_checkExplodedSelf( level{}, player{}, level%, x%, y%)
     REM checks whether the player has been caught in an explosion

     
LOCAL hit%
     REM look at all the spaces caught by the explosion
     
IF player.x% = x% AND player.y% = y% THEN
       
hit% = TRUE
     ENDIF
     IF 
player.x%-1 = x% AND player.y% = y% THEN
       
hit% = TRUE
     ENDIF
     IF 
player.x%+1 = x% AND player.y% = y% THEN
       
hit% = TRUE
     ENDIF
     IF 
player.x% = x% AND player.y%+1 = y% THEN
       
hit% = TRUE
     ENDIF
     IF 
player.x% = x% AND player.y%-1 = y% THEN
       
hit% = TRUE
     ENDIF
     
REM have you been hit?
     
IF hit% THEN
       PROC
_hurtByGhost(player{}, 10)
     ENDIF

     ENDPROC



     
DEFPROC_checkExplodedWalls( level{}, player{}, level%, x%, y%)
     REM checks whether any of the wall sections have been destroyed

     
IF INSTR("0Oo",MID$(level.map$( level%, y%-1),x%,1)) THEN
       MID$(
level.map$( level%, y%-1),x%,1) = " "
       player.score% += RUBBLE_SCORE%
     ENDIF
     IF INSTR(
"0Oo",MID$(level.map$( level%, y%+1),x%,1)) THEN
       MID$(
level.map$( level%, y%+1),x%,1) = " "
       player.score% += RUBBLE_SCORE%
     ENDIF
     IF INSTR(
"0Oo",MID$(level.map$( level%, y%),x%+1,1)) THEN
       MID$(
level.map$( level%, y%),x%+1,1) = " "
       player.score% += RUBBLE_SCORE%
     ENDIF
     IF INSTR(
"0Oo",MID$(level.map$( level%, y%),x%-1,1)) THEN
       MID$(
level.map$( level%, y%),x%-1,1) = " "
       player.score% += RUBBLE_SCORE%
     ENDIF

     ENDPROC


     
DEFPROC_checkExplodedAmmoCrates( level{}, player{}, level%, x%, y% )
     REM checks whether any ammo crates have been destroyed in the explosion
     
IF INSTR(AMMO$,MID$(level.map$( level%, y%-1),x%,1)) THEN
       PROC
_explode( level{}, player{}, level%, x%, y%-1)
     ENDIF

     IF INSTR(
AMMO$,MID$(level.map$( level%, y%+1),x%,1)) THEN
       PROC
_explode( level{}, player{}, level%, x%, y%+1)
     ENDIF

     IF INSTR(
AMMO$,MID$(level.map$( level%, y%),x%+1,1)) THEN
       PROC
_explode( level{}, player{}, level%, x%+1, y%)
     ENDIF

     IF INSTR(
AMMO$,MID$(level.map$( level%, y%),x%-1,1)) THEN
       PROC
_explode( level{}, player{}, level%, x%-1, y%)
     ENDIF

     ENDPROC




     
DEFPROC_explode( level{}, player{}, level%, x%, y%)
     REM deals with an explosion at coords x%, y%
     
MID$(level.map$( level%, y%),x%,1) = " "
     PROC_animateExplosion(level{}, level%, x%, y% )
     PROC_displayMap( level{}, level% )
     PROC_displayMonsters( level{}, level% )
     PROC_displayKobolds( level{}, level% )
     PROC_displayGhosts( level{}, level% )
     PROC_displayStats( player{} )
     PROC_checkExplodedMonsters( level{}, player{}, level%, x%, y%)
     PROC_checkExplodedKobolds( level{}, player{}, level%, x%, y%)
     PROC_checkExplodedSelf( level{}, player{}, level%, x%, y%)
     PROC_checkExplodedWalls( level{}, player{}, level%, x%, y%)
     PROC_checkExplodedAmmoCrates( level{}, player{}, level%, x%, y% )
     ENDPROC






     
DEFPROC_moveGhosts( level{}, player{}, level% )
     REM move ghosts
     REM ghosts move towards the player and can pass through all obstacles
     
LOCAL m%, ok%, heading%, n%, s%, e%, w%, tries%, same%
     FOR m% = 1 TO level.noGhosts%(level%)
       same% = FALSE
       IF 
level.ghostx%(level%, m%) = player.x% AND level.ghosty%(level%, m%) = player.y% THEN
         
same% = TRUE
       ENDIF
       IF RND
(6 )= 1 AND NOTsame% THEN
         
e% = FALSE: n% = FALSE:w% = FALSE : s% = FALSE
         
REM find direction to player
         
IF level.ghostx%( level%, m%) < player.x% THEN
           
e% = TRUE
         ELSE
           
w% = TRUE
         ENDIF
         IF 
level.ghosty%( level%, m%) < player.y% THEN
           
s% = TRUE
         ELSE
           
n% = TRUE
         ENDIF
         
REM now have preferred directions to player
         
ok% = FALSE

         IF 
n% AND FN_canGhostMove( level{}, level%, level.ghostx%( level%, m%), level.ghosty%( level%, m%), 0) THEN
           
heading% = 0
           ok% = TRUE
         ENDIF
         IF 
s% AND FN_canGhostMove( level{}, level%, level.ghostx%( level%, m%), level.ghosty%( level%, m%), 2) THEN
           
heading% = 2
           ok% = TRUE
         ENDIF
         IF 
e% AND FN_canGhostMove( level{}, level%, level.ghostx%( level%, m%), level.ghosty%( level%, m%), 1) THEN
           
heading% = 1
           ok% = TRUE
           IF 
n% AND FN_canGhostMove( level{}, level%, level.ghostx%( level%, m%), level.ghosty%( level%, m%), 0) AND RND(2) = 1 THEN
             
heading% = 0
             ok% = TRUE
           ENDIF
           IF 
s% AND FN_canGhostMove( level{}, level%, level.ghostx%( level%, m%), level.ghosty%( level%, m%), 2) AND RND(2) = 1 THEN
             
heading% = 2
             ok% = TRUE
           ENDIF

         ENDIF
         IF 
w% AND FN_canGhostMove( level{}, level%, level.ghostx%( level%, m%), level.ghosty%( level%, m%), 3) THEN
           
heading% = 3
           ok% = TRUE
           IF 
n% AND FN_canGhostMove( level{}, level%, level.ghostx%( level%, m%), level.ghosty%( level%, m%), 0) AND RND(2) = 1 THEN
             
heading% = 0
             ok% = TRUE
           ENDIF
           IF 
s% AND FN_canGhostMove( level{}, level%, level.ghostx%( level%, m%), level.ghosty%( level%, m%), 2) AND RND(2) = 1 THEN
             
heading% = 2
             ok% = TRUE
           ENDIF

         ENDIF
         
REM ok to move ghost
         
IF ok% THEN
           CASE 
heading% OF
             WHEN 
0 level.ghosty%(level%,m%) -=1
             WHEN 1 level.ghostx%(level%,m%) +=1
             WHEN 2 level.ghosty%(level%,m%) +=1
             WHEN 3 level.ghostx%(level%,m%) -=1
           ENDCASE
         ELSE
           
REM move it in a random direction
           
tries% = 0
           REPEAT
             
heading% = RND(4)-1
             tries% +=1
             IF FN_canGhostMove( level{}, level%, level.ghostx%( level%, m%), level.ghosty%( level%, m%), heading%) THEN
               
ok% = TRUE

             ENDIF
           UNTIL 
ok% OR tries% > 8
           IF ok% THEN
             CASE 
heading% OF
               WHEN 
0 level.ghosty%(level%,m%) -=1
               WHEN 1 level.ghostx%(level%,m%) +=1
               WHEN 2 level.ghosty%(level%,m%) +=1
               WHEN 3 level.ghostx%(level%,m%) -=1
             ENDCASE

           ENDIF
         ENDIF
       ENDIF

     NEXT 
m%
     ENDPROC






     
DEFFN_canMove( level{}, level%, x%, y%, direction% )
     REM can the player move in the direction indicated
     REM 0 north, 1 east, 2 south, 3 west
     REM look for walls
     
LOCAL xp%, yp%
     LOCAL row$
     CASE direction% OF
       WHEN 
0
         yp% = -1
       WHEN 1
         xp% = 1
       WHEN 2
         yp% = 1
       WHEN 3
         xp% = -1
     ENDCASE
     
REM check boundary conditions
     
IF y%+yp% <=0 THEN
       
=FALSE
     ENDIF
     IF 
y%+yp% > ROOM_DEPTH% THEN
       
=FALSE
     ENDIF
     IF 
x%+xp% <=0 THEN
       
=FALSE
     ENDIF
     IF 
x%+xp% > ROOM_WIDTH% THEN
       
=FALSE
     ENDIF
     
REM look for impasible walls
     
row$ = level.map$( level%, y%+yp% )
     IF INSTR("X0Oo",MID$( row$, x% + xp%, 1 )) THEN
       
FALSE
     ENDIF

     
TRUE






     
DEFFN_canGhostMove( level{}, level%, x%, y%, direction% )
     REM can the player move in the direction indicated
     REM 0 north, 1 east, 2 south, 3 west
     REM look for walls
     
LOCAL xp%, yp%
     LOCAL row$
     CASE direction% OF
       WHEN 
0
         yp% = -1
       WHEN 1
         xp% = 1
       WHEN 2
         yp% = 1
       WHEN 3
         xp% = -1
     ENDCASE
     
REM check boundary conditions
     
IF y%+yp% <=0 THEN
       
=FALSE
     ENDIF
     IF 
y%+yp% > ROOM_DEPTH% THEN
       
=FALSE
     ENDIF
     IF 
x%+xp% <=0 THEN
       
=FALSE
     ENDIF
     IF 
x%+xp% > ROOM_WIDTH% THEN
       
=FALSE
     ENDIF
     
TRUE


     
DEFPROC_title
     REM title screen
     
LOCAL g
     CLS
     COLOUR 
1
     *font Courier new, 50bu
     COLOUR 8
     PRINTTAB(5,1)"Bomb Man"
     *font Courier new, 20
     COLOUR 1
     PRINTTAB(16)"version "_VERSION$
     COLOUR 3
     PRINTTAB(13)"Superdecade games"
     COLOUR 1
     PRINTTAB(15)"7th June 2012"
     WAIT 50
     *font Courier new, 14
     PRINT''
     ENDPROC


     
DEFPROC_menu
     REM displays and runs a menu
     
LOCAL g$
     PRINTTAB(18)"Press 'i' for instructions, or"
     PRINTTAB(17)"any other key to start the game!"
     g$ = GET$
     IF 
g$ = "i" OR g$ = "I" THEN
       PROC
_instructions
     ENDIF
     ENDPROC



     
DEFPROC_instructions
     LOCAL g
     CLS
     COLOUR 
1
     *font Courier new, 50bu
     COLOUR 8
     PRINTTAB(4,1)"Bomb Man"
     *font Courier new, 14
     COLOUR 1
     PRINT
     PRINTTAB(
18)"Press arrow keys to move"
     PRINTTAB(16)"Press <space> to drop bomb"
     PRINTTAB(18)"Press <p> to pause game"
     PRINTTAB(19)"Press <s> for suicide"
     PRINT
     COLOUR 
2:PRINTTAB(2)"X",;:COLOUR1:PRINT"Impassable wall";
     COLOUR 2:PRINTTAB(40)"O",;:COLOUR1:PRINT"Rubble"
     COLOUR 7:PRINTTAB(2)"i",;:COLOUR1:PRINT"Dynamite";
     COLOUR 3:PRINTTAB(40)player.sprite$,;:COLOUR1:PRINT"You"
     COLOUR 8:PRINTTAB(2)GOLD$,;:COLOUR1:PRINT"Gold";
     COLOUR 7:PRINTTAB(40)HEALTH$,;:COLOUR1:PRINT"First-aid kit"
     COLOUR 9:PRINTTAB(2)ARMOUR$,;:COLOUR1:PRINT"Armour";
     COLOUR 9:PRINTTAB(40)AMMO$,;:COLOUR1:PRINT"Ammo crate";
     PRINT '
     COLOUR 4:PRINTTAB(2)"S",;:COLOUR1:PRINT"Snake - avoid or blow them up with dynamite!"
     COLOUR 5:PRINTTAB(2)"k",;:COLOUR1:PRINT"Kobold - run away, or blow them up with dynamite!"
     COLOUR 6:PRINTTAB(2)"W",;:COLOUR1:PRINT"Ghost - can pass through walls and armour;"
     PRINTTAB(18)"indestructible."
     g = GET
     WAIT 
20
     ENDPROC



     
DEFPROC_nextLevelScreen( level% )
     REM displays a screen telling the player about the next screen
     
LOCAL g
     CLS
     COLOUR 
4
     *font Courier new, 50b
     PRINTTAB(4,1) "Level "STR$(level%)
     PRINT
     
*font courier new, 12
     PRINT
     COLOUR 
1
     PROC_ww(level.text$(level%),72)
     REPEAT UNTIL INKEY(0) =-1
     g = GET
     WAIT 
100
     CLS
     ENDPROC




     
DEFPROC_displayMap( level{}, level% )
     REM displays the map passed as a parameter
     
LOCAL row%, n%
     *font courier new, 18
     PRINTTAB(0,0)level.name$( level% )
     FOR row% = 1 TO ROOM_DEPTH%
       PRINTTAB(3,row%+1);
       FOR n%= 1 TO LEN(level.map$( level%, row% ))
         COLOUR 2 : REM default
         REM colour gold
         
IF MID$(level.map$( level%, row% ), n%, 1) = "*" THEN
           COLOUR 
8
         ENDIF
         
REM colour armour
         
IF MID$(level.map$( level%, row% ), n%, 1) = "@" THEN
           COLOUR 
9
         ENDIF
         
REM colour ammo box
         
IF MID$(level.map$( level%, row% ), n%, 1) = "!" THEN
           COLOUR 
9
         ENDIF
         
REM colour health pack
         
IF MID$(level.map$( level%, row% ), n%, 1) = "+" THEN
           COLOUR 
7
         ENDIF
         
REM display the current character in the current colour
         
PRINT MID$(level.map$( level%, row% ), n%, 1);
       NEXT
       PRINT
     NEXT
     ENDPROC




     
DEFPROC_displayStats( player{} )
     REM display the players stats on the right hand side of the screen
     
*font courier new, 18
     COLOUR 1
     PRINTTAB(34,6)"Health : ";:COLOUR3:PRINTSTR$(player.health%)"  "
     COLOUR1:PRINTTAB(34,7)"Armour : "STR$(player.armour% )"  "
     PRINTTAB(34,8)"Bombs  : "STR$(player.dynamite%)"  "
     PRINTTAB(34,10)"Score  : ";:COLOUR5:PRINTSTR$(player.score%)"  "

     ENDPROC


     
DEFPROC_displayPlayer( player{} )
     REM display the character
     
COLOUR 3
     *font courier new, 18
     PRINTTAB(2+player.x%, 1 + player.y% )player.sprite$
     ENDPROC


     
DEFPROC_displayDynamite( level{}, player{}, level% )
     REM draw the dynamite on the map
     
LOCAL n%
     FOR n% = 0 TO MAX_BOMBS%-1
       REM is the dynamite on this level?
       
IF player.dynamiteLevel%(n%) = level% THEN
         
REM is the dynamite currently ticking?
         
IF player.dynamiteTimer%(n%) THEN
           COLOUR 
7
           REM display dynamite
           
PRINTTAB(2+player.dynamitex%(n%),1+player.dynamitey%(n%))"i"
         ENDIF
       ENDIF
     NEXT
     ENDPROC




     
DEFPROC_dynamiteTimer(level{}, player{}, level% )
     REM handles the timer on the dynamite
     
LOCAL  n%
     FOR n% = 0 TO MAX_BOMBS%-1
       REM checks whether the timer is currently set
       
IF player.dynamiteTimer%(n%) THEN
         
REM it is set, so reduce it by one
         
player.dynamiteTimer%(n%) -=1
         REM is it ready to explode?
         
IF player.dynamiteTimer%(n%) = 0 THEN
           PROC
_animateExplosion(level{}, level%, player.dynamitex%(n%), player.dynamitey%(n%) )
           REM check the effects of the explosion
           
PROC_checkExplodedMonsters( level{}, player{}, level%, player.dynamitex%(n%), player.dynamitey%(n%)  )
           PROC_checkExplodedKobolds( level{}, player{}, level%, player.dynamitex%(n%), player.dynamitey%(n%)  )
           PROC_checkExplodedSelf( level{}, player{}, level%, player.dynamitex%(n%), player.dynamitey%(n%) )
           PROC_checkExplodedWalls( level{}, player{}, level%, player.dynamitex%(n%), player.dynamitey%(n%) )
           PROC_checkExplodedAmmoCrates(level{}, player{}, level%, player.dynamitex%(n%), player.dynamitey%(n%) )
           REM remove the dynamite from this level
           
player.dynamiteLevel%(n%) = 0
           player.dynamitex%(n%) = -1
           player.dynamitey%(n%) = -1
         ENDIF
       ENDIF
     NEXT
     ENDPROC





     
DEFPROC_animateExplosion(level{}, level%, x%, y% )
     REM animate an explosion
     
LOCAL m%
     PROC_sound(0, -15, 52, 4)
     FOR m% = 1 TO 400
       REM display a random coloured character on the space x% and y%
       
COLOUR RND(7):PRINT TAB(2+x%,y% +1)CHR$(RND(100)+64)
       REM display a random coloured character on the spaces (that are not 'X') to the
       REM north, east, south and west
       
IF MID$(level.map$(level%, y%),x%+1,1)<>"X" COLOUR RND(7):PRINT TAB(2+x%+1,y% +1)CHR$(RND(100)+64)
       IF MID$(level.map$(level%, y%),x%-1,1)<>"X" COLOUR RND(7):PRINT TAB(2+x%-1,y% +1)CHR$(RND(100)+64)
       IF MID$(level.map$(level%, y%+1),x%,1)<>"X" COLOUR RND(7):PRINT TAB(2+x%,y% +1+1)CHR$(RND(100)+64)
       IF MID$(level.map$(level%, y%-1),x%,1)<>"X" COLOUR RND(7):PRINT TAB(2+x%,y% +1-1)CHR$(RND(100)+64)
     NEXT
     ENDPROC


     
DEFPROC_displayMonsters( level{}, level% )
     REM displays the monsters (snakes)
     REM snakes have two states 'S' and 's'
     
LOCAL m%, monsterChar$
     CASE TIME MOD OF
       WHEN 
1 monsterChar$ = "S"
       WHEN 0 monsterChar$ = "s"
     ENDCASE
     
*font courier new, 18
     FOR m% = 1 TO level.noMonsters%(level%)
       IF level.monsterx%(level%, m% ) <>-1 AND level.monstery%(level%, m% ) <>-1 THEN
         COLOUR 
4 : PRINTTAB(2+level.monsterx%(level%,m%),1+level.monstery%(level%,m%))monsterChar$
       ENDIF
     NEXT
     ENDPROC



     
DEFPROC_displayKobolds( level{}, level% )
     REM display the kobolds for this level
     REM the kobold alternates between the 'K' and 'k' character
     
LOCAL m%, monsterChar$
     CASE TIME MOD OF
       WHEN 
1 monsterChar$ = "K"
       WHEN 0 monsterChar$ = "k"
     ENDCASE
     
*font courier new, 18
     FOR m% = 1 TO level.noKobolds%(level%)
       IF level.koboldx%(level%, m% ) <>-1 AND level.koboldy%(level%, m% ) <>-1 THEN
         COLOUR 
5 : PRINTTAB(2+level.koboldx%(level%,m%),1+level.koboldy%(level%,m%))monsterChar$
       ENDIF
     NEXT
     ENDPROC


     
DEFPROC_displayGhosts( level{}, level% )
     REM display the ghosts on this level
     
LOCAL m%, monsterChar$
     monsterChar$ = "W"
     *font courier new, 18
     FOR m% = 1 TO level.noGhosts%(level%)
       IF level.ghostx%(level%, m% ) <>-1 AND level.ghosty%(level%, m% ) <>-1 THEN
         
REM there are two ghost characters
         REM 'W' for a ghost in a corridor
         REM 'w' for a ghost passing through a wall
         
IF INSTR("oO0X",MID$( level.map$(level%, level.ghosty%(level%, m%)), level.ghostx%(level%,m%), 1)) THEN
           
monsterChar$ = "w"
         ELSE
           
monsterChars$ = "W"
         ENDIF
         
REM now print the character
         
COLOUR 6 : PRINTTAB(2+level.ghostx%(level%,m%),1+level.ghosty%(level%,m%))monsterChar$
       ENDIF

     NEXT
     ENDPROC


     
DEFPROC_copyLevelData( from{}, dest{} )
     REM copies contents of one structure into another
     REM this is so we can make changes to the maps
     REM and level data at runtime without changing the template
     
LOCAL n%,m% : REM iterators
     
FOR n% = 1 TO LEVELS%
       dest.name$(n%) = from.name$(n%)
       FOR m% = 1 TO ROOM_DEPTH%
         dest.map$(n%, m% ) = from.map$(n%, m%)
       NEXT
       
dest.text$(n%) = from.text$(n%)
       dest.startx%(n%) = from.startx%(n%)
       dest.starty%(n%) = from.starty%(n%)
       dest.noMonsters%(n%) = from.noMonsters%(n%)
       FOR m% = 1 TO MAX_MONSTERS%
         dest.monsterx%(n%, m%) = from.monsterx%(n%,m%)
         dest.monstery%(n%, m%) = from.monstery%(n%,m%)
       NEXT
       
dest.noKobolds%(n%) = from.noKobolds%(n%)
       FOR m% = 1 TO MAX_KOBOLDS%
         dest.koboldx%(n%, m%) = from.koboldx%(n%,m%)
         dest.koboldy%(n%, m%) = from.koboldy%(n%,m%)
       NEXT
       
dest.noGhosts%(n%) = from.noGhosts%(n%)
       FOR m% = 1 TO MAX_GHOSTS%
         dest.ghostx%(n%, m%) = from.ghostx%(n%,m%)
         dest.ghosty%(n%, m%) = from.ghosty%(n%,m%)
       NEXT

     NEXT
     ENDPROC



     
REM Split a string at specified delimiter:
     REM A$ is the string to be split
     REM d$ is the delimiter at which to split
     REM a$() is an array to receive the parts (created if necessary)
     REM The returned value is the number of array elements written
     
DEF FN_split(A$, d$, RETURN a$())
     LOCAL C%, I%, N%, P%, Q%, R%
     IF !^a$() N% = DIM(a$(),1)+1
     FOR P% = 0 TO 1
       I% = 0
       R% = 0
       REPEAT
         
Q% = R%
         REPEAT
           
C% = INSTR(A$, d$, Q%+1)
           Q% = INSTR(A$, """", Q%+1)
           IF Q% IF C% > Q% THEN
             
Q% = INSTR(A$, """", Q%+1)
             IF Q%=0 ERROR 100, "Mismatched quotes"
           ELSE
             
Q% = 0
           ENDIF
         UNTIL 
Q% = 0
         IF C% = 0 THEN C% = LEN(A$)+1
         IF P% a$(I%) = MID$(A$, R%+1, C%-R%-1)
         R% = C%+LEN(d$)-1
         I% += 1
       UNTIL R% >= LEN(A$)
       IF P% = 0 IF N% < I% THEN
         IF 
N% a$() = ""
         !^a$() = 0
         DIM a$(I%-1)
       ENDIF
     NEXT 
P%
     = I%
     ;
     REM Join array elements using specified delimiter:
     
DEF FN_join(a$(), d$, N%)
     LOCAL I%,A$
     FOR I% = 0 TO N%-1
       IF I%=N%-1 d$=""
       A$ += a$(I%) + d$
     NEXT
     
= A$



     DEF FN_noLeadingSpaces(nam$)
     REM returns the string passed as a parameter with leading spaces removed
     
nam$=" "+nam$
     REPEAT nam$=MID$(nam$,2)
     UNTIL LEFT$(nam$,1)<>" "
     =nam$










     DEFPROC_sound(c%,l%,p%,d%)
     ON ERROR LOCAL ENDPROC
     SOUND 
c%,l%,p%,d%
     ENDPROC




     
DEFPROC_ww( s$, w% )
     REM word-wraps a string around the given screen width
     REM parameters:
     REM   s$  - the string to word wrap
     REM   w%  - the width of the string
     
:
     LOCAL out$ : REM output string
     
LOCAL crlf$ : crlf$ = CHR$(13) + CHR$(10)
     LOCAL c% : REM line counter
     
LOCAL t$ : REM a copy of the string to play with
     
LOCAL foundSpace% : REM boolean, has a space been found on this line?
     
LOCAL  l%
     LOCAL lf% : REM linefeed position
     
LOCAL n% : REM iteration
     
LOCAL parts%
     LOCAL a$() : DIM a$(1) : REM array used to split output into lines
     
:
     t$ = s$
     :
     WHILE LEN(t$)>w%
       REM deal with carriage returns
       
WHILE INSTR(LEFT$(t$,w%),crlf$)
         REM while this width of text contain any crlf characters?
         
out$ = out$ + LEFT$(t$,INSTR(t$,crlf$))+crlf$
         t$ = RIGHT$(t$,LEN(t$)-INSTR(t$,crlf$)-1)
       ENDWHILE
       
REM
       
foundSpace% = FALSE
       
l% = w%  : REM look at the last character first
       
REPEAT
         IF MID$(
t$,l%,1)=" " THEN
           
foundSpace% = TRUE
           
out$ = out$ + LEFT$(t$,l%) + crlf$
           t$ = RIGHT$(t$,LEN(t$)-l%)
           c% += 1
         ELSE
           
l% -=1 : REM look at the next letter down
           
IF l% = 0 THEN
             
REM i didn't find a space so I am just going to write it all
             
foundSpace% = TRUE
             
out$ = out$ + LEFT$(t$,w%) + crlf$
             t$ = RIGHT$(t$,LEN(t$)-w%)
             c% += 1

           ENDIF
         ENDIF
       UNTIL 
foundSpace%
       REM
     
ENDWHILE
     
REM the last bit doesn't need word-wrapping
     
out$ = out$ + t$
     REM now print all the lines out
     
parts% = FN_split(out$, crlf$, a$())
     FOR n% = 0 TO parts% -1
       PRINTFN_noLeadingSpaces( a$(n%))
     NEXT
     
REM
     
ENDPROC



     
DEFPROC_readMapData( level{} )
     LOCAL row%, m%
     REM reads the map data into
     
FOR level% = 1 TO LEVELS%
       READ level.name$( level% )
       FOR row% = 1 TO ROOM_DEPTH%
         READ level.map$( level%, row% )
       NEXT
       READ 
level.text$( level% )
       READ level.startx%( level% )
       READ level.starty%( level% )
       READ level.noMonsters%( level% )
       FOR m% = 1 TO MAX_MONSTERS%
         READ level.monsterx%(level%, m% )
         READ level.monstery%(level%, m% )
       NEXT
       READ 
level.noKobolds%( level% )
       FOR m% = 1 TO MAX_KOBOLDS%
         READ level.koboldx%(level%, m% )
         READ level.koboldy%(level%, m% )
       NEXT
       READ 
level.noGhosts%( level% )
       FOR m% = 1 TO MAX_GHOSTS%
         READ level.ghostx%(level%, m% )
         READ level.ghosty%(level%, m% )
       NEXT

     NEXT

     
(_LEVEL_DATA_)

     REM X - impassable wall
     REM 0 - (zero) Boulder (destroyed by dynamite)
     REM * - gold
     REM @ - armour
     REM + - heath/first-aid kit
     REM ! - ammo crate

     REM important
     REM There must be AT LEAST ONE GOLD on each level!

     REM each map should follow this format:

     REM data map name
     REM data 17 strings, of 30 characters each
     REM    IMPORTANT!  The border character of the players movement MUST be an X
     REM data string of text to be displayed before the level starts
     REM data x,y starting position
     REM data the number of snakes in the level (0 - 20)
     REM    IMPORTANT.  If you want zero snakes in a level, the position of the first snake MUST be (-1,-1)
     REM data 20 pairs of coordinates
     REM    IMPORTANT.  The coordinates must NOT be an 'X' or '0' on the map
     REM                leave coords as -1,-1 for 'no snake'
     REM                you MUST specify 20 coordinates for each level (-1,-1) for 'no snake'
     REM
     REM data the number of kobolds in the level (0-10)
     REM    IMPORTANT.  If you want zero kobolds, the position of the first kobold MUST be (-1,-1)
     REM data 10 pairs of coordinates for the kobold starting position
     REM    IMPORTANT.  The coordinates must NOT be an 'X' or '0' on the map
     REM                leave coords as -1,-1 for 'no kobold'
     REM                you MUST specify 10 coordinates for each level (-1,-1) for 'no kobold'
     REM
     REM data the number of ghosts in the level
     REM    IMPORTANT.  If you want zero ghosts, the position of the first ghost MUST be (-1,-1)
     REM data 3 pairs of coordinates for the ghost starting positions
     REM    IMPORTANT.  The coordinates can be an 'X' or '0' on the map (ghosts can walk through walls)
     REM                leave coords as -1,-1 for 'no ghost'
     REM                you MUST specify 10 coordinates for each level (-1,-1) for 'no ghost'

     
DATA "Humble beginnings"
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "    XXXXXXXXXXXXXXXXXXXXXX    "
     
DATA "       XXXXXXXXXXXXXXXXXX     "
     
DATA "    X !  XXXXXXXX      XXX    "
     
DATA "    X0000    XXX     * XX     "
     
DATA "              XX      * xx    "
     
DATA "    XXXXXXX    00     * XX    "
     
DATA "    XXXXXXXXXXXXXX     XXX    "
     
DATA "    XXXXXXXXXXXXXXXXXXXXXX    "
     
DATA "    XXXXXXXXXXXXXXXXXXXXXX    "
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "Pick up the ammo crate (!). Use the bombs (i) to blow a path through the rubble. Collect all the gold (*) to win the level! Oh yeah, and dont stand too close to the explosions!"
     
DATA 13,9
     DATA 0
     DATA -1,-1
     DATA 17,12
     DATA 12,12
     DATA 14,15
     DATA 7,8
     DATA 8,7
     DATA 3,12
     DATA 9,10
     DATA 26,12
     DATA 26,8
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1

     DATA 0 : REM number of kobolds
     DATA -1,-1
     DATA 18,9
     DATA 5,4
     DATA 3,4
     DATA 2,5
     DATA 18,12
     DATA 19,9
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA 0: rem number of ghosts
     DATA -1,-1
     DATA 5,8
     DATA 13,13


     DATA "Introducing Snakes"
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "    XXXXXXXXXXXXXXXXXXXXXX    "
     
DATA "        ! 000  XX0000XXXXX    "
     
DATA "    X000000  0XX0 0XX0   X    "
     
DATA "    X    XXXX00000xx     x    "
     
DATA "    XXXX0    00    0 0XX*X    "
     
DATA "    XXX    0XX    0XX X *X    "
     
DATA "    X0  x    0XX    x0XX0X    "
     
DATA "    X  !!XXXX  0  000000XX    "
     
DATA "    XXXXXXXXXXXXXXXXXXXXXX    "
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "Snakes move in a random direction and are slow enough for you to place a bomb next to them."
     
DATA 6,6
     DATA 2
     DATA 12,6
     DATA 17,11
     DATA 12,12
     DATA 14,15
     DATA 7,8
     DATA 8,7
     DATA 3,12
     DATA 9,10
     DATA 26,12
     DATA 26,8
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1

     DATA 0 : REM number of kobolds
     DATA -1,-1
     DATA 18,9
     DATA 5,4
     DATA 3,4
     DATA 2,5
     DATA 18,12
     DATA 19,9
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA 0: rem number of ghosts
     DATA -1,-1
     DATA 5,8
     DATA 13,13

     DATA "Prepreparation prevents..."
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "    XXXXXXXXXXXXXXXXXXXXXX    "
     
DATA "    X   !!!!XXXX00    00XX    "
     
DATA "    X         0        0XX    "
     
DATA "    X   0XXXXX  @@      0X    "
     
DATA "    XXXXX0!!0XXXXXX0    0X    "
     
DATA "    XXX        00XXXX    X    "
     
DATA "    X0                  0X    "
     
DATA "    X   * * *   @@      XX    "
     
DATA "    XXXXXXXXXXXXXXXXXXXXXX    "
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "Collect as many of the goodies you can from this level."
     
DATA 6,6
     DATA 2
     DATA 10,11
     DATA 17,9
     DATA 12,12
     DATA 14,15
     DATA 7,8
     DATA 8,7
     DATA 3,12
     DATA 9,10
     DATA 26,12
     DATA 26,8
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1

     DATA 0 : REM number of kobolds
     DATA -1,-1
     DATA 18,9
     DATA 5,4
     DATA 3,4
     DATA 2,5
     DATA 18,12
     DATA 19,9
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA 0: rem number of ghosts
     DATA -1,-1
     DATA 5,8
     DATA 13,13


     DATA "How to bomb like a boss"
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "    XXXXXXXXXXXXXXXXXXXXXX    "
     
DATA "    X   XXXXXXXXXXXXXXXXXX    "
     
DATA "    X !  XXXXXXXX      XXX    "
     
DATA "    X         XXX     * XX    "
     
DATA "    XXXXXXX    0000   * XX    "
     
DATA "    XXXXXXX    0XX    * XX    "
     
DATA "    XXXXXXXXXXXXXX     XXX    "
     
DATA "    XXXXXXXXXXXXXXXXXXXXXX    "
     
DATA "    XXXXXXXXXXXXXXXXXXXXXX    "
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "Collect some bombs, and breach the barrier. Don't be worried by the non-MLG snake camping outside"
     
DATA 13,9
     DATA 1
     DATA 5,3
     DATA 17,12
     DATA 12,12
     DATA 14,15
     DATA 7,8
     DATA 8,7
     DATA 3,12
     DATA 9,10
     DATA 26,12
     DATA 26,8
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1

     DATA 0 : REM number of kobolds
     DATA -1,-1
     DATA 18,9
     DATA 5,4
     DATA 3,4
     DATA 2,5
     DATA 18,12
     DATA 19,9
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA 0: rem number of ghosts
     DATA -1,-1
     DATA 5,8
     DATA 13,13


     DATA "MLG Snake Kills"
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "    XXXXXXXXXXXXXXXXXXXXXX    "
     
DATA "    X    000  XX00*00XXXXX    "
     
DATA "    X    XX0 0XX 000  000X    "
     
DATA "    X    XX  00000     00X    "
     
DATA "    XX          0 0XX   0X    "
     
DATA "    XXX    0XX    0XX  * X    "
     
DATA "    X0      XX     0XX0 0X    "
     
DATA "    X  !!  0  0    00000XX    "
     
DATA "    XXXXXXXXXXXXXXXXXXXXXX    "
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "Those snakes are noobs that camp to get kills. Bomb them all and get the gold."
     
DATA 6,6
     DATA 3
     DATA 8,6
     DATA 13,5
     DATA 16,10
     DATA 14,15
     DATA 7,8
     DATA 8,7
     DATA 3,12
     DATA 9,10
     DATA 26,12
     DATA 26,8
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1

     DATA 0 : REM number of kobolds
     DATA -1,-1
     DATA 18,9
     DATA 5,4
     DATA 3,4
     DATA 2,5
     DATA 18,12
     DATA 19,9
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA 0: rem number of ghosts
     DATA -1,-1
     DATA 5,8
     DATA 13,13





     (_PART_TWO_)

     DATA "Wake up call"
     
DATA "                              "
     
DATA "                       XXXX   "
     
DATA "                       0**0   "
     
DATA "                       0000   "
     
DATA "    XXXXXXXXXXXXXXXXXXXXXX    "
     
DATA "    X          XXXXXXXXXXX    "
     
DATA "    X !        XX *0    0     "
     
DATA "    X          XX000    X     "
     
DATA "    XX0XXXX    XX       XX    "
     
DATA "    XX0XXXXXXXXXX000 00XX     "
     
DATA "    XX0XXX!0 * XXX*0 0*XXX    "
     
DATA "    XX0XXX X * XXXXXXXXXXX    "
     
DATA "    XX XXX XXXXXXXXXXXXXXX    "
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "You wake up in a dark room with two monsters trying to kill you. you must get out of there and collect the stars!"
     
DATA 13,9
     DATA 1
     DATA 6,8
     DATA 6,9
     DATA 12,12
     DATA 14,15
     DATA 7,8
     DATA 8,7
     DATA 3,12
     DATA 9,10
     DATA 26,12
     DATA 26,8
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1

     DATA 0 : REM number of kobolds
     DATA 7,6
     DATA 7,8
     DATA 5,4
     DATA 3,4
     DATA 2,5
     DATA 18,12
     DATA 19,9
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA 0: rem number of ghosts
     DATA -1,-1
     DATA 5,8
     DATA 13,13


     DATA "The snake pit"
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "    XXXXXXXXXXXXXXXXXXXXXX    "
     
DATA "    X*X                0*X    "
     
DATA "    X0X                XXX    "
     
DATA "    X                    X    "
     
DATA "    X         !          X    "
     
DATA "    X                    X    "
     
DATA "    X0X                XXX    "
     
DATA "    X*X                0*X    "
     
DATA "    XXXXXXXXXXXXXXXXXXXXXX    "
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "                              "
     
DATA "You arrive in a pit full of snakes and find more stars. You must collect them and move on to escape! Don't forget to save up your bombs"
     
DATA 8,7
     DATA 10
     DATA 11,10
     DATA 9,9
     DATA 15,8
     DATA 7,7
     DATA 12,6
     DATA 7,5
     DATA 8,6
     DATA 9,6
     DATA 8,6
     DATA 10,7
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1

     DATA 0 : REM number of kobolds
     DATA -1,-1
     DATA 18,9
     DATA 5,4
     DATA 3,4
     DATA 2,5
     DATA 18,12
     DATA 19,9
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA 0: rem number of ghosts
     DATA -1,-1
     DATA 5,8
     DATA 13,13


     DATA "Clear the rubble!"
     
DATA "                              "
     
DATA "                              "
     
DATA "  XXXXXXXXXXXXXXXXXXXXXXXXXX  "
     
DATA "  XXX    X*00      00000*** X "
     
DATA "  X*0   !X*00      000000000X "
     
DATA "  XXX    X*00      00000000XX "
     
DATA "  X      X*00      000000000X "
     
DATA "  XXXX0XXXXXXX     00000000XX "
     
DATA "  X      X  !X     00000000XX "
     
DATA "  X      X   0             XX "
     
DATA "  XXXX0XXXXXXXXXXXX0XXXXXXXXX "
     
DATA "  X      X       X        XX "
     
DATA "  X      X       0        XX  "
     
DATA "  X      0       X         X  "
     
DATA "  XXXXXXXXXXXXXXXXXXXXXXXXXX  "
     
DATA "                              "
     
DATA "                              "
     
DATA "There is a room full of rubble and a limited supply of bombs. Avoid the snake and obtain the stars to learn more about why you're here!"
     
DATA 6,6
     DATA 0 : rem number of monsters
     DATA 19,6
     DATA 13,12
     DATA 12,12
     DATA 14,15
     DATA 7,8
     DATA 8,7
     DATA 3,12
     DATA 9,10
     DATA 26,12
     DATA 26,8
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1

     DATA 0 : REM number of kobolds
     DATA -1,-1
     DATA 18,9
     DATA 5,4
     DATA 3,4
     DATA 2,5
     DATA 18,12
     DATA 19,9
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA 0: rem number of ghosts
     DATA -1,-1
     DATA 5,8
     DATA 13,13


     DATA "Here are some supplies"
     
DATA "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
     
DATA "X*@@@@@@@@@@@@@@@@@@@@@@@@@@@X"
     
DATA "X@@@@@@@@@@@@@@@@@@@@@@@@@@@@X"
     
DATA "X@@@@@@@@@@@@@@@@@@@@@@@@@@@@X"
     
DATA "X@@@@@@@@@@@@@@@@@@@@@@@@@@@@X"
     
DATA "X@@@@@@@@@@@@@@@@@@@@@@@@@@@@X"
     
DATA "X@@@@@@@@@@@@@@@@@@@@@@@@@@@@X"
     
DATA "X0000000000000000000000000000X"
     
DATA "X!!!!!!!!!!!!!!!!!!!!!!!!!!!!X"
     
DATA "X!!!!!!!!!!!!!!!!!!!!!!!!!!!!X"
     
DATA "X!!!!!!!!!!!!!!!!!!!!!!!!!!!!X"
     
DATA "X!!!!!!!!!!!!!!!!!!!!!!!!!!!!X"
     
DATA "X!!!!!!!!!!!!!!!!!!!!!!!!!!!!X"
     
DATA "X!!!!!!!!!!!!!!!!!!!!!!!!!!!!X"
     
DATA "X!!!!!!!!!!!!!!!!!!!!!!!!!!!!X"
     
DATA "X!!!!!!!!!!!!!!!!!!!!!!!!!!!!X"
     
DATA "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
     
DATA "Remember ammo crates will blow when  exploded and so you can create a chain of bombs!"
     
DATA 13,9
     DATA 0
     DATA -1,-1
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2

     DATA 0 : REM number of kobolds
     DATA -1,-1
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 0: rem number of ghosts
     DATA -1,-1
     DATA 2,2
     DATA 2,2


     DATA "Blow it up!"
     
DATA "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
     
DATA "X*00000000   PAWN  0000000000X"
     
DATA "X0000000000000000000000000000X"
     
DATA "X0000000000000000000000000000X"
     
DATA "X0000000000000000000000000000X"
     
DATA "X0000000000000000000000000000X"
     
DATA "X0000000000000000000000000000X"
     
DATA "X0000000000000000000000000000X"
     
DATA "X0000000000000000000000000000X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
     
DATA "Don't Waste bombs!"
     
DATA 10,2
     DATA 1
     DATA 13,2
     DATA -1,-1
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2

     DATA 0 : REM number of kobolds
     DATA -1,-1
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 1: rem number of ghosts
     DATA 2,2
     DATA 2,2
     DATA 2,2


     DATA "CAVE IN!                 "
     
DATA "                              "
     
DATA "                              "
     
DATA "  XXXXXXXXXXXXXXXXXXXXXXXXXX  "
     
DATA "  XX!!!!!!!!!!!!!!!!!!!!!!!X  "
     
DATA "  XX!!!!!!     !!X!!  XXXXXXX "
     
DATA "  XXXXXXXXXXXXXXXXXXX0XXXXXX  "
     
DATA "  X        !!!!!!!!!000XXXXX  "
     
DATA "  X   XX!!!!!!!!!!!000X00XXX  "
     
DATA "  X       !     !!!XXXXX  XX  "
     
DATA "  X XX XXX      !0000000   X  "
     
DATA "  X XX     XX    XXX000    0  "
     
DATA "  X    XX   XX    0XXX0    X  "
     
DATA "  X   XXX         0XXX0    X  "
     
DATA "  X                X000    X  "
     
DATA "  XXXXXXXXXXXXXXXXXXXXXXXXXX  "
     
DATA "                    *         "
     
DATA "                              "
     
DATA "UH OH THE CAVE FELL IN!. IF THE KOBOLD TRIES TO EXIT THE WORLD YOU DIE!!!"
     
DATA 2,5
     DATA 0 : rem number of monsters
     DATA 19,6
     DATA 13,12
     DATA 12,12
     DATA 14,15
     DATA 7,8
     DATA 8,7
     DATA 3,12
     DATA 9,10
     DATA 26,12
     DATA 26,8
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1

     DATA 1 : REM number of kobolds
     DATA 3,8
     DATA 18,9
     DATA 5,4
     DATA 3,4
     DATA 2,5
     DATA 18,12
     DATA 19,9
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA 1: rem number of ghosts
     DATA 2,2
     DATA 5,8
     DATA 13,13



     DATA "BETTER RUN"
     
DATA "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
     
DATA "X++++++++++++++++++++++++++++X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "X@@@@@@@@@@@@@@@@@@@@@@@@@@@@X"
     
DATA "X0000000000000000000000000000X"
     
DATA "X!!!!!!!!!!!!!!!!!!!!!!!!!!!!X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
     
DATA "THE MONSTERS HAVE OVERRUN YOUR SUPPLY BASE!"
     
DATA 13,9
     DATA 20
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2

     DATA 10 : REM number of kobolds
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 3: rem number of ghosts
     DATA 2,2
     DATA 2,2
     DATA 2,2




     DATA "NO MORE EDITED LEVELS"
     
DATA "*XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
     
DATA "X++++++++++++++++++++++++++++X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "XTHIS IS THE END OF EDITED   X"
     
DATA "XLEVELS                      X"
     
DATA "X!!!!!!!!!!!!!!!!!!!!!!!!!!!!X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "X****************************X"
     
DATA "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
     
DATA "END OF MY LEVELS"
     
DATA 13,9
     DATA 0
     DATA -1,-1
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2
     DATA 2,2

     DATA 0: REM number of kobolds
     DATA -1,-1
     DATA 18,9
     DATA 5,4
     DATA 3,4
     DATA 2,5
     DATA 18,12
     DATA 19,9
     DATA -1,-1
     DATA -1,-1
     DATA -1,-1
     DATA 0: rem number of ghosts
     DATA -1,-1
     DATA 5,8
     DATA 13,13




     ENDPROC

Label