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

## Bigger grid, please

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 GAME

6 GOSUB 6000

10 REM INITIALIZE GRID

15 MV=0

20 GOSUB 4000

30 REM SHOW GRID

40 GOSUB 1000

47 IF LO=0 THEN 200

50 REM INPUT SQUARE

60 GOSUB 2000

70 REM TOGGLE SQUARES

80 GOSUB 3000

90 REM REPEAT

95 MV=MV+1

100 GOTO 30

200 REM GAME WON

220 PRINT "YOU WON IN";MV;"MOVES."

230 INPUT "PLAY AGAIN (Y/N)";Q$

240 IF Q$="Y" THEN 5

250 PRINT "GAME OVER"

260 END

1000 REM SHOW GRID

1005 PRINT "GAME NUMBER:";GN

1006 PRINT " ";1007 FOR A=1 TO GS1009 NEXT:PRINT

1008 PRINT RIGHT$(STR$(A),2);1010 FOR Y=0 TO GS-11030 IF L(X,Y) THEN PRINT "X ";:GOTO 1050

1015 PRINT RIGHT$(STR$(Y+1),2);" ";

1020 FOR X=0 TO GS-1

1040 PRINT ". ";

1050 NEXT

1060 PRINT

1070 NEXT

1080 PRINT "MOVES:";MV;"LIGHTS ON:";LO

1090 RETURN

2000 REM INPUT SQUARE2010 PRINT "X,Y (1-";GS;",1-";GS;" OR 0,0)";2015 IF X=0 THEN IF Y=0 THEN 230

2011 INPUT X,Y2020 IF X<1 OR X>GS OR Y<1 OR Y>GS THEN 20102025 X=X-1:Y=Y-1

2030 RETURN

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

4000 REM INITIALIZE GRID4005 INPUT "GRID SIZE (3-10)";GS4010 PRINT "INITIALIZING..."

4006 IF GS<3 OR GS>10 THEN 4005

4020 FOR A=1 TO 104030 Y=RND(GS)-14050 GOSUB 3000

4040 X=RND(GS)-1

4060 NEXT

4070 RETURN

6000 REM SELECT GAME

6010 PRINT "PLAY SPECIFIC GAME # (Y/N)?"

6020 S=S+1:A$=INKEY$:IF A$="" THEN 6020

6030 IF A$="Y" THEN 6060

6040 IF A$="N" THEN A=RND(-S)

6045 GN=RND(65535):A=RND(-GN)

6046 GOTO 6090

6050 GOTO 6020

6060 INPUT "PLAY GAME (1-65535)";GN

6070 IF GN<1 OR GN>65535 THEN 6060

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