24
Scribble
Scribble is a game for any number of players up to six, and has much in common with Scrabble, Lexicon and similar word games. The object is to make words, for which the computer awards points, the first player reaching a score of 200 points being the winner.
On his or her turn, the player may do one of three things: (a) shuffle the letter pool, (b) take a letter from the pool and add it to his hand, or (c) make a word from the letters in his hand. To shuffle the pool, the player simply presses RETURN. To take up a letter from the pool, the letter is typed. The computer removes the letter from the pool and adds it to those in the player's hand, then selects another letter for the pool. To play a word, the player types the whole word and presses RETURN. The computer checks that the word is possible from the letters in the hand, and if so, asks if any other player objects to the word or to its spelling. If all is well, the score is calculated and the letters are removed from the player's hand.
Please note very carefully that the score for a word depends upon (a) the individual values of the letters making up the word, (b) the length of the word, with longer words scoring heavily, and (c) the number of letters remaining in the hand; the more letters left unused, the greater the penalty. At the extreme, it is just possible to play a short word, have a lot of letters left over and so be awarded a negative score!
There are 'jokers' in the form of '*', which have no value but which may be used in place of any letter. To pick up such a joker, the '*' must be typed. On the other hand, to play a word containing a joker, the player does not include '*', but types the whole word as he or she wishes it to be. The computer first checks for normal letters and if one or more short, checks for jokers.
Before and after each player's move there is a timed delay for thought and observation, but players may move the game on swiftly by pressing RETURN. Finally, the number of times that each player may shuffle the letter pool is limited, dependent upon the number of players.
Lines 30 to 50 scatter various letters around the screen in a variety of colours and may well be omitted. They just make a pretty introduction to the game. The title screen appears on lines 60 to 80 and is moved on automatically after five seconds, or sooner if desired by pressing any key. The next lines seek information on the number of players, calculate the number of times each may shuffle the letter pool, and seek players' names. We then call PROCDISPLAY which in turn calls PROCBOX several times, creating an attractive playing screen. PROCINIT selects a starting pool of seven letters and also selects five letters for each player. We then enter the game loop.
It will be seen that the game loop is very simple. On each pass through it will call PROCPLAY, PROCPOOL, PROCPANEL and PROC2 before checking if the current player PL% has reached a winning score.
PROCPLAY calls PROCPANEL, which prints the player's name and lists the letters in his or her hand, with values printed below. The player is then prompted for his play, in line 1020. If G$ is empty, RETURN has been pressed on an empty set and so the player wants to shuffle the letter pool. If the length of the input string is 1, the player wishes to take a letter from the pool, and this is checked on line 1090. The presence of the letter in the pool is looked for in line 1120 and, all being well, line 1180 takes it into the player's hand. A new letter for the pool is found in line 1200.
The player's hand is checked, in lines 1220 onward, when he wishes to make a word. Each character of the input string is checked against the letters held, but notice that in order to save memory space we save the ASCII value of the letters, not the letters themselves. If we are short of a letter or two, lines 1300 to 1310 check for the presence of a joker. We have kept a running score of letter values in T% while the checking was going on, and in line 1440 we add a bonus for the length of the word and subtract three points for each letter left in the hand. Change this if you don't like it. The rest of the listing should be fairly straightforward.
You will see that the values of the 26 letters are stored as DATA statements in line 710, with the most commonly used letters having a value 1, rising up to 9 for Q and Z. The letters themselves are held in lines 720 to 800, and at first sight one might wonder why they are there at all - why not just pick a random number 1 to 26? In practice, however, such a course would have the J, X or Z occurring as often as E or A; clearly not a desirable state of affairs. Of course, one could write a RND statement and hedge it about with all sorts of IFs and other things to increase the frequency of chosen letters, but in the end one has a whole lot of BASIC statements that take up far more space than the DATA lines shown. I wrote the alphabet several times and then altered infrequently occurring letters to others over a large number of games until I achieved what I thought to be the right mix. Change it by all means!
Variables
C$ | Row of spaces for clearance purposes |
X% | General counter |
C% | Random colour |
Q$ | General-purpose print string; also dummy |
P% | Number of players |
MAX% | Shuffles permitted per player |
P%(X,Y) | Player's data, where X = player number and |
| Y = 0 = score |
| Y = 1 to 12 = ASCII value of letters held |
| Y = 13 = shuffles usd |
P$(X) | Players' names |
POOL$ | Letters in pool |
C%(X) | Current player's letters |
PL% | Current player number |
In PROCINIT:
X% | General counter |
L% | Randomly chosen letter, 1 to 178 |
G$ | Chosen letter |
In PROCPOOL:
X% | General counter |
V% | Letter value |
C% | Alphabetic position |
A% | General counter |
In PROCPLAY:
G$ | Player's input |
X$ | Message string |
Q$ | Dummy |
X% | General counter |
Y% | Number of first empty place in player's hand |
C% | Randomly chosen letter |
T% | Running total of score |
Z% | General counter |
S% | Letter value |
10 REM - Scribble
20 C$=STRING$(15," ")
30 CLS:FORX%=1 TO 200:C%=RND(26)+64
40 Q$=CHR$(RND(7)+128)+CHR$C%
50 PRINTTAB(RND(37),RND(22));Q$:NEXT
60 PROCDBL(12,13,135,"SCRIBBLE ")
70 PRINTTAB(13);"__________ "
80 PROCDBL(2,9,135," THE COMPUTER WORD GAME ")
90 Q$=INKEY$(500):MODE7
100 PRINT''''"How many players (1-6)";:PROCBOX(1,1,4)
110 REPEAT:P%=GET-48:UNTIL P%>0 AND P%<=6:PRINT;P%
120 MAX%=12/(P%+1)
130 IF P%=1 PRINT''"You";ELSE PRINT''"Each player";
140 PRINT;" may shuffle the letters"
150 IF MAX%=1 PRINT"once."''ELSE PRINT;MAX%;" times."''
160 INPUT" Press RETURN..."G$
170 DIM P%(P%,13),P$(P%),POOL$(7),C%(12)
180 CLS:FOR X%=1 TO P%
190 PRINT'"Player #";X%;" -"
200 PRINT"please type your name ";:PROCBOX(12,1,4)
210 INPUT P$(X%):NEXT:PROCDISPLAY:PROCINIT:PL%=1
220
230 REM - GAME LOOP ***************
240
250 PROCPLAY
260 PROCPOOL
270 PROCPANEL
280 PROCL2
290 IF P%(PL%,0)<200 PL%=(PL%MODP%)+1:GOTO250
300 PRINTTAB(21,19);CHR$135;CHR$136;P$(PL%);" WINS!";
310 END
320
330 DEFPROCDBL(X%,Y%,C%,X$)
340 PRINTTAB(X%,Y%);CHR$141;CHR$C%;X$
350 PRINTTAB(X%,Y%+1);CHR$141;CHR$C%;X$:ENDPROC
360
370 DEFPROCBOX(L%,H%,C%)
380 V%=VPOS:W%=POS
390 PRINTTAB(W%,V%-H%);CHR$(C%+144);"7";
400 FOR I%=0 TO L%+1:PRINT"£";:NEXT:PRINT"k"
410 PRINTTAB(W%,V%+1);CHR$(C%+144);"u";
420 FOR I%=0 TO L%+1:PRINT"p";:NEXT:PRINT"z"
430 FOR J%=V%-H%+1 TO V%
440 PRINTTAB(W%,J%);CHR$(C%+144);"5";CHR$135:NEXT
450 FOR J%=V%-H%+1 TO V%
460 PRINTTAB(W%+L%+3,J%);CHR$(C%+144);"j":NEXT
470 PRINTTAB(W%+3,V%);"";:ENDPROC
480
490 DEFPROCDISPLAY
500 CLS:PRINTTAB(0,4);:PROCBOX(35,4,1)
510 PRINTTAB(0,11);:PROCBOX(15,4,3)
520 PRINTTAB(4,8);CHR$133;"Letter Pool"
530 PRINTTAB(20,21);:PROCBOX(15,14,2)
540 PRINTTAB(22,8);CHR$129;"Name Score"
550 PRINTTAB(0,21);:PROCBOX(15,7,4)
560 ENDPROC
570
580 DEFPROCINIT
590 PROCMIX:REM - Shuffle pool
600 FOR X%=1 TO P%:FOR C%=1 TO 5
610 RESTORE 720:L%=RND(178)
620 FOR Y%=1 TO L%:READ G$:NEXT
630 P%(X%,C%)=ASC(G$):NEXT:NEXT
640 PROCUPDATE:PROCPOOL:ENDPROC
650
660 DEFPROCMIX:REM - Shuffle pool
670 FOR X%=1 TO 7:RESTORE 720
680 L%=RND(178)
690 FOR Y%=1 TO L%:READ POOL$(X%)
700 NEXT:NEXT:ENDPROC
710 DATA 1,5,3,3,1,4,2,2,1,6,5,2,3,3,1,3,9,3,2,2,2,6,4,7,2,9
720 DATA A,B,C,D,E,F,E,E,I,J,K,L,E,A,O,P,*,R,S,T,U
730 DATA V,I,X,Y,U,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P
740 DATA O,R,S,T,U,V,A,X,Y,E,A,B,C,D,E,F,G,H,I,E,*
750 DATA L,M,N,O,P,R,S,T,U,E,W,X,Y,A,B,C,D,E,F,G,H
760 DATA I,J,K,L,M,N,O,P,R,S,T,U,E,W,Y,*
770 DATA A,B,C,D,E,F,G,H,I,E,L,M,N,O,P,R,S,T,E,W,Y,*
780 DATA A,C,D,E,F,G,H,I,L,E,N,O,P,R,S,T,U,W,Y,*
790 DATA A,C,D,E,G,H,I,L,M,N,O,P,R,S,T,U,Y,*,A,E,G
800 DATA H,I,L,M,O,S,T,U,Y,*,A,E,I,O,E
810
820 DEFPROCUPDATE:REM - Print scores
830 FOR X%=1 TO P%
840 PRINTTAB(22,9+X%);CHR$135;P$(X%);TAB(35,9+X%);P%(X%,0)
850 NEXT:ENDPROC
860
870 DEFPROCPOOL:REM - Print pool
880 PRINTTAB(3,10);CHR$135;
890 FOR X%=1 TO 7:PRINT;POOL$(X%);" ";:NEXT
900 PRINTTAB(3,11);CHR$134;
910 FOR X%=1 TO 7:IF POOL$(X%)="*" V%=0:GOTO950
920 C%=ASC(POOL$(X%))-64
930 RESTORE 710
940 FOR A%=1 TO C%:READ V%:NEXT
950 PRINT;V%;" ";
960 NEXT:ENDPROC
970
980 DEFPROCPLAY
990 *FX15,1
1000 PROCPANEL:VDU7
1010 PRINTTAB(2,15);CHR$135;P$(PL%);
1020 PRINTTAB(2,16);CHR$135;"play";:INPUT G$
1030 IF G$<>""GOTO1090
1040 IF P%(PL%,13)<MAX% GOTO1080
1050 X$="All shuffles used"
1060 PRINTTAB(2,17);CHR$129;X$
1070 PROCBOING:Q$=INKEY$(500):PROCCLIP:GOTO990
1080 PROCMIX:PROCPOOL:ENDPROC
1090 IF LEN(G$)>1 GOTO1220 ELSE X%=1
1100
1110 REM - Take letter from pool
1120 IF POOL$(X%)=G$ GOTO1150
1130 X%=X%+1:IF X%<=7 GOTO1120
1140 X$="Not in the pool":GOTO1060
1150 IF P%(PL%,12)<>0 X$="Hand full":GOTO1060
1160 Y%=1
1170 IF P%(PL%,Y%)<>0 Y%=Y%+1:GOTO1170
1180 P%(PL%,Y%)=ASC(G$)
1190 RESTORE 720:C%=RND(178)
1200 FOR D%=1 TO C%:READ POOL$(X%):NEXT:ENDPROC
1210
1220 REM - Make a word
1230 FOR X%=1 TO 12:C%(X%)=P%(PL%,X%):NEXT:FL%=1
1240 T%=0:FOR X%=1 TO LEN(G$)
1250 C%=ASC(MID$(G$,X%,1)):Y%=1
1260 IF C%=C%(Y%) GOTO1320 ELSE Y%=Y%+1
1270 IF Y%<=12 GOTO1260 ELSE Y%=1
1280
1290 REM - Letter not found. Check *'s
1300 IF C%(Y%)=42 GOTO1320 ELSE Y%=Y%+1
1310 IF Y%<=12 GOTO1300 ELSE X$="Impossible":GOTO1060
1320 C%(Y%)=0:IF C%(Y%)=42 GOTO1340
1330 RESTORE 710:FOR Z%=1 TO C%-64:READ S%:NEXT
1340 T%=T%+S%:NEXT X%
1350 PRINTTAB(2,17);CHR$130;"Objections? ";
1360 REPEAT:Q$=GET$:UNTIL Q$="Y" OR Q$="N":PRINTQ$
1370 IF Q$<>"Y"GOTO1430
1380 P%(PL%,0)=P%(PL%,0)-10:PROCCLIP
1390 PRINTTAB(2,16);CHR$129;"Penalty 10"
1400 Q$=INKEY$(500):PROCCLIP:GOTO1010
1410
1420 REM - Calculate score
1430 C%=0:FOR X%=1 TO 12:IF C%(X%)<>0 C%=C%+1
1440 NEXT X%:T%=T%+(LEN(G$)-1)^2-C%
1450 P%(PL%,0)=P%(PL%,0)+T%
1460 PRINTTAB(2,18);CHR$133;"Score ";T%
1470 PROCUPDATE:PROCWARBLE:PROCL2:Y%=1
1480 FOR X%=1 TO 12:P%(PL%,X%)=0:NEXT
1490 FOR X%=1 TO 12
1500 IF C%(X%)=0 GOTO1520
1510 P%(PL%,Y%)=C%(X%):Y%=Y%+1
1520 NEXT X%
1530 ENDPROC
1540
1550 DEFPROCPANEL:REM - Player's panel
1560 PROCL3
1570 PRINTTAB(2,1);CHR$135;P$(PL%);
1580 PRINT" - in your hand you have"
1585 PRINTTAB(2,3);CHR$135;:X%=1
1590 IF P%(PL%,X%)=0 GOTO1620
1600 PRINT;CHR$(P%(PL%,X%));" ";
1610 X%=X%+1:IF X%<=12 GOTO1600
1620 PRINTTAB(2,4);CHR$134;:X%=1:T%=0
1630 IF P%(PL%,X%)=0 GOTO1680
1640 IF P%(PL%,X%)=42 V%=0:GOTO1670
1650 RESTORE 710
1660 FOR A%=1 TO P%(PL%,X%)-64:READ V%:NEXT
1670 PRINT;V%;" ";:T%=T%+V%:X%=X%+1:IF X%<=12 GOTO1630
1680 PRINT;" (";T%;")":ENDPROC
1690
1700 DEFPROCCLIP:REM Clear input
1710 PRINTTAB(2,16);C$:PRINTTAB(3,17);C$:ENDPROC
1720 DEFPROCL2:REM Clear input panel
1730 G$=INKEY$(500)
1740 FOR X%=15 TO 18:PRINTTAB(3,X%);C$:NEXT:ENDPROC
1750 DEFPROCL3:REM Clear player's panel
1760 FORX%=1 TO 4:PRINTTAB(2,X%);STRING$(36," "):NEXT
1770 ENDPROC
1780
1790 DEFPROCWARBLE
1800 FORS%=1TO20:SOUND1,-12,30,1
1810 SOUND1,-12,100,1:NEXT:ENDPROC
1820
1830 DEFPROCBOING
1840 SOUND 0,-15,80,2
1850 FOR S%=-15 TO 0:SOUND1,S%,20+S%,2:NEXT:ENDPROC