1 REMark $$stak=2000
100 DIM move_dir(8),board(100),move_ok(100),save_p(100,8),s(100),ab(15),move_list(100),move_sc(100)
110 RESTORE 120:FOR i=1 TO 8:READ move_dir(i)
120 DATA -10,-9,1,11,10,9,-1,-11
130 RESTORE 1430
140 FOR i=11 TO 81 STEP 10
150 FOR j=i TO i+7:READ s(j)
160 END FOR i
170 PAPER 2:INK 7:WINDOW 448,200,32,16:CLS:CSIZE 1,0
180 score=0:nsa=0:nsd=0
190 INPUT "LEVEL?"!max_lev
200 CLS
210 AT 1,17:PRINT "   A B C D E F G H"
220 FOR i=1 TO 8:PRINT TO 17;i!FILL$(" .",16)
230 base_save=0:ts=1:move_no=0
240 plot_piece 44,-1:plot_piece 45,1:plot_piece 54,1:plot_piece 55,-1
250 REPeat move_no
260 AT 14,10:INPUT "Your move"!mv$
270 AT 16,10:CLS 3
280 IF mv$="!" THEN GO TO 400
290 IF LEN(mv$)<>2 THEN GO TO 380
300 m1=mv$(1) INSTR "12345678"
310 m2=mv$(2) INSTR "ABCDEFGH"
320 IF m1<1 OR m2<1 THEN GO TO 380
330 pos=m1*10+m2
340 IF board(pos)<>0 THEN GO TO 380
350 ts=0:base_save=0
360 score=-score:place_piece pos,-1,1:score=-score
370 IF valid THEN GO TO 400
380 PRINT "ERROR!"
390 GO TO 260
400 AT 14,10:CLS 3
410 BEEP 5000,10,20,1000,1
420 ts=0:tm=1:best_pos=0
430 FOR i=1 TO 15:ab(i)=-999999*(i MOD 2*2-1)
440 ret_score=check_board(1,-1,1,move_no)
450 BEEP 9000,0,10,1000,1
460 AT 16,10
470 IF best_pos=0 THEN PRINT "I can't move":GO TO 260
480 PRINT "I move"!CHR$(best_pos DIV 10+48);CHR$(best_pos MOD 10+64)
490 place_piece best_pos,1,-1
500 END REPeat move_no
510 DEFine FuNction check_board(side_a,side_d,level,move_no)
520 LOCal pos,base_save,mv,high_scr,score_save,base_move
530 base_save=ts:base_move=tm:score_save=score:high_scr=-999999
540 IF level=1 THEN PRINT #0,\TO 5;:ELSE PRINT #0," [";
550 FOR pos=11 TO 18,21 TO 28,31 TO 38,41 TO 48,51 TO 58,61 TO 68,71 TO 78,81 TO 88
560 IF board(pos)<>0 OR move_ok(pos)=0 THEN NEXT pos:GO TO 750
570 sc=0:ret_score=0
580 FOR i=1 TO 8
590 j=move_dir(i):IF board(pos+j)<>side_d THEN save_p(ts,i)=pos:NEXT i:GO TO 640
600 p=pos+j
610 REPeat k:sc=sc+2*s(p)+move_no:p=p+j:IF board(p)<>side_d THEN EXIT k
620 IF board(p)<>side_a THEN sc=ret_score:save_p(ts,i)=pos:NEXT i:GO TO 640
630 ret_score=sc:save_p(ts,i)=p-j
640 END FOR i
650 IF sc=0 THEN NEXT pos:GO TO 750
660 SELect ON pos
670 =12,21,22:IF board(11)=0 THEN sc=sc-300
680 =17,28,27:IF board(18)=0 THEN sc=sc-300
690 =71,82,72:IF board(81)=0 THEN sc=sc-300
700 =87,78,77:IF board(88)=0 THEN sc=sc-300
710 END SELect 
720 sc=score+sc+s(pos)+move_no:i=tm-1:save_p(ts,0)=pos
730 REPeat j:IF move_sc(i)>sc OR i<base_move THEN EXIT j:ELSE move_sc(i+1)=move_sc(i):move_list(i+1)=move_list(i):i=i-1
740 move_sc(i+1)=sc:move_list(i+1)=ts:tm=tm+1:ts=ts+1
750 END FOR pos
760 IF level<=max_lev THEN GO TO 790
770 IF tm>base_move THEN high_scr=move_sc(base_move):ELSE high_scr=-999999*side_a
780 tm=base_move:ts=base_save:PRINT #0," ]";:RETurn -high_scr
790 FOR mv=base_move TO tm-1
800 i=move_list(mv):pos=save_p(i,0):score=-move_sc(mv):board(pos)=side_a
810 PRINT #0,!(pos DIV 10)&"ABCDEFGH"(pos MOD 10);
820 FOR j=1 TO 8
830 FOR k=pos+move_dir(j) TO save_p(i,j) STEP move_dir(j):board(k)=side_a
840 move_ok(k)=move_ok(k)+1
850 END FOR j
860 ret_score=check_board(-side_a,-side_d,level+1,move_no+1)
870 FOR j=1 TO 8
880 FOR k=pos+move_dir(j) TO save_p(move_list(mv),j) STEP move_dir(j):board(k)=side_d
890 move_ok(k)=move_ok(k)-1
900 END FOR j
910 board(pos)=0:REMark PRINT #0,!ret_score;
920 IF ret_score>=ab(level) XOR level MOD 2 THEN high_scr=ret_score:PRINT #0," a]";:EXIT mv
930 IF ret_score<high_scr THEN NEXT mv:GO TO 1020
940 high_scr=ret_score:REMark PRINT #0,"x";
950 IF level>1 THEN NEXT mv:GO TO 1020
960 IF best_pos>0 THEN AT best_pos DIV 10+1,best_pos MOD 10*2+18:PRINT ".";
970 BEEP 500,pos:best_pos=pos
980 STRIP 0
990 AT best_pos DIV 10+1,best_pos MOD 10*2+18:PRINT ".";
1000 STRIP 2
1010 NEXT mv
1020 PRINT #0," ]";
1030 END FOR mv
1035 IF high_scr<ab(level) XOR level MOD 2 THEN ab(level)=high_scr
1040 tm=base_move:ts=base_save:score=score_save
1050 RETurn -high_scr
1060 END DEFine 
1070 DEFine PROCedure place_piece(pos,side_a,side_d)
1080 valid=0
1090 FOR i=-10,-9,1,11,10,9,-1,-11
1100 p=pos
1110 REPeat j:p=p+i:IF board(p)<>side_d THEN EXIT j
1120 IF board(p)<>side_a THEN NEXT i:GO TO 1140
1130 FOR j=pos+i TO p-i STEP i:plot_piece j,side_a:score=score+2*s(j)+move_no
1140 END FOR i
1150 IF NOT valid THEN RETurn 
1160 plot_piece pos,side_a:score=score+s(j)+move_no
1170 AT 11,7:PRINT "Number of 'X' ="!nsa;" ","Number of 'O' ="!nsd;" ";
1180 move_no=move_no+1
1190 IF nsa>0 AND nsd>0 AND nsa+nsd<64 THEN RETurn 
1200 PRINT:PRINT:PRINT:PRINT:PRINT:PRINT
1210 IF nsa>nsd THEN PRINT "You won"
1220 IF nsa<nsd THEN PRINT "I won"
1230 IF nsa=nsd THEN PRINT "We drew"
1240 STOP
1250 END DEFine 
1260 DEFine PROCedure plot_piece(pos,side_a)
1270 IF board(pos)<0 THEN nsa=nsa-1
1280 IF board(pos)>0 THEN nsd=nsd-1
1290 board(pos)=side_a:valid=1
1300 FOR k=pos-10,pos-9,pos+1,pos+11,pos+10,pos+9,pos-1,pos-11:move_ok(k)=move_ok(k)+1
1310 AT pos DIV 10+1,pos MOD 10*2+18:PRINT "X.O"(side_a+2)
1320 IF side_a<0 THEN nsa=nsa+1
1330 IF side_a>0 THEN nsd=nsd+1
1340 END DEFine 
1350 DATA 64,32,16, 8, 8,16,32,64
1360 DATA 32,16, 8, 4, 4, 8,16,32
1370 DATA 16, 8, 4, 2, 2, 4, 8,16
1380 DATA  8, 4, 2, 1, 1, 2, 4, 8
1390 DATA  8, 4, 2, 1, 1, 2, 4, 8
1400 DATA 16, 8, 4, 2, 2, 4, 8,16
1410 DATA 32,16, 8, 4, 4, 8,16,32
1420 DATA 64,32,16, 8, 8,16,32,64
1430 DATA 160,40,112,56,56,112,40,160
1440 DATA  40,10, 28,14,14, 28,10, 40
1450 DATA 112,28, 80,40,40, 80,28,112
1460 DATA  56,14, 40,20,20, 40,14, 56
1470 DATA  56,14, 40,20,20, 40,14, 56
1480 DATA 112,28, 80,40,40, 80,28,112
1490 DATA  40,10, 28,14,14, 28,10, 40
1500 DATA 160,40,112,56,56,112,40,160
