# Let’s write Lights Out in BASIC – part 6

See also: part 1, part 2, part 3, part 4, part 5, part 6 and part 7.

At this point, we have a nicely functional BASIC version of Lights Out. Some of its features include:

• 5×5 grid of lights.
• Random games.
• Allows replaying a specific game.
• Counts moves for scoring.
• Ability to quite a game in progress.
• Slightly less sucky user interface than the original version.

But we still have more to do!

One of the enhancements I mentioned in the previous installment was the ability to specify larger (or smaller, I suppose), grid sizes. We know that the official Lights Out games from Tiger Electronics in the 1990s used a 5×5 and 6×6 grid. Others have since created variations, such as one that operates around a cube (maybe we write that version some day). Let’s start there…

For this simple version, we’ll just arbitrarily pick a maximum grid size of 10×10. This should still fit easily on the CoCo’s 32×16 text screen. For fun, we could also allow a grid size smaller than 5×5 to be chosen. Since the spiritual predecessor of Lights Out was a 1970s game that featured a 3×3 grid, I’ll use that size as the minimum.

The changes needed should be fairly minor. When starting a game, the user will be prompted for the grid size.

It seems we could allow rectangular grids (5×3, 10×5, etc.), but for now we’ll just stick to square grids where both sides are the same size. The array for the grid just needs to be large enough to hold the largest sized grid.

## Wrong DIMension

An oversight I made when starting this program was not adding a DIM statement to specify the maximum size of the two-dimensional grid array! The current version really needs a line that contains this at the very top:

`DIM L(4,4)`

Reminder: DIM is base-0, so it starts counting entries at 0. A DIM X(4) gives entries X(0), X(1), X(2), X(3) and X(4).

The program only works because Color BASIC allows array entries 0-10 before the DIM is needed. You can do A(10)=42 without needing to DIM A(10) first. (I find it weird that Microsoft chose to default to 11 array entries. I bet whoever coded that was thinking “1-10” rather than “0-10”.)

To enhance the program to support up to a 10×10 grid, we’ll allocate an array that large.

`4 DIM L(9,9)`

Next we need to ask the user what size grid they want. This can be added to the “initialize grid” subroutine:

`4000 REM INITIALIZE GRID4005 INPUT "GRID SIZE (3-10)";GS4006 IF GS<3 OR GS>10 THEN 4005...`

After that, any place that is currently hard coded to 4 will need to be changed to use the grid size variable. If the user types in 10 (for a 10×10), the array will be using 0-9. We must pay attention to that and know that a 10 grid is actually 0-9.

This is also a good time to clean up the printing of the grid a bit. Here is the full program with the latest changes in bold:

`4 DIM L(9,9)5 REM SELECT GAME6 GOSUB 600010 REM INITIALIZE GRID15 MV=020 GOSUB 400030 REM SHOW GRID40 GOSUB 100047 IF LO=0 THEN 20050 REM INPUT SQUARE60 GOSUB 200070 REM TOGGLE SQUARES80 GOSUB 300090 REM REPEAT95 MV=MV+1100 GOTO 30200 REM GAME WON220 PRINT "YOU WON IN";MV;"MOVES."230 INPUT "PLAY AGAIN (Y/N)";Q\$240 IF Q\$="Y" THEN 5250 PRINT "GAME OVER"260 END1000 REM SHOW GRID1005 PRINT "GAME NUMBER:";GN1006 PRINT "  ";1007 FOR A=1 TO GS1008 PRINT RIGHT\$(STR\$(A),2);1009 NEXT:PRINT1010 FOR Y=0 TO GS-11015 PRINT RIGHT\$(STR\$(Y+1),2);" ";1020 FOR X=0 TO GS-11030 IF L(X,Y) THEN PRINT "X ";:GOTO 10501040 PRINT ". ";1050 NEXT1060 PRINT1070 NEXT1080 PRINT "MOVES:";MV;"LIGHTS ON:";LO1090 RETURN2000 REM INPUT SQUARE2010 PRINT "X,Y (1-";GS;",1-";GS;" OR 0,0)";2011 INPUT X,Y2015 IF X=0 THEN IF Y=0 THEN 2302020 IF X<1 OR X>GS OR Y<1 OR Y>GS THEN 20102025 X=X-1:Y=Y-12030 RETURN3000 REM TOGGLE SQUARES 3010 L(X,Y)=NOT L(X,Y):LO=LO-(L(X,Y)*2+1)3020 IF X>0 THEN L(X-1,Y)=NOT L(X-1,Y):LO=LO-(L(X-1,Y)*2+1)3030 IF X<GS-1 THEN L(X+1,Y)=NOT L(X+1,Y):LO=LO-(L(X+1,Y)*2+1)3040 IF Y>0 THEN L(X,Y-1)=NOT L(X,Y-1):LO=LO-(L(X,Y-1)*2+1)3050 IF Y<GS-1 THEN L(X,Y+1)=NOT L(X,Y+1):LO=LO-(L(X,Y+1)*2+1)3060 RETURN4000 REM INITIALIZE GRID4005 INPUT "GRID SIZE (3-10)";GS4006 IF GS<3 OR GS>10 THEN 40054010 PRINT "INITIALIZING..."4020 FOR A=1 TO 104030 Y=RND(GS)-14040 X=RND(GS)-14050 GOSUB 30004060 NEXT4070 RETURN6000 REM SELECT GAME6010 PRINT "PLAY SPECIFIC GAME # (Y/N)?"6020 S=S+1:A\$=INKEY\$:IF A\$="" THEN 60206030 IF A\$="Y" THEN 60606040 IF A\$="N" THEN A=RND(-S)6045 GN=RND(65535):A=RND(-GN)6046 GOTO 60906050 GOTO 60206060 INPUT "PLAY GAME (1-65535)";GN6070 IF GN<1 OR GN>65535 THEN 60606080 A=RND(-GN)6090 RETURN`

This version will display the grid with nicely (?) formatted headers for the columns and rows, and less nicely formatted prompts for what values are allowed.

There is still so much work to do to make the user interface nicer to look at and interact with.

To be continued…

This site uses Akismet to reduce spam. Learn how your comment data is processed.