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

As we begin this part, let’s look at the BASIC Lights Out code as it stands currently:

5 REM SELECT GAME

6 GOSUB 6000

10 REM INITIALIZE GRID

20 GOSUB 4000

30 REM SHOW GRID

40 GOSUB 1000

47 IF LO=0 THEN PRINT "YOU WON!":END

48 PRINT "LIGHTS ON:";LO

50 REM INPUT SQUARE

60 GOSUB 2000

70 REM TOGGLE SQUARES

80 GOSUB 3000

90 REM REPEAT

100 GOTO 30

1000 REM SHOW GRID

1005 PRINT "GAME NUMBER:";GN

1010 FOR Y=0 TO 4

1020 FOR X=0 TO 4

1030 IF L(X,Y) THEN PRINT "X";:GOTO 1050

1040 PRINT ".";

1050 NEXT

1060 PRINT

1070 NEXT

1080 PRINT

1090 RETURN

2000 REM INPUT SQUARE

2010 INPUT "X,Y (0-4,0-4)";X,Y

2020 IF X<0 OR X>4 OR Y<0 OR Y>4 THEN 2010

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<4 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<4 THEN L(X,Y+1)=NOT L(X,Y+1):LO=LO-(L(X,Y+1)*2+1)

3060 RETURN

4000 REM INITIALIZE GRID

4010 PRINT "INITIALIZING..."

4020 FOR A=1 TO 10

4030 Y=RND(5)-1

4040 X=RND(5)-1

4050 GOSUB 3000

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

There are quite a few more things that could (and probably need to) be done:

- The number of moves taken should be counted and displayed.
- If the game is won, it just
**END**s in line 47. It could ask the player if they want to play again. - There is no way to quit a game in progress other than hitting the break key.
- The user interface (typing in coordinates such as “0,2”) is user-hostile. At the very least, we could label the rows/columns to show which values to type. Perhaps even labeling them “A B C D E …” across, and “1 2 3 4 5” vertically, similar to how chess boards are done.
- Options for grids larger than 5×5 could be implemented with very little change in the code.

Once the game is “code complete“, there is also be some cleanup and renumbering that should be done. (Having those odd line numbers like 47 bugs me.)

## Score (Counting Moves)

The current code only knows that you won the game (the game ends) or you are still playing. If one person plays game number 16809 and solves it in 80 moves, and another person plays the same game and solves it in 10 moves, they are both treated to the same ending – the game exits.

Let’s add a move counter. We’ll reset it at the start of a game…

10 REM INITIALIZE GRID15 MV=0

20 GOSUB 4000

…and increment it after every move:

90 REM REPEAT95 MV=MV+1

100 GOTO 30

We should also display the move count each time the grid is display. This is a good time to also move the “number of lights on” in to the display grid routine, too.

~~(removed)~~48 PRINT "LIGHTS ON:";LO

1000 REM SHOW GRID

1005 PRINT "GAME NUMBER:";GN

1010 FOR Y=0 TO 4

1020 FOR X=0 TO 4

1030 IF L(X,Y) THEN PRINT "X";:GOTO 1050

1040 PRINT ".";

1050 NEXT

1060 PRINT

1070 NEXT1080 PRINT "MOVES:";MV;"LIGHTS ON:";LO

1090 RETURN

This now gives us a display of our game number (which was already there), the number of moves made so far (new), and the current count of how many lights are on (already there).

DONE: ~~The number of moves taken should be counted and displayed.~~

## Game Over

The next thing I want to add is a game over screen. When the game is on, this screen should display how many moves it took. It could then prompt the user to see if they want to play agan.

It could be as simple as this:

47 IF LO=0 THEN 200

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

DONE: ~~If the game is won, it just ~~**END**s in line 47. It could ask the player if they want to play again.

## I give up!

The user should also be able to quit. Currently, the awful “type in an X,Y coordinate” thing is yucky, but we could make typing “-1,-1” end the game. (We will fix the user interface later.)

`2000 REM INPUT SQUARE`

**2010 INPUT "X,Y (0-4,0-4 OR -1,-1)";X,Y**

2015 IF X=-1 THEN IF Y=-1 THEN 230

2020 IF X<0 OR X>4 OR Y<0 OR Y>4 THEN 2010

2030 RETURN

This is so yucky, but the goal here is to get the code fully functional. We can make it nice later.

DONE: ~~There is no way to quit a game in progress other than hitting the break key.~~

## The user interface sucks!

Okay, this one will take more work, but a quick enhancement might be to just print the columns and rows so the player knows what to type. Also, humans like counting from one instead of zero (base-1 humans) so typing in things to match the base-0 arrays is not very human friendly. We can fix both things here.

1000 REM SHOW GRID

1005 PRINT "GAME NUMBER:";GN1006 PRINT " 12345"1010 FOR Y=0 TO 41015 PRINT Y+1;1020 FOR X=0 TO 4

1030 IF L(X,Y) THEN PRINT "X";:GOTO 1050

1040 PRINT ".";

1050 NEXT

1060 PRINT

1070 NEXT

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

1090 RETURN

…and…

2000 REM INPUT SQUARE2010 INPUT "X,Y (1-5,1-5 OR 0,0)";X,Y2015 IF X=0 THEN IF Y=0 THEN 2302030 RETURN

2020 IF X<1 OR X>5 OR Y<1 OR Y>5 THEN 2010

2025 X=X-1:Y=Y-1

Now the user will see numbers above the grid, and to the left of the grid, and be able to enter them using 1-5 rather than 0-4. I made 0,0 exit as well to save the use from having to type the minus signs.

But, this interface still sucks. After we get the “text and typing” version done, we can do one that is more modern and uses the arrow keys to cursor around and select squares.

DONE: ~~The user interface (typing in coordinates such as “0,2”) is user-hostile.~~

## Bigger grid, please

Hey, let’s just get the basic game working first, then we can worry about “Deluxe Lights Out.”

DEFERRED: Options for grids larger than 5×5 could be implemented with very little change in the code.

To be continued…