HTBasic Help
×
Menu
Index

Example: Bomb Squad (*Create Version)

 
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
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