00010 REM OTHELLO AUTHOR: RICHARD O. DUDA 00020 REM PLAYS THE GAME "OTHELLO" WITH TWO STRATEGIES: 00030 REM 1. TAKE THE MAXIMUM NUMBER OF PIECES 00040 REM 2. ADD A BONUS FOR OUTSIDE POSITION 00050 REM BOARD IS THE ARRAY A, BOUNDED BY 0'S (BLANKS) 00060 REM A = 0 FOR EMPTY SQUARE 00070 REM A = B FOR BLACK SQUARE -- X (INTERNALLY -1) 00080 REM A = W FOR WHITE SQUARE -- O (INTERNALLY +1) 00090 REM I AND J ALWAYS USED FOR ROW/COLUMN INDICES 00100 REM I4 AND J4 STORE INCREMENTS TO THE 8 NEIGHBORS 00110 REM C$ AND D$ STORE CHARACTERS A-H,X,.,O FOR OUTPUT 00120 DIM A(9,9),I4(8),J4(8),C$(8),D$(2) 00130 REM INITIAL GREETING 00140 PRINT "GREETINGS FROM OTHELLO" 00150 PRINT "DO YOU WANT INSTRUCTIONS (Y OR N) "; 00160 INPUT X$ 00170 IF X$ = "N" THEN 390 00180 IF X$ <> "Y" THEN 160 00190 PRINT 00200 PRINT "OTHELLO IS PLAYED ON AN 8 X 8 CHECKER BOARD," 00210 PRINT "ROWS NUMBERED 1 TO 8 AND COLUMNS A TO H." 00220 PRINT "THE INITIAL CONFIGURATION IS ALL BLANK, EXCEPT" 00230 PRINT "FOR THE CENTER FOUR SQUARES, WHICH FORM THE" 00240 PRINT "PATTERN" 00250 PRINT " O X" 00260 PRINT " X O" 00270 PRINT 00280 PRINT "TRY TO PLACE YOUR PIECE SO THAT IT 'OUTFLANKS'" 00290 PRINT "MINE, CREATING A HORIZONTAL, VERTICAL, OR" 00300 PRINT "DIAGONAL RUN OF MY PIECES BOUNDED AT EACH END" 00310 PRINT "BY AT LEAST ONE OF YOURS. THIS WILL 'FLIP' MY" 00320 PRINT "PIECES, TURNING THEM INTO YOURS." 00330 PRINT "NOTE: YOU MUST CAPTURE AT LEAST ONE OF MY" 00340 PRINT "PIECES IN THIS WAY IF IT IS AT ALL POSSIBLE." 00350 PRINT "IF IT IS NOT POSSIBLE, YOU FORFEIT YOUR TURN BY" 00360 PRINT "ENTERING 0,0 FOR YOUR (ROW,COL) MOVE." 00370 PRINT 00380 REM INITIALIZE 00390 PRINT "SHOULD I WAIT BEFORE MAKING MY MOVES (Y OR N) "; 00400 F2 = 0 00410 INPUT X$ 00420 IF X$ = "N" THEN 460 00430 IF X$ <> "Y" THEN 410 00440 F2 = 1 00450 PRINT "OK. TYPING ANY CHARACTER WILL LET ME GO." 00460 PRINT "SHOULD I PLAY MY BEST STRATEGY (Y OR N) "; 00470 S2 = 0 00480 INPUT X$ 00490 IF X$ = "N" THEN 520 00500 IF X$ <> "Y" THEN 480 00510 S2 = 2 00520 B = -1 00530 W = +1 00540 D$(B + 1) = "X" 00550 D$(0 + 1) = "." 00560 D$(W + 1) = "O" 00570 FOR K = 1 TO 8 00580 READ I4(K) 00590 NEXT K 00600 DATA 0,-1,-1,-1,0,1,1,1 00610 FOR K = 1 TO 8 00620 READ J4(K) 00630 NEXT K 00640 DATA 1,1,0,-1,-1,-1,0,1 00650 FOR K = 1 TO 8 00660 READ C$(K) 00670 NEXT K 00680 DATA A,B,C,D,E,F,G,H 00690 REM SET UP A NEW GAME 00700 FOR I = 0 TO 9 00710 FOR J = 0 TO 9 00720 A(I,J ) = 0 00730 NEXT J 00740 NEXT I 00750 A(4,4) = W 00760 A(5,5) = W 00770 A(4,5) = B 00780 A(5,4) = B 00790 C1 =2 00800 H1 =2 00810 N1 = 4 00820 Z = 0 00830 REM HUMAN'S CHOICES 00840 PRINT "DO YOU WANT TO HAVE X OR O "; 00850 C = W 00860 H = B 00870 INPUT X$ 00880 IF X$ = "X" THEN 920 00890 IF X$ <> "O" THEN 870 00900 C = B 00910 H = W 00920 PRINT "DO YOU WANT TO GO FIRST (Y OR N) "; 00930 INPUT X$ 00940 IF X$ = "N" THEN 1020 00950 IF X$ <> "Y" THEN 930 00960 REM PRINT INITIAL BOARD 00970 GOSUB 3100 00980 GO TO 1690 00990 REM COMPUTER'S MOVE 01000 IF F2 = 0 THEN 1020 01010 INPUT X$ 01020 B1 = -1 01030 I3 = J3 = 0 01040 T1 = C 01050 T2 = H 01060 REM SCAN FOR BLANK SQUARE 01070 FOR I = 1 TO 8 01080 FOR J = 1 TO 8 01090 IF A(I,J) <> 0 THEN 1380 01100 REM FOUND A BLANK SQUARE 01110 REM DOES IT HAVE AN OPPONENT AS A NEIGHBOR? 01120 GOSUB 2620 01130 IF F1 = 0 THEN 1380 01140 REM FOUND AN OPPONENT AS A NEIGHBOR 01150 REM HOW MANY OF HIS PIECES CAN WE FLIP? 01160 REM (DON'T DO IT NOW) 01170 U = -1 01180 GOSUB 2820 01190 REM EXTRA POINTS FOR BOUNDARY POSITION 01200 IF S1 =0 THEN 1380 01210 IF (I - 1) * (I - 8) <> 0 THEN 1230 01220 S1 = S1 + S2 01230 IF (J - 1) * (J - 8) <> 0 THEN 1260 01240 S1 = S1 + S2 01250 REM IS THIS BETTER THAN THE BEST FOUND SO FAR? 01260 IF S1 < B1 THEN 1380 01270 IF S1 > B1 THEN 1340 01280 REM A TIE; RANDOM DECISION 01290 REM THE NEXT TWO EXECUTABLE STATEMENTS CAN BE DELETED 01300 REM FOR A VERSION OF BASIC-WITHOUT RANDOM NUMBERS 01310 R = RND(1 ) 01320 IF R > 0.5 THEN 1380 01330 REM YES 01340 B1 = S1 01350 I3 = I 01360 J3 = J 01370 REM END OF SCAN LOOP 01380 NEXT J 01390 NEXT I 01400 REM COULD WE DO ANYTHING? 01410 IF B1 > 0 THEN 01480 01420 REM NO 01430 PRINT "I HAVE TO FORFEIT MY MOVE" 01440 IF Z = 1 THEN 2190 01450 Z = 1 01460 GO TO 1690 01470 REM MAKE THE MOVE 01480 Z = 0 01490 PRINT "I WILL MOVE TO "; 01500 PRINT I3; 01510 PRINT ", "; 01520 PRINT C$(J3) 01530 I = I3 01540 J = J3 01550 U = 1 01560 GOSUB 2820 01570 C1 = C1 + S1 + 1 01580 H1 = H1 - S1 01590 N1 = N1 + 1 01600 PRINT "THAT GIVES ME "; 01610 PRINT S1; 01620 PRINT " OF YOUR PIECES" 01630 REM PRINT OUT BOARD 01640 GOSUB 3100 01650 REM TEST FOR END OF GAME 01660 IF H1 = 0 THEN 2190 01670 IF N1 = 64 THEN 2190 01680 REM HUMAN'S MOVE 01690 T1 = H 01700 T2 = C 01710 PRINT "YOUR MOVE -- (ROW, COL) "; 01720 INPUT I, X$ 01730 IF I < 0 THEN 1720 01740 IF I > 8 THEN 1720 01750 IF I <> 0 THEN 1820 01760 PRINT "ARE YOU FORFEITING YOUR TURN (Y OR N) " 01770 INPUT X$ 01780 IF X$ <> "Y" THEN 1710 01790 IF Z = 1 THEN 2190 01800 Z = 1 01810 GO TO 1000 01820 FOR J = 1 TO 8 01830 IF C$(J) = X$ THEN 1870 01840 NEXT J 01850 GO TO 1720 01860 REM CHECK IF BLANK 01870 IF A(I,J) = 0 THEN 1910 01880 PRINT "SORRY, THAT SQUARE IS OCCUPIED; TRY AGAIN" 01890 GO TO 1720 01900 REM CHECK FOR LEGAL NEIGHBOR 01910 GOSUB 2620 01920 IF F1 = 1 THEN 1970 01930 PRINT "SORRY, YOU ARE NOT NEXT TO ONE OF MY PIECES;" 01940 PRINT "TRY AGAIN" 01950 GO TO 1720 01960 REM CHECK IF LEGAL RUN 01970 U = -1 01980 GOSUB 2820 01990 IF S1 > 0 THEN 2030 02000 PRINT "SORRY, THAT DOESN'T FLANK A ROW; TRY AGAIN" 02010 GO TO 1720 02020 REM EVERYTHING LEGAL; MAKE HUMAN'S MOVE 02030 Z = 0 02040 PRINT "THAT GIVES YOU "; 02050 PRINT S1; 02060 PRINT " OF MY PIECES" 02070 U = 1 02080 GOSUB 2820 02090 H1 = H1 + S1 + 1 02100 C1 = C1 - S1 02110 N1 = N1 + 1 02120 REM PRINT OUT BOARD 02130 GOSUB 3100 02140 REM TEST FOR END OF GAME 02150 IF C1 = 0 THEN 2190 02160 IF N1 = 64 THEN 2190 02170 GO TO 1000 02180 REM END OF GAME WRAPUP 02190 PRINT 02200 PRINT "YOU HAVE "; 02210 PRINT H1; 02220 PRINT " PIECES AND I HAVE "; 02230 PRINT C1; 02240 PRINT " PIECES -- "; 02250 IF H1 = C1 THEN 2290 02260 IF H1 > C1 THEN 2310 02270 PRINT "SORRY, I WON THAT ONE." 02280 GO TO 2320 02290 PRINT "A TIE !!" 02300 GO TO 2500 02310 PRINT "YOU WON !" 02320 C1 = C1 - H1 02330 IF C1 > 0 THEN 2350 02340 C1 = -C1 02350 C1 = (64 * C1) / N1 02360 PRINT "THAT WAS A "; 02370 IF C1 < 11 THEN 2490 02380 IF C1 < 25 THEN 2470 02390 IF C1 < 39 THEN 2450 02400 IF C1 < 53 THEN 2430 02410 PRINT "PERFECT GAME." 02420 GO TO 2500 02430 PRINT "WALKAWAY." 02440 GO TO 2500 02450 PRINT "FIGHT." 02460 GO TO 2500 02470 PRINT "HOT GAME !" 02480 GO TO 2500 02490 PRINT "SQUEAKER ! ! " 02500 PRINT 02510 PRINT "DO YOU WANT TO PLAY ANOTHER GAME (Y OR N) "; 02520 INPUT X$ 02530 IF X$ = "Y" THEN 700 02540 IF X$ <> "N" THEN 2520 02550 PRINT "THANKS FOR PLAYING." 02560 STOP 02570 REM 02580 REM SUBROUTINE TEST-FOR-PROPER-NEIGHBOR 02590 REM ASSUMES: 02600 REM I,J LOCATES A BLANK SQUARE 02610 REM YOU HOPE TO SEE AN ADJACENT T2 (= -T1) 02620 FOR I1 = -1 TO 1 02630 FOR J1 = -1 TO 1 02640 IF A(I+I1,J+J1) = T2 THEN 2710 02650 NEXT J1 02660 NEXT I1 02670 REM NO T2 FOUND; FAILURE 02680 F1 = 0 02690 RETURN 02700 REM SUCCESS 02710 F1 = 1 02720 RETURN 02730 REM SUBROUTINE SCORE-AND-UPDATE 02740 REM ASSUMES: 02750 REM (I,J) IS A TENTATIVE PLACE FOR A PIECE T1. 02760 REM WANT RUNS OF T2 = -T1, TERMINATED BY A T1. 02770 REM IF U IS TRUE (1), MARK THOSE RUNS AS T1'S. 02780 REM RETURN SUM OF ALL RUNS (T2'S ONLY) IN S1. 02790 REM MAIN PROGRAM CONTAINS THE FOLLOWING ARRAYS: 02800 REM I4: 0 -1 -1 -1 0 1 1 1 02810 REM J4: 1 1 0 -1 -1 -1 0 1 02820 S1 = 0 02830 FOR K = 1 TO 8 02840 I5 = I4(K) 02850 J5 = J4(K) 02860 I6 = I + I5 02870 J6 = J + J5 02880 S3 = 0 02890 IF A(I6,J6) <> T2 THEN 3070 02900 REM LOOP THROUGH THE RUN 02910 S3 = S3 + 1 02920 I6 = I6 + I5 02930 J6 = J6 + J5 02940 IF A(I6,J6) = T1 THEN 2970 02950 IF A(I6,J6) = 0 THEN 3070 02960 GO TO 2910 02970 S1 = S1 + S3 02980 IF U <> 1 THEN 3070 02990 REM UPDATE BOARD 03000 I6 = I 03010 J6 = J 03020 FOR K1 = 0 TO S3 03030 A(I6,J6) = T1 03040 I6 = I6 + I5 03050 J6 = J6 + J5 03060 NEXT K1 03070 NEXT K 03080 RETURN 03090 REM SUBROUTINE PRINT-BOARD 03100 PRINT 03110 PRINT " A B C D E F G H" 03120 FOR I = 1 TO 8 03130 PRINT I; 03140 FOR J = 1 TO 8 03150 PRINT " "; 03160 PRINT D$(A(I,J)+1); 03170 NEXT J 03180 PRINT 03190 NEXT I 03200 PRINT 03210 RETURN 03220 END