home *** CD-ROM | disk | FTP | other *** search
- 10 ! ********************************************************************
- 20 ! Example: Bomb Squad (*CREATE Version)
- 30 !
- 40 ! This program demonstrates the use of the CLOCK widget in TIMER mode
- 50 ! by playing a game in which the user has to disarm a bomb by cutting
- 60 ! wires. There are 10 wires - you must cut the correct four to disarm
- 70 ! the bomb. Of the six wires left, four are don't-cares and two wires
- 80 ! cause the bomb go off immediately.
- 90 !
- 100 ! The wires are represented by 10 TOGGLEBUTTONs. This program uses the
- 110 ! SYSTEM widget to create the TOGGLEBUTTONs. This is convenient since
- 120 ! otherwise you would have to have some degree of separate code for
- 130 ! each TOGGLEBUTTON. The fact that you only get one event for all
- 140 ! 10 TOGGLEBUTTONs is all right, too, since each time a TOGGLEBUTTON
- 150 ! event happens, the program scans through all the TOGGLEBUTTONs to
- 160 ! check their VALUEs.
- 170 !
- 180 ! ********************************************************************
- 190 !
- 200 RANDOMIZE INT(10^7*FRACT(TIMEDATE))! Set random seed
- 210 !
- 220 ! Miscellaneous general-purpose variables
- 230 !
- 240 INTEGER N,V
- 250 DIM S$[256],B$(1:1)[64],Eol$[2]
- 260 Eol$=CHR$(13)
- 270 !
- 280 ! Variables for display and widget handling
- 290 !
- 300 INTEGER Nlines,D(1:4) ! Used for display setup
- 310 REAL Dw,Dh ! Display dimensions
- 320 REAL Px,Py,Pw,Ph,Iw,Ih ! Main PANEL parameters
- 330 REAL Gap,Bh,Bw,Ch,Cw,Cx,Cy! Button/Clock dimensions
- 340 REAL Prh,Prw,Prx,Pry ! Printer widget dimensions
- 350 !
- 360 ! Various variables for playing the game
- 370 !
- 380 INTEGER Playgame ! Indicates game in progress
- 390 INTEGER Wires(1:10) ! Designates wire settings
- 400 INTEGER Live,Kill,Dontcare,Cut! Wire values
- 410 DATA 1,2,3,4
- 420 READ Live,Deadly,Dontcare,Cut
- 430 INTEGER Livewires,Lethal ! Number of live/deadly wires
- 440 !
- 450 ! Set up display
- 460 !
- 470 CLEAR SCREEN
- 480 STATUS CRT,13;Nlines ! Get number of display lines
- 490 GESCAPE CRT,3;D(*) ! Get BASIC display size
- 500 Dw=D(3)-D(1) ! Display width
- 510 Dh=(D(4)-D(2))*((Nlines-7)/Nlines)! Display height above softkeys
- 520 !
- 530 ! Set up PANEL coordinates
- 540 !
- 550 Pw=Dw*.7
- 560 Ph=Dh*.9
- 570 Px=(Dw-Pw)/2
- 580 Py=(Dh-Ph)/2
- 590 !
- 600 ! Create a SYSTEM widget
- 610 !
- 620 COM @Sys
- 630 ASSIGN @Sys TO WIDGET "SYSTEM"
- 640 !
- 650 ! Create a PANEL on the SYSTEM widget with SYSTEM MENU attribute
- 660 !
- 670 CONTROL @Sys;SET ("*NAME":"Main","*CREATE":"PANEL","VISIBLE":0)
- 680 CONTROL @Sys;SET ("RESIZABLE":0,"MAXIMIZABLE":0)
- 690 CONTROL @Sys;SET ("X":Px,"Y":Py,"WIDTH":Pw,"HEIGHT":Ph)
- 700 CONTROL @Sys;SET ("TITLE":" Example: Bomb Squad (*CREATE)")
- 710 CONTROL @Sys;SET ("SYSTEM MENU":"Quit")
- 720 !
- 730 ! Get interior dimensions of PANEL
- 740 !
- 750 STATUS @Sys;RETURN ("INSIDE WIDTH":Iw,"INSIDE HEIGHT":Ih)
- 760 !
- 770 ! Set up widget coordinates and dimensions
- 780 !
- 790 Gap=Ih*.03 ! Vertical gap
- 800 Bh=Ih*.1 ! Button height
- 810 Bw=Iw*.2 ! Button width
- 820 !
- 830 Ch=Iw*.20 ! Clock height
- 840 Cw=Ch ! Clock Width
- 850 Cx=Bw+((Iw-Bw)-Cw)/2! Clock X location
- 860 Cy=Gap ! Clock Y coordinate
- 870 !
- 880 Prh=Ih-(Ch+3*Gap)! Printer height
- 890 Prw=((Iw-Bw)-2*Gap)! Printer width
- 900 Prx=Bw+Gap ! Printer X coordinate
- 910 Pry=Ch+2*Gap ! Printer Y coordinate
- 920 !
- 930 ! Set up buttons in PANEL. The SYSTEM widget is used
- 940 ! to good advantage here, since the same code can
- 950 ! create all ten TOGGLEBUTTONS.
- 960 !
- 970 FOR N=1 TO 10
- 980 S$=VAL$(N)
- 990 CONTROL @Sys;SET ("*NAME":"Main/T"&S$,"*CREATE":"TOGGLEBUTTON")
- 1000 CONTROL @Sys;SET ("X":0,"Y":(N-1)*Bh,"WIDTH":Bw,"HEIGHT":Bh)
- 1010 CONTROL @Sys;SET ("LABEL":"Wire "&S$)
- 1020 NEXT N
- 1030 !
- 1040 ! Create CLOCK, set up as down-counting TIMER. The TIMER
- 1050 ! limit does not have to be set - it is 0 by default.
- 1060 !
- 1070 CONTROL @Sys;SET ("*NAME":"Main/Clock","*CREATE":"CLOCK")
- 1080 CONTROL @Sys;SET ("X":Cx,"Y":Cy,"WIDTH":Cw,"HEIGHT":Ch)
- 1090 CONTROL @Sys;SET ("TYPE":"TIMER","TIMER DIRECTION":"DOWN")
- 1100 !
- 1110 ! Create PRINTER
- 1120 !
- 1130 CONTROL @Sys;SET ("*NAME":"Main/Printer","*CREATE":"PRINTER")
- 1140 CONTROL @Sys;SET ("X":Prx,"Y":Pry,"WIDTH":Prw,"HEIGHT":Prh)
- 1150 !
- 1160 ! Set up events for SYSTEM MENU, TOGGLEBUTTONS, and CLOCK
- 1170 !
- 1180 ON EVENT @Sys,"SYSTEM MENU",15 GOTO Finis
- 1190 ON EVENT @Sys,"CHANGED" GOSUB Cutwire
- 1200 ON EVENT @Sys,"TIMER" GOSUB Boomboom
- 1210 !
- 1220 ! Turn on panel
- 1230 !
- 1240 CONTROL @Sys;SET ("*NAME":"Main","VISIBLE":1)
- 1250 !
- 1260 ! Display instructions using a DIALOG
- 1270 !
- 1280 S$="Disarm the bomb before the clock times out"&Eol$
- 1290 S$=S$&Eol$
- 1300 S$=S$&"The bomb has ten wires:"&Eol$
- 1310 S$=S$&Eol$
- 1320 S$=S$&" - 4 wires are inert."&Eol$
- 1330 S$=S$&" - 4 wires must be cut to disarm the bomb."&Eol$
- 1340 S$=S$&" - 2 wires are triggers: cut both, "&Eol$
- 1350 S$=S$&" and the bomb goes off."&Eol$
- 1360 S$=S$&Eol$
- 1370 S$=S$&"GOOD LUCK!"&Eol$
- 1380 !
- 1390 B$(1)="Click Here To Begin Game"
- 1400 !
- 1410 DIALOG "INFORMATION",S$;SET ("TITLE":" Bomb Squad Instructions","JUSTIFICATION":"LEFT","BACKGROUND":9,"PEN":0,"DIALOG BUTTONS":B$(*))
- 1420 !
- 1430 ! Main game loop
- 1440 !
- 1450 LOOP
- 1460 !
- 1470 ! Clear PRINTER widget, set up all the "wires"
- 1480 !
- 1490 DISABLE
- 1491 CONTROL @Sys;SET ("STACKING ORDER":0)
- 1500 CONTROL @Sys;SET ("*NAME":"Main/Printer","TEXT":"")
- 1510 CALL Pr(" Welcome to BOMB SQUAD.")
- 1520 CALL Pr("")
- 1530 !
- 1540 FOR N=1 TO 10
- 1550 Wires(N)=Dontcare
- 1560 S$=VAL$(N)
- 1570 CONTROL @Sys;SET ("*NAME":"Main/T"&S$)
- 1580 CONTROL @Sys;SET ("SENSITIVE":1,"VALUE":0)
- 1590 NEXT N
- 1600 !
- 1610 ! Set up the deadly wires
- 1620 !
- 1630 Lethal=0
- 1640 REPEAT
- 1650 N=1+INT(10*RND)
- 1660 IF Wires(N)=Dontcare THEN
- 1670 Wires(N)=Deadly
- 1680 Lethal=Lethal+1
- 1690 END IF
- 1700 UNTIL (Lethal=2)
- 1710 !
- 1720 ! Set up the live wires
- 1730 !
- 1740 Livewires=0
- 1750 REPEAT
- 1760 N=1+INT(10*RND)
- 1770 IF Wires(N)=Dontcare THEN
- 1780 Wires(N)=Live
- 1790 Livewires=Livewires+1
- 1800 END IF
- 1810 UNTIL (Livewires=4)
- 1820 !
- 1830 ! Set the timer to 30 seconds, and start it running
- 1840 !
- 1850 CONTROL @Sys;SET ("*NAME":"Main/Clock")
- 1860 CONTROL @Sys;SET ("TIMER VALUE":30000,"TIMER STATE":"RUNNING")
- 1870 !
- 1880 ! Loop until game over. Note how the "Playgame" variable is
- 1890 ! set to 1 by EVENT-driven routines to tell the main routine
- 1900 ! that the game is over and that a new one should be started
- 1910 ! (by returning to the top of the loop).
- 1920 !
- 1930 ENABLE
- 1940 Playgame=0
- 1950 REPEAT
- 1960 UNTIL (Playgame=1)
- 1970 !
- 1980 END LOOP
- 1990 STOP
- 2000 !
- 2010 ! This routine checks the status of the "wire" togglebuttons.
- 2020 ! It relies on the "Wires" array to track the condition
- 2030 ! of the wire set at any time.
- 2040 !
- 2050 ! The following comments may help explain the routine.
- 2060 !
- 2070 Cutwire:!
- 2080 !
- 2090 ! Check status of all ten wires
- 2100 !
- 2110 FOR N=1 TO 10
- 2120 !
- 2130 ! Ignore the wire if it has been cut
- 2140 !
- 2150 IF Wires(N)<>Cut THEN
- 2160 !
- 2170 ! Otherwise, query the togglebutton value
- 2180 !
- 2190 S$=VAL$(N)
- 2200 CONTROL @Sys;SET ("*NAME":"Main/T"&S$)
- 2210 STATUS @Sys;RETURN ("VALUE":V)
- 2220 !
- 2230 ! Ignore the button if it is not set, otherwise ...
- 2240 !
- 2250 IF V=1 THEN
- 2260 !
- 2270 ! ... disable the button ...
- 2280 !
- 2290 CONTROL @Sys;SET ("SENSITIVE":0)
- 2300 !
- 2310 ! ... and take the appropriate measures for the wire value
- 2320 !
- 2330 SELECT Wires(N)
- 2340 !
- 2350 ! Don't care, just say so
- 2360 !
- 2370 CASE Dontcare
- 2380 CALL Pr("Inert wire.")
- 2390 !
- 2400 ! Live wire: decrement the live-wire count - if it reaches 0,
- 2410 ! you win. Use a DIALOG to indicate the matter and query to see
- 2420 ! if the user wants to play another game. If it is not 0,
- 2430 ! announce the wire has been cut and list the number of wires
- 2440 ! remaining.
- 2450 !
- 2460 CASE Live
- 2470 Livewires=Livewires-1
- 2480 IF Livewires=0 THEN
- 2490 CONTROL @Sys;SET ("*NAME":"Main/Clock")
- 2500 CONTROL @Sys;SET ("TIMER STATE":"STOPPED")
- 2510 S$="Play another game?"
- 2520 DIALOG "QUESTION",S$,Btn;SET ("TITLE":" Bomb Disarmed !!")
- 2530 SELECT Btn
- 2540 CASE 0
- 2550 Playgame=1! Start new game
- 2560 RETURN
- 2570 CASE 1
- 2580 GOTO Finis! Quit program
- 2590 END SELECT
- 2600 ELSE
- 2610 S$=VAL$(Livewires)
- 2620 CALL Pr("LIVE WIRE -- "&S$&" wires left.")
- 2630 END IF
- 2640 !
- 2650 ! Is deadly -- count down deadly wires, if zero, you are dead
- 2660 !
- 2670 CASE Deadly
- 2680 Lethal=Lethal-1
- 2690 IF Lethal=0 THEN
- 2700 GOSUB Boomboom
- 2710 RETURN
- 2720 ELSE
- 2730 CALL Pr("DANGER -- trigger wire, one left!")
- 2740 END IF
- 2750 END SELECT
- 2760 !
- 2770 ! If you have not either won or been killed, mark this wire as
- 2780 ! being "cut".
- 2790 !
- 2800 Wires(N)=Cut
- 2810 !
- 2820 END IF
- 2830 END IF
- 2840 NEXT N
- 2850 RETURN
- 2860 !
- 2870 ! This routine tells you that you are dead
- 2880 !
- 2890 Boomboom:!
- 2900 CONTROL @Sys;SET ("*NAME":"Main/Clock","TIMER STATE":"STOPPED")
- 2910 S$="YOU'RE DEAD!"
- 2920 S$=S$&Eol$&Eol$
- 2930 S$=S$&"Play another game?"
- 2940 DIALOG "QUESTION",S$,Btn;SET ("TITLE":" Bomb Exploded !!")
- 2950 IF Btn=0 THEN
- 2960 Playgame=1
- 2970 RETURN
- 2980 ELSE
- 2990 GOTO Finis
- 3000 END IF
- 3010 RETURN
- 3020 !
- 3030 ! Go here when done
- 3040 !
- 3050 Finis:!
- 3060 ASSIGN @Sys TO *! Delete SYSTEM widget
- 3070 END
- 3080 !
- 3090 ! *************** End of Main Program ***********************
- 3100 !
- 3110 ! Routine to print string in PRINTER widget
- 3120 !
- 3130 SUB Pr(S$)
- 3140 COM @Sys
- 3150 CONTROL @Sys;SET ("*NAME":"Main/Printer","APPEND TEXT":S$)
- 3160 SUBEND
-