-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPCHESS32.BAS
More file actions
861 lines (838 loc) · 42.9 KB
/
Copy pathPCHESS32.BAS
File metadata and controls
861 lines (838 loc) · 42.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
' Modification of PANCHESS.BAS to run in QB64 or FreeBasic
' Only change was to rewrite the DEF FN()'s as Function calls
' Still works in Qbasic. For freebasic use: fbc pchess32.bas -lang qb
DECLARE FUNCTION GNA% (ZZ%)
DECLARE FUNCTION GNB% (ZZ%)
DECLARE FUNCTION GNC% (ZZ%)
DECLARE FUNCTION GND% (ZZ%)
DECLARE FUNCTION GNX1Y1% (ZZ%)
DECLARE FUNCTION GNX2Y2% (ZZ%)
DECLARE FUNCTION GNABCD% (AB%, CD%)
DECLARE FUNCTION GNCMT% (ZF%, ZT%)
DECLARE FUNCTION GNCBI% (ZWB%, ZF%, ZT%, ZK%)
DECLARE FUNCTION GNUP$ (C$)
DECLARE FUNCTION GNNN% (ZZ%)
DECLARE FUNCTION GNSS% (ZZ%)
DECLARE FUNCTION GNEE% (ZZ%)
DECLARE FUNCTION GNWW% (ZZ%)
DECLARE FUNCTION GNNE% (ZZ%)
DECLARE FUNCTION GNSE% (ZZ%)
DECLARE FUNCTION GNNW% (ZZ%)
DECLARE FUNCTION GNSW% (ZZ%)
DECLARE FUNCTION GNX% (ZZ%)
DECLARE FUNCTION GNY% (ZZ%)
10 REM PANDEMIC CHESS: DAVID JOHNSON (Sept. 2022) GW-BASIC
15 REM Copyright (c) 2026 David R. Johnson
17 REM Licensed under the MIT License
20 REM BOARD 11 21 31 41 ...
30 REM INDEX 12 22 32 42 ...
40 REM 13 23 33 43 ...
50 REM
60 REM MV(1,--) = CHESS MOVE, MV(2,--) = MOVE INFO, MV(3,--) = MOVE EVALUATION
70 REM CHESS MOVE: MXY=ABCD WHERE AB=FROM CD=TO
80 REM MOVE INFO (ABCD) A=1:2(W/B), B=BRD_VAL_FROM C=VAL_TO D=MOVE_TYPE
90 REM MOVE TYPE (D) WW/PROMOTE=1 WE=2 WB=3 ENPASS=4 BW=5 BE=6 BB/PROMOTE=7 KCASTLE=8 QCASTLE=9
100 REM ..WHERE WE=WHITE TO EMPTY, WW=WHITE TO WHITE WB=WHITE TO BLACK
110 REM
120 REM WCAST WCAST WHITE HAS CASTLED
130 REM BCAST BCAST BLACK HAS CASTLED
140 REM XCAST(1) WCAST21 WHITE KING MOVED (58)
150 REM XCAST(2) WCAST22 WK-ROOK MOVED (88)
160 REM XCAST(3) WCAST23 WQ-ROOK MOVED (18)
170 REM XCAST(4) BCAST21 BLACK KINGS MOVED (51)
180 REM XCAST(5) BCAST22 BK-ROOK MOVED (81)
190 REM XCAST(6) BCAST23 BQ-ROOK MOVED (11)
200 REM
210 REM XCHECK(1) WHITE KING IS CHECKED
220 REM XCHECK(2) SQUARES BETWEEN WK-ROOK ATTACKED
230 REM XCHECK(3) SQUARES BETWEEN WQ-ROOK ATTACHED
240 REM XCHECK(4) BLACK KING IS CHECKED
250 REM XCHECK(5) SQUARES BETWEEN BK-ROOK ATTACKED
260 REM XCHECK(6) SQUARES BETWEEN BQ-ROOK ATTACKED
270 REM
280 REM AFTER MOVE USE BCK(GL+1) OR WCK(GL+1) E.G., HALF SCAN AHEAD
290 REM AFTER SIMPLE SCAN USE XCHECK(1) AND XCHECK(4)
300 REM ------------------------------------------------------------
310 'CLEAR , , 2048: REM STACK SPACE FOR GWBASIC
320 DEFINT A-Z: REM ONLY INTEGERS!
330 REM === HELPER FUNCTIONS ===
340 'DEF FNX (ZZ) = INT(ZZ / 10): REM XY -> X
350 'DEF FNY (ZZ) = ZZ MOD (10): REM XY -> Y
360 'DEF FNA (ZZ) = INT(ZZ / 1000): REM ABCD -> A
370 'DEF FNB (ZZ) = INT(ZZ / 100) MOD (10): REM ABCD -> B
380 'DEF FNC (ZZ) = INT(ZZ / 10) MOD (10): REM ABCD -> C
390 'DEF FND (ZZ) = ZZ MOD (10): REM ABCD -> D
400 'DEF FNX1Y1 (ZZ) = INT(ZZ / 100): REM ABCD -> AB
410 'DEF FNX2Y2 (ZZ) = ZZ MOD (100): REM ABCD -> CD
420 'DEF FNABCD (AB, CD) = AB * 100 + CD: REM AB, CD -> ABCD
430 'DEF FNCMT (ZF, ZT) = 2 * SGN(ZF) + SGN(ZT) + 4: REM MOVE TYPE
440 'DEF FNCBI (ZWB, ZF, ZT, ZK) = ZWB * 1000 + 100 * ABS(ZF) + 10 * ABS(ZT) + ZK: REM MOVE INFO
450 'DEF FNUP$ (C$) = CHR$(ASC(C$) - 32 * (ASC(C$) > 96) * (ASC(C$) < 123))
460 'DEF FNNN (ZZ) = ZZ - 1: DEF FNSS (ZZ) = ZZ + 1
470 'DEF FNEE (ZZ) = ZZ + 10: DEF FNWW (ZZ) = ZZ - 10
480 'DEF FNNE (ZZ) = ZZ + 9: DEF FNSE (ZZ) = ZZ + 11
490 'DEF FNNW (ZZ) = ZZ - 11: DEF FNSW (ZZ) = ZZ - 9
500 REM
510 DIM B(99), QB(99), XQB(99), CMD(99), TPAWN(99), TKN(99), TBISHOP(99), TROOK(99), TQUEEN(99), TKMID(99)
520 DIM XCAST(6), XCHECK(6), ZCAST(6), ZCHECK(6), ECOUNT(10), EKING(99), EPAWN(99), EROOK(99)
530 DIM MV(250, 30), LV(10), GT(10), ALPHA(10), BETA(10), ABCUT(10), WPT(10), BPT(10), WCK(10), BCK(10): REM MV(I, 3*DEPTH)
540 DIM SWB(2), CRANK(2), MEP(3), CPVAL(14), OM$(15)
550 FOR II = 1 TO 6: XCAST(II) = 0: XCHECK(6) = 0: NEXT II
560 SELF0 = 1: FENCE = 7: WHITE = -1: BLACK = 1: ENPASS = 9: WCAST = 0: BCAST = 0: GMOVE = 1: GMX = 0: KEEPIT = 0
570 BIG = 1: SMALL = -1: PINF = 25000: REM ALPHA/BETA CONSTANTS
580 LV(1) = 0: LV(2) = 3: LV(3) = 6: LV(4) = 9: LV(5) = 12: LV(6) = 15: LV(7) = 18: LV(8) = 21: LV(9) = 24: LV(10) = 27
590 SWB(1) = -1: SWB(2) = 1: CRANK(1) = 8: CRANK(2) = 1: MEP(1) = 1114: MEP(3) = 2114
600 CP$ = "KQRBNP.pnbrqk": CP2$ = "KQRBNP.onbrqk": CP3$ = "KQRBNP.123456": AI = BLACK: HUMAN = WHITE
610 CPVAL(1) = -1800: CPVAL(2) = -900: CPVAL(3) = -500: CPVAL(4) = -330: CPVAL(5) = -320: CPVAL(6) = -100: CPVAL(7) = 0
620 CPVAL(8) = 100: CPVAL(9) = 320: CPVAL(10) = 330: CPVAL(11) = 500: CPVAL(12) = 900: CPVAL(13) = 1800
630 EGAM = 45: MOPX = 22: PDEPTH = 4: MDEPTH = PDEPTH: REM END-GAME AND MOPUP LIMITS
640 AXY = 0: BXY = 0: CXY = 0: DFLAG = 0: ZKEEP = 0
650 XTUNE = 6: ETUNE = 5: TTUNE = 15: REM HOW QUIESCENT SEARCH IS SCORED (MIDDLE AND END GAME).
660 REM CHESS BOARD
670 FOR JJ = 1 TO 8: FOR II = 1 TO 8
680 READ B(II * 10 + JJ)
690 NEXT II: NEXT JJ
700 DATA 4,2,3,5,6,3,2,4,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0
710 DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1
720 DATA -1,-1,-1,-1,-4,-2,-3,-5,-6,-3,-2,-4
730 REM FENCE AROUND BOARD FOR MOVE CONTAINMENT
740 FOR II = 0 TO 9
750 B(0 + II) = FENCE: B(90 + II) = FENCE
760 B(II * 10 + 0) = FENCE: B(II * 10 + 9) = FENCE
770 NEXT II
780 REM
790 REM values from https://www.chessprogramming.org/Simplified_Evaluation_Function
800 REM PAWN TABLE VALUES (Tomasz Michniewksi simplified)
810 DATA 0,0,0,0,0,0,0,0,50,50,50,50,50,50,50,50,10,10,20,30,30,20,10,10,5,5,10,25,25,10,5,5
820 DATA 0,0,0,20,20,0,0,0,5,-5,-10,0,0,-10,-5,5,5,10,10,-20,-20,10,10,5,0,0,0,0,0,0,0,0
830 FOR JJ = 1 TO 8: FOR II = 1 TO 8: READ TPAWN(II * 10 + JJ): NEXT II: NEXT JJ
840 REM
850 REM KNIGHT TABLE VALUES (Tomasz Michniewksi simplified)
860 DATA -50,-40,-30,-30,-30,-30,-40,-50,-40,-20,0,0,0,0,-20,-40,-30,0,10,15,15,10,0,-30
870 DATA -30,5,15,20,20,15,5,-30,-30,0,15,20,20,15,0,-30,-30,5,10,15,15,11,5,-30
880 DATA -40,-20,0,5,5,0,-20,-40,-50,-40,-30,-30,-30,-30,-40,-50
890 FOR JJ = 1 TO 8: FOR II = 1 TO 8: READ TKN(II * 10 + JJ): NEXT II: NEXT JJ
900 REM
910 REM BISHOP TABLE VALUES (Tomasz Michniewksi simplified)
920 DATA -20,-10,-10,-10,-10,-10,-10,-20,-10,0,0,0,0,0,0,-10,-10,0,5,10,10,5,0,-10
930 DATA -10,5,5,10,10,5,5,-10,-10,0,10,10,10,10,0,-10,-10,10,10,10,10,10,10,-10
940 DATA -10,5,0,0,0,0,5,-10,-20,-10,-10,-10,-10,-10,-10,-20
950 FOR JJ = 1 TO 8: FOR II = 1 TO 8: READ TBISHOP(II * 10 + JJ): NEXT II: NEXT JJ
960 REM
970 REM ROOK TABLE VALUES (Tomasz Michniewksi simplified)
980 DATA 0,0,0,0,0,0,0,0,5,10,10,10,10,10,10,5,-5,0,0,0,0,0,0,-5
990 DATA -5,0,0,0,0,0,0,-5,-5,0,0,0,0,0,0,-5,-5,0,0,0,0,0,0,-5
1000 DATA -5,0,0,0,0,0,0,-5,0,0,0,5,5,0,0,0
1010 FOR JJ = 1 TO 8: FOR II = 1 TO 8: READ TROOK(II * 10 + JJ): NEXT II: NEXT JJ
1020 REM
1030 REM QUEEN TABLE VALUES (Tomasz Michniewksi simplified)
1040 DATA -20,-10,-10,-5,-5,-10,-10,-20,-10,0,0,0,0,0,0,-10,-10,0,5,5,5,5,0,-10
1050 DATA -5,0,5,5,5,5,0,-5,0,0,5,5,5,5,0,-5,-10,5,5,5,5,5,0,-10
1060 DATA -10,0,5,0,0,0,0,-10,-20,-10,-10,-5,-5,-10,-10,-20
1070 FOR JJ = 1 TO 8: FOR II = 1 TO 8: READ TQUEEN(II * 10 + JJ): NEXT II: NEXT JJ
1080 REM
1090 REM KING MIDDLE GAME (Tomasz Michniewksi simplified E2=-60)
1100 DATA -30,-40,-40,-50,-50,-40,-40,-30,-30,-40,-40,-50,-50,-40,-40,-30,-30,-40,-40,-50,-50,-40,-40,-30
1110 DATA -30,-40,-40,-50,-50,-40,-40,-30,-20,-30,-30,-40,-40,-30,-30,-20,-20,-20,-20,-20,-20,-20,-20,-10
1120 DATA 20,20,0,0,-60,0,20,20,20,30,10,0,0,10,30,20
1130 FOR JJ = 1 TO 8: FOR II = 1 TO 8: READ TKMID(II * 10 + JJ): NEXT II: NEXT JJ
1140 REM ===============
1150 REM END KING (Tomasz Michniewksi simplified)
1160 DATA -50,-40,-30,-20,-20,-30,-40,-50,-30,-20,-10,0,0,-10,-20,-30,-30,-10,20,30,30,20,-10,-30
1170 DATA -30,-10,30,40,40,30,-10,-30,-30,-10,30,40,40,30,-10,-30,-30,-10,20,30,30,20,-10,-30
1180 DATA -30,-30,0,0,0,0,-30,-30,-50,-30,-30,-30,-30,-30,-30,-50
1190 FOR JJ = 1 TO 8: FOR II = 1 TO 8: READ EKING(II * 10 + JJ): NEXT II: NEXT JJ
1200 REM ===============
1210 REM END PAWN (PESTO pawn endgame * 1.5)
1220 DATA 0,0,0,0,0,0,0,0,267,260,237,201,221,198,248,281,141,128,85,100,84,80,128,126
1230 DATA 48,36,20,8,-3,5,26,26,20,14,-5,-11,-11,-12,5,-2,6,11,-9,2,0,-8,-2,-12
1240 DATA 20,12,12,15,20,0,3,-11,0,0,0,0,0,0,0,0
1250 FOR JJ = 1 TO 8: FOR II = 1 TO 8: READ EPAWN(II * 10 + JJ): NEXT II: NEXT JJ
1260 REM ===============
1270 REM END ROOK (PESTO rook endgame * 1.5)
1280 DATA 20,15,27,23,18,18,12,8,17,20,20,17,-5,5,12,5,11,11,11,8,6,-5,-8,-5
1290 DATA 6,5,20,2,3,2,-2,3,5,8,12,6,-8,-9,-12,-17,-6,0,-8,-2,-11,-18,-12,-24
1300 DATA -9,-9,0,3,-14,-14,-17,-5,-14,3,5,-2,-8,-20,6,-30
1310 FOR JJ = 1 TO 8: FOR II = 1 TO 8: READ EROOK(II * 10 + JJ): NEXT II: NEXT JJ
1320 REM ===============
1330 REM CENTRAL MANHATTAN DISTANCE (MOP-UP GAME)
1340 DATA 6,5,4,3,3,4,5,6,5,4,3,2,2,3,4,5,4,3,2,1,1,2,3,4,3,2,1,0,0,1,2,3
1350 DATA 3,2,1,0,0,1,2,3,4,3,2,1,1,2,3,4,5,4,3,2,2,3,4,5,6,5,4,3,3,4,5,6
1360 FOR JJ = 1 TO 8: FOR II = 1 TO 8: READ CMD(II * 10 + JJ): NEXT II: NEXT JJ
1370 REM
1380 REM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1390 PRINT : PRINT " *** PANDEMIC CHESS ***": PRINT
1400 INPUT " SAVE OUTPUT TO FILE (1=YES) ", KEEPIT: REM SAVE GAME OUTPUT FOR STUDY
1410 IF KEEPIT = 1 THEN INPUT " FILENAME: ", NM$: OPEN NM$ FOR OUTPUT AS #2: PRINT
1420 INPUT " USE OPENING BOOK MOVES (1=YES) ", OBM: IF OBM <> 1 THEN OBM = 0
1430 IF OBM = 1 THEN PRINT " USING THE OPENING BOOK " : RANDOMIZE
1440 INPUT " PLAY AS BLACK (1=YES) ", ZZ
1450 IF ZZ = 1 THEN B(55) = -1: B(57) = 0: AI = WHITE: HUMAN = BLACK:
1460 IF KEEPIT = 1 AND ZZ = 1 THEN PRINT #2, "E2E4 COMPUTER PLAYS WHITE"
1470 IF KEEPIT = 1 AND ZZ <> 1 THEN PRINT #2, "COMPUTER PLAYS BLACK"
1480 PRINT : PRINT " NOTE MOVES ENTERED AS E2E4 -AND- TO CASTLE USE E1G1 NOTATION"
1490 GOSUB 7420: REM SAVE BOARD FOR BACK OPTION
1500 REM ============== MAIN LOOP ===================================
1510 REM SET THE PLAYERS
1520 SELF0 = AI: P1$ = "WHITE": P2$ = "BLACK": REM AI PLAYS BLACK
1530 IF AI = WHITE THEN P1$ = "BLACK": P2$ = "WHITE": REM AI PLAYS WHITE
1540 GOSUB 1920: REM DISPLAY BOARD
1550 REM ===PLAYER'S TURN===
1560 FOR II = 1 TO 6: XCHECK(II) = 0: NEXT II: REM CLEAR CASTLING FLAGS STUFF
1570 GOSUB 2340: HUMAN$ = AA$: REM GET PLAYER'S INPUT
1580 GOSUB 2610: REM MAKE THE MOVE FOR THE PLAYER
1590 REM ....MAKE SURE KING IS NOT ATTACKED.........
1600 IF ZFLAG = 1 THEN PRINT " YOU ARE IN CHECK!" ELSE GOTO 1650
1610 SELF0 = -SELF0: ZDEPTH = MDEPTH: MDEPTH = 2: REM SO CHECK IS IT MATE?
1620 GOSUB 6250: SELF0 = -SELF0: MDEPTH = ZDEPTH: REM LET'S CHECK THE MOVE
1630 IF GMX = 1 THEN 1760 ELSE GOTO 1520: REM HAVE A CHECKMATE!!
1640 REM ...........................................
1650 GOSUB 1810: REM SET CASTLING FLAGS FOR HUMAN
1660 REM ===COMPUTER'S (AI) TURN===
1670 GOSUB 6250: IF GMX = 1 THEN 1760: REM AI MAKES MOVES RETURNING MX, MXY
1680 ZZ = MXY: GOSUB 2220: AI$ = AA$: REM CONVERT TO STANDARD CHESS BOARD
1690 PRINT P1$; " "; HUMAN$: PRINT P2$; " "; AI$: REM SHOW THE MOVES
1700 IF KEEPIT = 1 THEN PRINT #2, HUMAN$; " "; AI$; " "; : ZKEEP = ZKEEP + 1
1710 IF ZKEEP > 6 THEN PRINT #2, " ": ZKEEP = 0
1720 MINDEX = MX: GOSUB 2610: REM DO COMPUTER'S MOVE (UPDATE THE BOARD)
1730 GOSUB 1810: REM SET CASTLING FLAGS FOR AI
1740 REM ===NEXT MOVE===
1750 GMOVE = GMOVE + 1: GOTO 1520: REM REPEAT
1760 GOSUB 1920: INPUT "GAME OVER HIT RETURN",AA$
1770 IF KEEPIT = 1 THEN CLOSE #2:
1780 END: REM BYE!
1790 REM ========================================================
1800 REM ===PLAYER'S CASTLING FLAGS=============================
1810 MXY = MV(MINDEX, 1 + LV(GL)): XY = GNX1Y1(MXY)
1820 XTO = GNX2Y2(MXY): REM XFROM = GNX1Y1(MXY)
1830 IF B(XTO) = -6 THEN XCAST(1) = 1: WCAST = 1
1840 IF XY = 88 THEN XCAST(2) = 1
1850 IF XY = 18 THEN XCAST(3) = 1
1860 IF B(XTO) = 6 THEN XCAST(4) = 1: BCAST = 1
1870 IF XY = 81 THEN XCAST(5) = 1
1880 IF XY = 11 THEN XCAST(6) = 1
1890 RETURN: REM ==============================================
1900 REM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1910 REM ===DISPLAY BOARD===
1920 GMT = 0: WMT = 0: BMT = 0: PRINT
1930 PRINT " A B C D E F G H COMMANDS= DEPTH SWAP LOAD EDIT SUGGEST"
1940 PRINT " ================= XMOVE BACK WHITE BLACK CLEAR SAVE QUIT"
1950 FOR JJ = 1 TO 8: PRINT 9 - JJ;
1960 FOR II = 1 TO 8
1970 PRINT CHR$(32) + MID$(CP2$, B(II * 10 + JJ) + 7, 1);
1980 REM Print B(II * 10 + JJ);
1990 GMT = GMT + ABS(B(II * 10 + JJ))
2000 IF SGN(B(II * 10 + JJ)) = WHITE THEN WMT = WMT + B(II * 10 + JJ) ELSE BMT = BMT + B(II * 10 + JJ)
2010 NEXT II: PRINT CHR$(32); 9 - JJ
2020 NEXT JJ
2030 REM ===SET GAMPLAY DEPTH BASED ON MATERIAL===
2040 IF DFLAG = 1 THEN DFLAG = 0: GOTO 2100
2050 MDEPTH = PDEPTH
2060 IF GMT < EGAM THEN MDEPTH = PDEPTH + 1
2070 IF GMT < EGAM - 4 THEN TTUNE = 50
2080 IF GMT < MOPX THEN MDEPTH = PDEPTH + 2
2090 IF MDEPTH > 8 THEN MDEPTH = 8
2100 PRINT " ================= MOVE BOARD WHITE BLACK DEPTH"
2110 PRINT " A B C D E F G H ", GMOVE; " "; GMT; " "; ABS(WMT); " "; BMT; " "; MDEPTH
2120 PRINT : PRINT
2130 REM ===CASTLING FLAGS FROM BOARD CONFIG===
2140 IF B(58) <> -6 THEN XCAST(1) = 1: WCAST = 1
2150 IF B(88) <> -4 THEN XCAST(2) = 1
2160 IF B(18) <> -4 THEN XCAST(3) = 1
2170 IF B(51) <> 6 THEN XCAST(4) = 1: BCAST = 1
2180 IF B(81) <> 4 THEN XCAST(5) = 1
2190 IF B(11) <> 4 THEN XCAST(6) = 1
2200 RETURN
2210 REM === OUTPUT; INTEGER TO STRING: ZZ -> AA$ ====
2220 QA = GNA(ZZ) + 64: QB2 = 9 - GNB(ZZ) + 48
2230 QC = GNC(ZZ) + 64: QD = 9 - GND(ZZ) + 48
2240 AA$ = CHR$(QA) + CHR$(QB2) + CHR$(QC) + CHR$(QD)
2250 RETURN
2260 REM
2270 REM == INPUT; STRING TO INTEGER: AA$ -> ZZ ====
2280 FOR J = 1 TO LEN(AA$): MID$(AA$, J, 1) = GNUP$(MID$(AA$, J, 1)): NEXT
2290 V1 = ASC(MID$(AA$, 1, 1)) - 64: V2 = 57 - ASC(MID$(AA$, 2, 1))
2300 W1 = ASC(MID$(AA$, 3, 1)) - 64: W2 = 57 - ASC(MID$(AA$, 4, 1))
2310 ZZ = V1 * 1000 + V2 * 100 + W1 * 10 + W2
2320 RETURN
2330 REM ================INPUT AND PLAY=============================!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2340 GL = 1: TRY = 0: GOSUB 2960: REM SCAN THE BOARD
2350 PRINT GMOVE; ") "; P1$; : INPUT " TO MOVE ", A9$: IF LEN(A9$) < 4 THEN 2350
2360 A9$ = LEFT$(A9$, 4)
2370 FOR J = 1 TO LEN(A9$): MID$(A9$, J, 1) = GNUP$(MID$(A9$, J, 1)): NEXT
2380 REM ===AN UGLY MENU===============================
2390 IF A9$ = "QUIT" OR A9$ = "EXIT" THEN 1760
2400 IF A9$ = "BOAR" THEN GOSUB 1920: GOTO 2350
2410 IF A9$ = "SUGG" THEN GOSUB 5030: GOTO 2350
2420 IF A9$ = "DEPT" THEN GOSUB 5120: GOTO 2350
2430 IF A9$ = "CLEA" THEN GOSUB 4730: GOTO 2530
2440 IF A9$ = "SAVE" THEN GOSUB 4810: GOTO 2530
2450 IF A9$ = "LOAD" THEN GOSUB 4910: GOTO 2530
2460 IF A9$ = "SWAP" THEN GOSUB 4570: GOTO 2530
2470 IF A9$ = "BACK" THEN GOSUB 7380: GOTO 2530
2480 IF A9$ = "XMOV" THEN GOSUB 7460: GOTO 2530
2490 IF A9$ = "EDIT" THEN GOSUB 4660: GL = 1: GOSUB 2960: GOTO 2530
2500 IF A9$ = "WHIT" THEN AI = BLACK: HUMAN = WHITE: SELF0 = AI: P1$ = "WHITE": P2$ = "BLACK": GOTO 2530
2510 IF A9$ = "BLAC" THEN AI = WHITE: HUMAN = BLACK: SELF0 = AI: P1$ = "BLACK": P2$ = "WHITE": GOTO 2530
2520 GOTO 2550
2530 GOSUB 1920: GOTO 2350: REM DISPLAY BOARD AND REPEAT
2540 REM ================================================
2550 AA$ = A9$: REM HAVE MOVE AND NOT A MENU ITEM
2560 GOSUB 2270: MXY = ZZ: REM GET THE MOVE HUMAN PLAYER
2570 GOSUB 4510: IF MINDEX = 0 THEN PRINT " ---INVALID MOVE---": PRINT : GOTO 2350: REM SEE IF MOVE MXY IS VALID
2580 XY = GNX1Y1(MXY): IF SGN(B(XY)) <> HUMAN THEN PRINT "WRONG COLOR": GOTO 2350
2590 GOSUB 7420: RETURN: REM ===== NOW HAS USER INPUT IN TERM OF MINDEX ======
2600 REM ======MINDEX: NOW DO THE MOVE (USER OR COMPUTER)=========
2610 ZFLAG = 0
2620 MXY = MV(MINDEX, 1 + LV(GL)): XFROM = GNX1Y1(MXY): ZCPF = B(XFROM): ZCPS = SGN(B(XFROM))
2630 GOSUB 2900: REM CLEAR ENPASS FLAGS
2640 MINFO = MV(MINDEX, 2 + LV(GL)): MWB = GNA(MINFO): MTYPE = GND(MINFO)
2650 XTO = GNX2Y2(MXY): X1 = GNX(XFROM): Y1 = GNY(XFROM): X2 = GNX(XTO): Y2 = GNY(XTO)
2660 B(XTO) = B(XFROM): B(XFROM) = 0
2670 IF MTYPE = 8 THEN B(60 + CRANK(MWB)) = 4 * SWB(MWB): B(80 + CRANK(MWB)) = 0: IF MWB = 1 THEN XCAST(1) = 1 ELSE XCAST(4) = 1: REM CAST KING SIDE
2680 IF MTYPE = 9 THEN B(40 + CRANK(MWB)) = 4 * SWB(MWB): B(10 + CRANK(MWB)) = 0: IF MWB = 1 THEN XCAST(1) = 1 ELSE XCAST(4) = 1: REM CAST QUEEN SIDE
2690 IF MTYPE = 4 AND Y1 = 4 THEN EXY = GNSS(GNX2Y2(MXY)): B(EXY) = 0: GOTO 2780: REM DO ENPASSE
2700 IF MTYPE = 4 AND Y1 = 5 THEN EXY = GNNN(GNX2Y2(MXY)): B(EXY) = 0: GOTO 2780: REM DO ENPASSE
2710 IF MTYPE = 6 AND Y1 = 2 AND Y2 = 4 AND B(XTO) = 1 THEN B(X1 * 10 + 0) = ENPASS: GOTO 2780: REM ENPASSE-SETUP
2720 IF MTYPE = 2 AND Y1 = 7 AND Y2 = 5 AND B(XTO) = -1 THEN B(X1 * 10 + 9) = ENPASS: GOTO 2780: REM ENPASSE-SETUP
2730 IF MTYPE = 6 AND Y2 = 8 AND B(XTO) = 1 THEN B(XTO) = 5: GOTO 2780: REM BLACK PAWN PROMOTION
2740 IF MTYPE = 2 AND Y2 = 1 AND B(XTO) = -1 THEN B(XTO) = -5: GOTO 2780: REM WHITE PAWN PROMOTION
2750 IF MTYPE = 5 AND Y2 = 8 AND B(XTO) = 1 THEN B(XTO) = 5: GOTO 2780: REM BLACK PAWN PROMOTION
2760 IF MTYPE = 3 AND Y2 = 1 AND B(XTO) = -1 THEN B(XTO) = -5: REM WHITE PAWN PROMOTION
2770 REM
2780 IF ZCPF = -6 THEN XCAST(1) = 1
2790 IF XFROM = 88 THEN XCAST(2) = 1
2800 IF XFROM = 18 THEN XCAST(3) = 1
2810 IF ZCPF = 6 THEN XCAST(4) = 1
2820 IF XFROM = 81 THEN XCAST(5) = 1
2830 IF XFROM = 11 THEN XCAST(6) = 1
2840 UXY = MXY: UINFO = MINFO: REM GoSub 5430
2850 GL = GL + 1: GOSUB 2960: REM SCAN AFTER THE MOVE
2860 IF ZCPS = WHITE AND WCK(GL) <> 0 THEN GOSUB 5780: ZFLAG = 1
2870 IF ZCPS = BLACK AND BCK(GL) <> 0 THEN GOSUB 5780: ZFLAG = 1
2880 GL = GL - 1: REM CURRENT STACK LAYER
2890 RETURN
2900 REM ============CLEAR EN-PASSANT FLAGS==============
2910 FOR II = 1 TO 8: B(II * 10) = FENCE: NEXT II: REM BLACK
2920 REM
2930 FOR II = 1 TO 8: B(II * 10 + 9) = FENCE: NEXT II: REM WHITE
2940 RETURN
2950 REM ==============SCAN BOARD==========================
2960 GT(GL) = 0: WPT(GL) = 0: BPT(GL) = 0: WCK(GL) = 0: BCK(GL) = 0: ECOUNT(GL) = 0: ZCOUNT = 0
2970 FOR II = 1 TO 6: XCHECK(II) = 0: NEXT II
2980 B(1) = FENCE: B(9) = FENCE: REM CLEAR CHECK FLAG
2990 FOR II = 1 TO 8: FOR JJ = 1 TO 8
3000 XY = 10 * II + JJ
3010 IF B(XY) = -6 THEN WKING = XY: GOTO 3040
3020 IF B(XY) = 6 THEN BKING = XY: GOTO 3040
3030 GOSUB 3090
3040 NEXT JJ: NEXT II
3050 XY = WKING: GOSUB 3090
3060 XY = BKING: GOSUB 3090
3070 RETURN
3080 REM ==================================================
3090 CPF = B(XY): CPS = SGN(CPF)
3100 ON ABS(CPF) GOSUB 3140, 3370, 3600, 3740, 3880, 3910
3110 RETURN
3120 REM ==================================================
3130 REM ===MOVE PAWN===
3140 XY1 = XY: ZX = GNX(XY): ZY = GNY(XY)
3150 IF CPS = WHITE THEN 3160 ELSE GOTO 3240
3160 XY2 = GNNN(XY): IF B(XY2) <> 0 THEN 3190
3170 GOSUB 4240: REM -WHITE-
3180 XY2 = GNNN(XY2): IF ZY = 7 AND B(XY2) = 0 THEN GOSUB 4240
3190 XY2 = GNNE(XY): IF SGN(B(XY2)) = BLACK THEN GOSUB 4240
3200 XY2 = GNNW(XY): IF SGN(B(XY2)) = BLACK THEN GOSUB 4240
3210 EXY = GNEE(XY): IF B(EXY) = 1 AND ZY = 4 AND B(GNX(EXY) * 10) = ENPASS THEN ETXY = GNNE(XY): GOSUB 3330
3220 EXY = GNWW(XY): IF B(EXY) = 1 AND ZY = 4 AND B(GNX(EXY) * 10) = ENPASS THEN ETXY = GNNW(XY): GOSUB 3330
3230 GOTO 3310
3240 XY2 = GNSS(XY): IF B(XY2) <> 0 THEN 3270
3250 GOSUB 4240: REM -BLACK-
3260 XY2 = GNSS(XY2): IF ZY = 2 AND B(XY2) = 0 THEN GOSUB 4240
3270 XY2 = GNSE(XY): IF SGN(B(XY2)) = WHITE THEN GOSUB 4240
3280 XY2 = GNSW(XY): IF SGN(B(XY2)) = WHITE THEN GOSUB 4240
3290 EXY = GNEE(XY): IF B(EXY) = -1 AND ZY = 5 AND B(GNX(EXY) * 10 + 9) = ENPASS THEN ETXY = GNSE(XY): GOSUB 3330
3300 EXY = GNWW(XY): IF B(EXY) = -1 AND ZY = 5 AND B(GNX(EXY) * 10 + 9) = ENPASS THEN ETXY = GNSW(XY): GOSUB 3330
3310 RETURN
3320 REM ===EN-PASSANT===
3330 GT(GL) = GT(GL) + 1
3340 MV(GT(GL), 1 + LV(GL)) = GNABCD(XY, ETXY): MV(GT(GL), 2 + LV(GL)) = MEP(CPS + 2)
3350 RETURN
3360 REM ==MOVE KNIGHT===
3370 XY1 = XY
3380 XY = GNNN(XY): IF B(XY) >= FENCE THEN 3420
3390 XY = GNNN(XY): IF B(XY) >= FENCE THEN 3420
3400 XY2 = GNEE(XY): GOSUB 4240
3410 XY2 = GNWW(XY): GOSUB 4240
3420 XY = XY1
3430 XY = GNEE(XY): IF B(XY) >= FENCE THEN 3470
3440 XY = GNEE(XY): IF B(XY) >= FENCE THEN 3470
3450 XY2 = GNNN(XY): GOSUB 4240
3460 XY2 = GNSS(XY): GOSUB 4240
3470 XY = XY1
3480 XY = GNSS(XY): IF B(XY) >= FENCE THEN 3520
3490 XY = GNSS(XY): IF B(XY) >= FENCE THEN 3520
3500 XY2 = GNEE(XY): GOSUB 4240
3510 XY2 = GNWW(XY): GOSUB 4240
3520 XY = XY1
3530 XY = GNWW(XY): IF B(XY) >= FENCE THEN 3570
3540 XY = GNWW(XY): IF B(XY) >= FENCE THEN 3570
3550 XY2 = GNNN(XY): GOSUB 4240
3560 XY2 = GNSS(XY): GOSUB 4240
3570 XY = XY1
3580 RETURN
3590 REM ===MOVE BISHOP===
3600 XY1 = XY: XY2 = XY
3610 XY2 = GNNE(XY2): GOSUB 4240: REM -NORTH EAST-
3620 IF CPT = 0 THEN 3610
3630 XY2 = XY1
3640 XY2 = GNSE(XY2): GOSUB 4240: REM -SOUTH EAST-
3650 IF CPT = 0 THEN 3640
3660 XY2 = XY1
3670 XY2 = GNNW(XY2): GOSUB 4240: REM -NORTH WEST-
3680 IF CPT = 0 THEN 3670
3690 XY2 = XY1
3700 XY2 = GNSW(XY2): GOSUB 4240: REM -SOWTH WEST-
3710 IF CPT = 0 THEN 3700
3720 RETURN
3730 REM ===MOVE ROOK===
3740 XY1 = XY: XY2 = XY
3750 XY2 = GNNN(XY2): GOSUB 4240: REM -NORTH-
3760 IF CPT = 0 THEN 3750
3770 XY2 = XY1
3780 XY2 = GNSS(XY2): GOSUB 4240: REM -SOUTH-
3790 IF CPT = 0 THEN 3780
3800 XY2 = XY1
3810 XY2 = GNEE(XY2): GOSUB 4240: REM -EAST-
3820 IF CPT = 0 THEN 3810
3830 XY2 = XY1
3840 XY2 = GNWW(XY2): GOSUB 4240: REM -WEST-
3850 IF CPT = 0 THEN 3840
3860 RETURN
3870 REM ===MOVE QUEEN===
3880 GOSUB 3600: GOSUB 3740: REM BISHOP + ROOK
3890 RETURN
3900 REM ===MOVE KING===
3910 XY1 = XY
3920 XY2 = GNNN(XY): GOSUB 4240
3930 XY2 = GNSS(XY): GOSUB 4240
3940 XY2 = GNEE(XY): GOSUB 4240
3950 XY2 = GNWW(XY): GOSUB 4240
3960 XY2 = GNNE(XY): GOSUB 4240
3970 XY2 = GNSE(XY): GOSUB 4240
3980 XY2 = GNNW(XY): GOSUB 4240
3990 XY2 = GNSW(XY): GOSUB 4240
4000 IF (WCAST + XCAST(1) + XCAST(2) + XCHECK(1) + XCHECK(2)) = 0 AND XY = 58 THEN GOSUB 4060
4010 IF (WCAST + XCAST(1) + XCAST(3) + XCHECK(1) + XCHECK(3)) = 0 AND XY = 58 THEN GOSUB 4100: GOTO 4040
4020 IF (BCAST + XCAST(4) + XCAST(5) + XCHECK(4) + XCHECK(5)) = 0 AND XY = 51 THEN GOSUB 4150
4030 IF (BCAST + XCAST(4) + XCAST(6) + XCHECK(4) + XCHECK(6)) = 0 AND XY = 51 THEN GOSUB 4190
4040 RETURN
4050 REM ===CASTLE WHITE===
4060 IF B(68) = 0 AND B(78) = 0 AND B(88) = -4 THEN 4070 ELSE GOTO 4090
4070 GT(GL) = GT(GL) + 1
4080 MV(GT(GL), 1 + LV(GL)) = 5878: MV(GT(GL), 2 + LV(GL)) = 1608
4090 RETURN
4100 IF B(48) = 0 AND B(38) = 0 AND B(28) = 0 AND B(18) = -4 THEN 4110 ELSE GOTO 4130
4110 GT(GL) = GT(GL) + 1
4120 MV(GT(GL), 1 + LV(GL)) = 5838: MV(GT(GL), 2 + LV(GL)) = 1609
4130 RETURN
4140 REM ===CASTLE BLACK===
4150 IF B(61) = 0 AND B(71) = 0 AND B(81) = 4 THEN 4160 ELSE GOTO 4180
4160 GT(GL) = GT(GL) + 1
4170 MV(GT(GL), 1 + LV(GL)) = 5171: MV(GT(GL), 2 + LV(GL)) = 2608
4180 RETURN
4190 IF B(41) = 0 AND B(31) = 0 AND B(21) = 0 AND B(11) = 4 THEN 4200 ELSE GOTO 4220
4200 GT(GL) = GT(GL) + 1
4210 MV(GT(GL), 1 + LV(GL)) = 5131: MV(GT(GL), 2 + LV(GL)) = 2609
4220 RETURN
4230 REM ===IDENTIFY MOVE===
4240 CPT = B(XY2): IF ABS(CPT) > 6 THEN 4490: REM NOT A CHESS PIECE
4250 MTYPE = GNCMT(CPF, CPT): IF MTYPE = 1 OR MTYPE = 7 THEN 4490: REM WHITE TO WHITE OR B2B
4260 GT(GL) = GT(GL) + 1: REM TO EMPY SPACE OR CAPTURE
4270 IF CPS = WHITE THEN WPT(GL) = WPT(GL) + 1: CWB = 1 ELSE BPT(GL) = BPT(GL) + 1: CWB = 2: REM COUNT MOVES
4280 MINFO = GNCBI(CWB, CPF, CPT, MTYPE)
4290 CMOVE = GNABCD(XY1, XY2)
4300 REM ---DOES THE MOVE CAPTURE A KING?. STORE B(0,1) B(09)---
4310 IF MTYPE = 3 AND CPT = 6 THEN B(1) = CMOVE: BCK(GL) = CMOVE: XCHECK(4) = 1: REM WHITE TAKES BLK KING
4320 IF MTYPE = 5 AND CPT = -6 THEN B(9) = CMOVE: WCK(GL) = CMOVE: XCHECK(1) = 1: REM BLACK TAKES WHT KING
4330 REM --------------------
4340 IF WCAST = 1 THEN 4400: REM WHITE HAS ALREADY CASTLED
4350 IF MTYPE = 6 AND XY2 = 78 THEN XCHECK(2) = 1: REM WHITE KING CASTLES INTO CHECK KSIDE
4360 IF MTYPE = 6 AND XY2 = 68 THEN XCHECK(2) = 1: REM WHITE CASTLE JUMPS INTO BEING ATTACKED KSIDE
4370 IF MTYPE = 6 AND XY2 = 38 THEN XCHECK(3) = 1: REM WHITE KING CASTLES INTO CHECK QSIDE
4380 IF MTYPE = 6 AND XY2 = 48 THEN XCHECK(3) = 1: REM WHITE CASTLE JUMPS INT BEING ATTACHED QSIDE
4390 REM --------------------
4400 IF BCAST = 1 THEN 4460: REM BLACK HAS ALREADY CASTLED
4410 IF MTYPE = 2 AND XY2 = 71 THEN XCHECK(5) = 1: REM BLACK KING CASTLES INTO CHECK KSIDE
4420 IF MTYPE = 2 AND XY2 = 61 THEN XCHECK(5) = 1: REM BLACK CASTLE JUMPS INTO BEING ATTACKED KSIDE
4430 IF MTYPE = 2 AND XY2 = 31 THEN XCHECK(6) = 1: REM BLACK KING CASTLES INTO CHECK QSIDE
4440 IF MTYPE = 2 AND XY2 = 41 THEN XCHECK(6) = 1: REM BLACK CASTLE JUMPS INT BEING ATTACHED QSIDE
4450 REM ---------------------
4460 MV(GT(GL), 1 + LV(GL)) = CMOVE: MV(GT(GL), 2 + LV(GL)) = MINFO
4470 REM ---SIMPLISTIC MOVE ORDERING---
4480 IF MTYPE = 3 OR MTYPE = 5 THEN ZCOUNT = ZCOUNT + 1: SWAP MV(GT(GL), 1 + LV(GL)), MV(ZCOUNT, 1 + LV(GL)): SWAP MV(GT(GL), 2 + LV(GL)), MV(ZCOUNT, 2 + LV(GL))
4490 ECOUNT(GL) = ZCOUNT: RETURN
4500 REM === IS MOVE VALID? LOOK FOR IT IN THE LIST ===
4510 MINDEX = 0
4520 FOR II = 1 TO GT(GL)
4530 IF MV(II, 1 + LV(GL)) = MXY THEN MINDEX = II: GOTO 4550
4540 NEXT II
4550 RETURN
4560 REM ===SWAP PLAYERS===
4570 SELF0 = -SELF0
4580 GOSUB 6250: MINDEX = MX: GOSUB 2610: REM MAKE THE MOVE FOR THE HUMAN
4590 ZZ = MXY: GOSUB 2210: PRINT AA$
4600 AI = -1 * AI: HUMAN = -1 * HUMAN: REM NOW AI TAKES THE OTHER SIDE
4610 P1$ = "WHITE ": P2$ = "BLACK ": IF AI = WHITE THEN P1$ = "BLACK ": P2$ = "WHITE "
4620 TRY = TRY + 1: IF TRY > 1 THEN GMOVE = GMOVE + 1: TRY = 0: REM FOR SELF PLAY
4630 IF GMX = 1 THEN GOTO 1760: REM GAME OVER!
4640 RETURN
4650 REM ===EDIT BOARD===
4660 PRINT : PRINT " WHITE: PNBRQK=(-1,-6) BLACK: pnbrqk=(+1, +6)"
4670 PRINT " ENTER PIECE, CHESS SQUARE (P,XY) ";
4680 INPUT CP, AA$: IF LEN(AA$) <> 2 THEN 4670
4690 AA$ = AA$ + AA$: GOSUB 2280: IF INT(ZZ / 100) < 11 OR INT(ZZ / 100) > 88 THEN 4710
4700 X1Y1 = GNX1Y1(ZZ): B(X1Y1) = CP
4710 GOSUB 2960: RETURN
4720 REM ===CLEAR BOARD===
4730 PRINT : INPUT "CLEAR BOARD (0=NO/1=YES) ", ZZ
4740 IF ZZ <> 1 THEN 4790
4750 FOR JJ = 1 TO 8: FOR II = 1 TO 8
4760 B(II * 10 + JJ) = 0
4770 NEXT II: NEXT JJ
4780 INPUT "ENTER MOVE NUMBER ", GMOVE
4790 RETURN
4800 REM ===SAVE BOARD===
4810 INPUT "FILE: ", NM$: IF LEN(NM$) = 0 THEN NM$ = "CB.TXT"
4820 OPEN NM$ FOR OUTPUT AS #1
4830 FOR II = 0 TO 9: FOR JJ = 0 TO 9
4840 PRINT #1, B(II * 10 + JJ)
4850 NEXT JJ: NEXT II: PRINT #1, GMOVE
4860 PRINT #1, SELF0, AI, HUMAN
4870 PRINT #1, P1$
4880 PRINT #1, P2$
4890 CLOSE #1: RETURN
4900 REM ===LOAD BOARD===
4910 INPUT "FILE: ", NM$: IF LEN(NM$) = 0 THEN NM$ = "CB.TXT"
4920 OPEN NM$ FOR INPUT AS #1
4930 FOR II = 0 TO 9: FOR JJ = 0 TO 9
4940 INPUT #1, B(II * 10 + JJ)
4950 NEXT JJ: NEXT II: INPUT #1, GMOVE
4960 INPUT #1, SELF0, AI, HUMAN
4970 INPUT #1, P1$
4980 INPUT #1, P2$
4990 CLOSE #1
5000 IF AI = WHITE THEN P1$ = "BLACK": P2$ = "WHITE"
5010 GOSUB 2960: GMX = 0: RETURN
5020 REM ===SUGGEST MOVE ===
5030 ZZ9 = SELF0: ALTXY = 0
5040 INPUT "SUGGEST MOVE FOR 1=WHITE, 2=BLACK ", II
5050 IF II = 1 THEN SELF0 = -1 ELSE SELF0 = 1
5060 GOSUB 6250: ZZ = MXY: GOSUB 2220
5070 PRINT "SUGGESTED MOVE: "; AA$
5080 ZZ = ALTXY: GOSUB 2220: PRINT "ALTERNATE MOVE: "; AA$
5090 SELF0 = ZZ9
5100 RETURN
5110 REM ===SET DEPTH===
5120 PRINT "CURRENT BASE DEPTH = "; PDEPTH: REM ===SET DEPTH===
5130 INPUT "NEW VALUE= ", PDEPTH
5140 IF PDEPTH < 2 THEN PDEPTH = 2
5150 IF PDEPTH > 8 THEN PDEPTH = 8
5160 MDEPTH = PDEPTH: GOSUB 1920: RETURN
5170 REM ===SAVE CASTLING FLAGS===
5180 FOR Z9 = 1 TO 6
5190 ZCAST(Z9) = XCAST(Z9): ZCHECK(Z9) = XCHECK(Z9): ZWCAST = WCAST: ZBCAST = BCAST
5200 NEXT Z9: RETURN
5210 REM ===RESTORE CASTLING FLAGS===
5220 FOR Z9 = 1 TO 6
5230 XCAST(Z9) = ZCAST(Z9): XCHECK(Z9) = ZCHECK(Z9): WCAST = ZWCAST: BCAST = ZBCAST
5240 NEXT Z9: RETURN
5250 REM ===BOARD EVALUATION=================================================================
5260 EV0 = 0: OPMOB = 0: PASSED = 0: WBIS = 0: BBIS = 0: T9 = 0
5270 FOR II = 11 TO 88: QB(II) = B(II): NEXT II: REM ***SAVE BOARD****
5280 REM ===SIMPLESTIC QUIESCENT SEARCH===
5290 IF GMOVE <= 3 THEN 5450
5300 GL = GL + 1: REM ...SET WORKSPACE
5310 QX2Y2 = GNX2Y2(MV(ZI, 1 + LV(GL))): QKIND = ZKIND
5320 FOR QII = 1 TO 8
5330 FOR Q9 = 1 TO ECOUNT(GL)
5340 LXY = MV(Q9, 1 + LV(GL)): LX1Y1 = GNX1Y1(LXY): LX2Y2 = GNX2Y2(LXY): QSN = SWB(GNA(MV(Q9, 2 + LV(GL))))
5350 IF QSN = SELF0 * QKIND THEN T9 = T9 + CPVAL(B(LX2Y2) + 7) / TTUNE
5360 IF Y2 = 8 AND B(LX1Y1) = 1 THEN B(LX1Y1) = 5: REM BLACK PAWN PROMOTION
5370 IF Y2 = 1 AND B(LX1Y1) = -1 THEN B(LX1Y1) = -5: REM WHITE PAWN PROMOTION
5380 IF LX2Y2 = QX2Y2 AND QSN = SELF0 * QKIND THEN EV0 = EV0 + CPVAL(B(QX2Y2) + 7) / TUNE: B(QX2Y2) = B(LX1Y1): B(LX1Y1) = 0: GOTO 5400
5390 NEXT Q9: EV0 = EV0 + T9 / TTUNE: GOTO 5420: REM NO MORE CONFLICT, XOUT
5400 QKIND = -QKIND: GOSUB 2960: REM SCAN NEW BOARD CONFIGURATION
5410 NEXT QII
5420 GL = GL - 1: REM ...RESET WORKSPACE!!!
5430 FOR II = 11 TO 88: B(II) = QB(II): NEXT II: REM ===FINISH QUIESCENT SEARCH===
5440 REM ===MATERIAL COUNT===
5450 IF GNB(MV(I1, 2)) > 4 AND GMOVE < 5 THEN EV0 = EV0 - SELF0 * 50: REM HOLD BACK QUEEN AND KING AT FIRST
5460 IF GND(MV(I1, 2)) > 7 THEN EV0 = EV0 + SELF0 * 30: REM BONUS POINTS FOR CASTLING
5470 FOR II = 1 TO 8: FOR JJ = 1 TO 8
5480 XY = 10 * II + JJ
5490 EV0 = EV0 + CPVAL(B(XY) + 7)
5500 IF B(XY) = 6 THEN BXX = II: BYY = JJ
5510 IF B(XY) = -6 THEN WXX = II: WYY = JJ
5520 IF B(XY) = -3 THEN WBIS = WBIS + 1
5530 IF B(XY) = 3 THEN BBIS = BBIS + 1
5540 KSN = SGN(B(XY)): KCP = ABS(B(XY))
5550 KK = JJ: IF KSN = 1 THEN KK = 9 - JJ
5560 REM ===PAWN EVALUATION===
5570 PPN = 0: IF KCP <> 1 THEN 5620
5580 FOR LL = 1 TO 8: IF ABS(B(II * 10 + LL)) = 1 THEN PPN = PPN + 1: PASSED = PASSED + 1
5590 NEXT LL: IF PPN = 1 THEN EV0 = EV0 + KSN * KK * (1 + ENDGAME): REM SINGLE PAWN ON FILE
5600 EV0 = EV0 + KSN * TPAWN(II * 10 + KK) * (1 - ENDGAME) + KSN * EPAWN(II * 10 + KK) * ENDGAME: GOTO 5670
5610 REM ===OTHER PIECES===
5620 IF KCP = 2 THEN EV0 = EV0 + KSN * TKN(II * 10 + KK): GOTO 5670
5630 IF KCP = 3 THEN EV0 = EV0 + KSN * TBISHOP(II * 10 + KK): GOTO 5670
5640 IF KCP = 4 THEN EV0 = EV0 + KSN * TROOK(II * 10 + KK) * (1 - ENDGAME) + KSN * ENDGAME * EROOK(II * 10 + KK) / (1 + 3 * MOPUP): GOTO 5670
5650 IF KCP = 5 THEN EV0 = EV0 + KSN * TQUEEN(II * 10 + KK): GOTO 5670
5660 IF KCP = 6 THEN EV0 = EV0 + KSN * TKMID(II * 10 + KK) * (1 - ENDGAME) + KSN * EKING(II * 10 + KK) * ENDGAME * (1 + MOPUP)
5670 NEXT JJ: NEXT II
5680 IF WBIS = 2 THEN EV0 = EV0 - 30: REM BONUS POINTS FOR KEEPING TWO BISHOPS
5690 IF BBIS = 2 THEN EV0 = EV0 + 30
5700 IF SELF0 = WHITE THEN KX = BXX: KY = 9 - BYY: OPMOB = BPT(MDEPTH): REM OPPOSING KING
5710 IF SELF0 = BLACK THEN KX = WXX: KY = WYY: OPMOB = WPT(MDEPTH)
5720 QMD = ABS(BXX - WXX) + ABS(BYY - WYY): REM ONLY DO MOP-UP EVALUATION IF NO PAWNS TO MOVE
5730 IF MOPUP = 1 AND PASSED = 0 AND BMT < ABS(WMT) AND SELF0 = WHITE THEN EV0 = EV0 - (5 * CMD(KX * 10 + KY) + 4 * (14 - QMD)) * 10
5740 IF MOPUP = 1 AND PASSED = 0 AND ABS(WMT) < BMT AND SELF0 = BLACK THEN EV0 = EV0 + (5 * CMD(KX * 10 + KY) + 4 * (14 - QMD)) * 10
5750 EV0 = EV0 - OPMOB
5760 RETURN: REM ============================================================================
5770 REM =====UNDO MOVE ROUTINE========
5780 U1V1 = GNX1Y1(UXY): U2V2 = GNX2Y2(UXY): U1 = GNA(UXY): V1 = GNB(UXY): U2 = GNC(UXY): V2 = GND(UXY)
5790 FF = GNB(UINFO): TT = GNC(UINFO): ZZ = GND(UINFO)
5800 IF ZZ = 2 THEN B(U1V1) = WHITE * FF: B(U2V2) = WHITE * TT: IF FF = 1 AND V1 = 7 AND V2 = 5 THEN B(U1 * 10 + 9) = FENCE
5810 IF ZZ = 3 THEN B(U1V1) = WHITE * FF: B(U2V2) = BLACK * TT
5820 IF ZZ = 6 THEN B(U1V1) = BLACK * FF: B(U2V2) = BLACK * TT: IF FF = 1 AND V1 = 2 AND V2 = 4 THEN B(U1 * 10 + 0) = FENCE
5830 IF ZZ = 5 THEN B(U1V1) = BLACK * FF: B(U2V2) = WHITE * TT
5840 IF GNA(UINFO) = 1 AND ZZ = 8 THEN B(88) = -4: B(68) = 0: B(78) = 0: B(58) = -6: XCAST(1) = 0: REM WK-CASTLE
5850 IF GNA(UINFO) = 1 AND ZZ = 9 THEN B(18) = -4: B(38) = 0: B(48) = 0: B(58) = -6: XCAST(1) = 0: REM WQ-CASTLE
5860 IF GNA(UINFO) = 2 AND ZZ = 8 THEN B(81) = 4: B(61) = 0: B(71) = 0: B(51) = 6: XCAST(4) = 0: REM BK-CASTLE
5870 IF GNA(UINFO) = 2 AND ZZ = 9 THEN B(11) = 4: B(31) = 0: B(41) = 0: B(51) = 6: XCAST(4) = 0: REM BQ-CASTLE
5880 IF GNA(UINFO) = 1 AND ZZ = 4 THEN B(U1V1) = WHITE: B(U2 * 10 + V2 + 1) = BLACK: B(U2V2) = 0: B(U2 * 10 + 0) = ENPASS
5890 IF GNA(UINFO) = 2 AND ZZ = 4 THEN B(U1V1) = BLACK: B(U2 * 10 + V2 - 1) = WHITE: B(U2V2) = 0: B(U2 * 10 + 9) = ENPASS
5900 RETURN
5910 REM ==============================
5920 REM ===SUBROUTINE TO DO THE MOVE AND SET ALPHA/BETA===
5930 XFLAG = 0
5940 ZFS = GNA(MV(ZI, 2 + LV(GL))): IF SWB(ZFS) <> ZKIND * SELF0 THEN XFLAG = 1: GOTO 5970
5950 ABCUT(GL) = 0: MINDEX = ZI: GOSUB 2610
5960 ALPHA(GL + 1) = ALPHA(GL): BETA(GL + 1) = BETA(GL)
5970 MV(ZI, 3 + LV(GL)) = ZKIND * PINF
5980 RETURN
5990 REM ===ALPHA=== ZI=I2 Z0=I1 ETC
6000 IF MV(ZI, 3 + LV(GL)) = PINF AND MOPUP = 1 THEN GOSUB 5260: MV(ZI, 3 + LV(GL)) = EV0: GOTO 6020: REM TRY MOPUP
6010 IF MV(ZI, 3 + LV(GL)) = PINF AND XCHECK(1) + XCHECK(4) = 0 THEN GOSUB 5260: MV(ZI, 3 + LV(GL)) = EV0: REM FOR ENDGAME
6020 ZZ = MV(ZI, 3 + LV(GL))
6030 IF ZZ > MV(Z0, 3 + LV(GL - 1)) THEN MV(Z0, 3 + LV(GL - 1)) = ZZ: ALPHA(GL) = ZZ
6040 IF ALPHA(GL) >= BETA(GL - 1) THEN ABCUT(GL) = 1
6050 UXY = MV(ZI, 1 + LV(GL)): UINFO = MV(ZI, 2 + LV(GL)): GOSUB 5780
6060 RETURN
6070 REM ===BETA====
6080 IF MV(ZI, 3 + LV(GL)) = -PINF AND MOPUP = 1 THEN GOSUB 5260: MV(ZI, 3 + LV(GL)) = EV0: GOTO 6100: REM TRY MOPUP
6090 IF MV(ZI, 3 + LV(GL)) = -PINF AND XCHECK(1) + XCHECK(4) = 0 THEN GOSUB 5260: MV(ZI, 3 + LV(GL)) = EV0: REM FOR ENDGAME
6100 ZZ = MV(ZI, 3 + LV(GL))
6110 IF ZZ < MV(Z0, 3 + LV(GL - 1)) THEN MV(Z0, 3 + LV(GL - 1)) = ZZ: BETA(GL) = ZZ
6120 IF BETA(GL) <= ALPHA(GL - 1) THEN ABCUT(GL) = 1
6130 UXY = MV(ZI, 1 + LV(GL)): UINFO = MV(ZI, 2 + LV(GL)): GOSUB 5780
6140 RETURN
6150 REM ===AT DEPTH EVALUATION LOOP===(AB=1 ->BETA)...(AB=2 -> ALPHA)===
6160 GL = MDEPTH: FOR IXX = 1 TO GT(MDEPTH)
6170 GL = MDEPTH: ZI = IXX: GOSUB 5930: IF XFLAG + ZFLAG > 0 THEN 6210
6180 GOSUB 5260: MV(IXX, 3 + LV(GL)) = EV0 * SELF0: REM BOARD EVALUATION
6190 GL = MDEPTH: ZI = IXX: IF AB = 1 THEN GOSUB 6080 ELSE GOSUB 6000
6200 IF ABCUT(MDEPTH) = 1 THEN GOTO 6220
6210 NEXT IXX
6220 RETURN
6230 REM ===INITIAL EVALUATION (GAME STAGE AND CURRENT MATERIAL)===
6240 REM SET FLAGS: ENDGAME (0/1) AND MOPUP (0/1)
6250 MTOTAL = 0: QNT = 0: ENDGAME = 0: MOPUP = 0: WMT = 0: BMT = 0: ALTXY = 0
6260 GOSUB 5180: REM SAVE CASTING FLAGS
6270 FOR JJ = 1 TO 8: FOR II = 1 TO 8: XY = II * 10 + JJ
6280 MTOTAL = MTOTAL + ABS(B(XY))
6290 IF ABS(B(XY)) = 5 THEN QNT = QNT + 1: REM COUNT QUEENS
6300 IF SGN(B(XY)) = WHITE THEN WMT = WMT + B(XY) ELSE BMT = BMT + B(XY)
6310 NEXT II: NEXT JJ: REM ===GAME PROGRESSION===
6320 TUNE = XTUNE: IF MTOTAL <= 50 THEN TUNE = ETUNE: REM TRANSITION TO ENDGAME
6330 IF MTOTAL <= EGAM THEN ENDGAME = 1
6340 IF MTOTAL < MOPX THEN MOPUP = 1
6350 IF SELF0 = WHITE AND BMT < 8 THEN MOPUP = 1: REM BLACK IS DONE
6360 IF SELF0 = BLACK AND ABS(WMT) < 8 THEN MOPUP = 1: REM WHITE IS DONE
6370 IF OBM = 1 AND GMOVE < 10 THEN GOSUB 7140: IF MXY <> 0 THEN 7120: REM OPENING BOOK
6380 REM ===INITIAL SCAN AND SETUP ALPHA/BETA FLAGS================
6390 GL = 1: MX = 0: LMX = 0: EMOVE = -PINF: REM TO TRACK VALID MOVES
6400 FOR II = 1 TO 10: ALPHA(II) = -PINF: BETA(II) = PINF: NEXT II
6410 GOSUB 2960: REM SCAN THE BOARD
6420 REM ===STATUS BAR============================================
6430 FOR II = 1 TO GT(1)
6440 Z9 = GNA(MV(II, 2)): IF SWB(Z9) = SELF0 THEN PRINT "=";
6450 NEXT II: PRINT
6460 REM ==========================================================
6470 REM ===MINIMAX WITH ALPHA-BETA================================
6480 GL = 1: FOR I1 = 1 TO GT(1)
6490 GL = 1: ZI = I1: ZKIND = BIG: GOSUB 5930: IF XFLAG + ZFLAG > 0 THEN 6990
6500 PRINT ".";
6510 LMX2 = 0: LMX = I1: REM TRACK LAST VALID MOVE
6520 IF GL + 1 = MDEPTH THEN Z0 = I1: AB = 1: ZKIND = SMALL: GOSUB 6160: GOTO 6960: REM BETA2
6530 REM =====================================================
6540 GL = 2: FOR I2 = 1 TO GT(2)
6550 GL = 2: ZI = I2: ZKIND = SMALL: GOSUB 5930: IF XFLAG + ZFLAG > 0 THEN 6850
6560 LMX2 = I2
6570 IF GL + 1 = MDEPTH THEN Z0 = I2: AB = 2: ZKIND = BIG: GOSUB 6160: GOTO 6840
6580 GL = 3: FOR I3 = 1 TO GT(3)
6590 GL = 3: ZI = I3: ZKIND = BIG: GOSUB 5930: IF XFLAG + ZFLAG > 0 THEN 6830
6600 IF GL + 1 = MDEPTH THEN Z0 = I3: AB = 1: ZKIND = SMALL: GOSUB 6160: GOTO 6820: REM BETA4
6610 GL = 4: FOR I4 = 1 TO GT(4)
6620 GL = 4: ZI = I4: ZKIND = SMALL: GOSUB 5930: IF XFLAG + ZFLAG > 0 THEN 6810
6630 IF GL + 1 = MDEPTH THEN Z0 = I4: AB = 2: ZKIND = BIG: GOSUB 6160: GOTO 6800: REM ALPHA5
6640 GL = 5: FOR I5 = 1 TO GT(5)
6650 GL = 5: ZI = I5: ZKIND = BIG: GOSUB 5930: IF XFLAG + ZFLAG > 0 THEN 6790
6660 IF GL + 1 = MDEPTH THEN Z0 = I5: AB = 1: ZKIND = SMALL: GOSUB 6160: GOTO 6780
6670 GL = 6: FOR I6 = 1 TO GT(6)
6680 GL = 6: ZI = I6: ZKIND = SMALL: GOSUB 5930: IF XFLAG + ZFLAG > 0 THEN 6770
6690 IF GL + 1 = MDEPTH THEN Z0 = I6: AB = 2: ZKIND = BIG: GOSUB 6160: GOTO 6760
6700 GL = 7: FOR I7 = 1 TO GT(7)
6710 GL = 7: ZI = I7: ZKIND = BIG: GOSUB 5930: IF XFLAG + ZFLAG > 0 THEN 6750
6720 IF GL + 1 = MDEPTH THEN Z0 = I7: AB = 1: ZKIND = SMALL: GOSUB 6160: GOTO 6740
6730 REM ---====---====---====---=====----=====---=====----====----====
6740 GL = 7: ZI = I7: Z0 = I6: GOSUB 6000: IF ABCUT(GL) = 1 THEN 6760: REM *ALPHA*
6750 NEXT I7
6760 GL = 6: ZI = I6: Z0 = I5: GOSUB 6080: IF ABCUT(GL) = 1 THEN 6780: REM *BETA*
6770 NEXT I6
6780 GL = 5: ZI = I5: Z0 = I4: GOSUB 6000: IF ABCUT(GL) = 1 THEN GOTO 6800: REM *ALPHA*
6790 NEXT I5
6800 GL = 4: ZI = I4: Z0 = I3: GOSUB 6080: IF ABCUT(GL) = 1 THEN GOTO 6820: REM *BETA*
6810 NEXT I4
6820 GL = 3: ZI = I3: Z0 = I2: GOSUB 6000: IF ABCUT(GL) = 1 GOTO 6840: REM *ALPHA*
6830 NEXT I3
6840 GL = 2: ZI = I2: Z0 = I1: GOSUB 6080: IF ABCUT(GL) = 1 THEN GOTO 6960: REM *BETA*
6850 NEXT I2: GL = 1: REM CHECK IF STALEMATE AND AVOID
6860 REM =====================================================
6870 IF LMX2 = 0 AND WCK(2) = 0 AND SELF0 = BLACK THEN 6980: REM GoSub 1394: If B(9) <= CHECK Then GoTo 5600
6880 IF LMX2 = 0 AND BCK(2) = 0 AND SELF0 = WHITE THEN 6980: REM GoSub 1394: If B(1) <= CHECK Then GoTo 5600
6890 IF LMX2 = 0 AND WCK(2) <> 0 AND SELF0 = BLACK THEN GOTO 6920: REM BLACK MATES
6900 IF LMX2 = 0 AND BCK(2) <> 0 AND SELF0 = WHITE THEN GOTO 6920: REM WHITE MATES
6910 GOTO 6960: REM HERE THE WINNING LINE
6920 PRINT "CHECKMATE! >>"; : ZZ = MV(I1, 1): GOSUB 2220: PRINT AA$:
6930 IF KEEPIT = 1 THEN PRINT #2, HUMAN$; " "; AA$; " CHECKMATE!"
6940 GMX = 1: UINFO = MV(I1, 2): GOSUB 5780: GOTO 7120
6950 REM =====================================================
6960 GL = 1: ZZ = MV(I1, 3 + LV(GL))
6970 IF ZZ > EMOVE THEN EMOVE = ZZ: MOLD = MX: MX = I1: ALPHA(GL) = EMOVE
6980 UXY = MV(I1, 1 + LV(GL)): UINFO = MV(I1, 2 + LV(GL)): GOSUB 5780
6990 GOSUB 5220: REM RESTORE CASTLING FLAGS
7000 NEXT I1: PRINT
7010 REM ==========================================================
7020 REM <<<< MAX FROM LAYER-1 >>>>
7030 IF LMX = 0 AND WCK(1) = 0 AND BCK(1) = 0 THEN PRINT "<<<STALEMATE>>>": GMX = 1: GOTO 7120
7040 IF LMX = 0 AND KEEPIT = 1 THEN PRINT #2, HUMAN$; " CHECKMATE!"
7050 IF LMX = 0 THEN PRINT "*** CHECKMATE! ***": GMX = 1: GOTO 7120
7060 IF MX = 0 THEN MX = LMX: REM VALID MOVE AT LEVEL-1 THOUGH SHOULD RESIGN!
7070 MXY = MV(MX, 1 + LV(GL)): ALTXY = MV(MOLD, 1 + LV(GL))
7080 NEAR = ABS(MV(MX, 3) - MV(MOLD, 3)): AXY = MXY
7090 IF AXY = CXY AND ALTXY <> 0 AND NEAR < 25 THEN MXY = ALTXY: MX = MOLD: PRINT "ALTERNATE MOVE USED!": AXY = 0: BXY = 0: CXY = 0: GOTO 7110
7100 IF AXY = CXY AND ALTXY <> 0 AND NEAR > 24 AND DFLAG = 0 THEN MDEPTH = MDEPTH + 1: DFLAG = 1: : AXY = 0: BXY = 0: CXY = 0: PRINT "DEPTH INCREASED!"
7110 CXY = BXY: BXY = AXY: REM MAKE SURE WE DO NOT REPEAT LAST SET OF MOVES
7120 RETURN: REM ==> MX, MXY, ALTXY
7130 REM ===OPENING BOOK MOVES===
7140 M$ = "": FOR II = 1 TO 8: FOR JJ = 1 TO 8
7150 M$ = M$ + MID$(CP$, B(JJ * 10 + II) + 7, 1)
7160 NEXT JJ: NEXT II
7170 MXY = 0: JJ = 0
7180 IF SELF0 = BLACK THEN OPEN "MYBOOK.TXT" FOR INPUT AS #1
7190 IF SELF0 = WHITE THEN OPEN "WMYBOOK.TXT" FOR INPUT AS #1
7200 FOR II = 1 TO 5000: REM LOAD OPENING BOOK
7210 INPUT #1, AA1$, AA2$
7220 IF LEFT$(AA1$, 2) = "ZZ" THEN 7250
7230 IF LEFT$(AA1$, 64) = LEFT$(M$, 64) THEN JJ = JJ + 1: PRINT AA2$; " "; : OM$(JJ) = AA2$
7240 NEXT II
7250 PRINT : CLOSE #1
7260 IF JJ < 1 THEN 7360
7270 JJ = INT((JJ + 1) * RND(1)): IF JJ = 0 THEN JJ = 1
7280 PRINT "USING OPENING MOVE# "; JJ: PRINT
7290 AA$ = OM$(JJ): GOSUB 2280: MXY = ZZ: LMX = 1
7300 MX = 1: MV(1, 1) = MXY
7310 REM OPEN BOOK CASTLING: HANDLE THE ROOK HERE
7320 IF AA$ = "E1G1" THEN B(88) = 0: B(68) = -4: GOTO 7360
7330 IF AA$ = "E8G8" THEN B(81) = 0: B(61) = 4: GOTO 7360
7340 IF AA$ = "E1C1" THEN B(18) = 0: B(48) = -4: GOTO 7360
7350 IF AA$ = "E8C8" THEN B(11) = 0: B(41) = 4
7360 RETURN
7370 REM ===RESTORE BOARD===
7380 FOR II = 11 TO 88: B(II) = XQB(II): NEXT II:
7390 GOSUB 5220: REM RESTORE CASTLING FLAGES
7400 AI = ZAI: GMOVE = ZMOVE: GOSUB 2960: RETURN
7410 REM ===SAVE BOARD===
7420 FOR II = 11 TO 88: XQB(II) = B(II): NEXT II:
7430 GOSUB 5180: REM SAVE CASTLING FLAGS
7440 ZAI = AI: ZMOVE = GMOVE: RETURN
7450 REM ===MAGIC X-MOVE: MOVE ANYWHERE FOR BOARD SETUP===
7460 INPUT " MOVE ANYWHERE! >> ", AA$: IF LEN(AA$) < 4 THEN 7490
7470 FOR JJ = 1 TO LEN(AA$): MID$(AA$, JJ, 1) = GNUP$(MID$(AA$, JJ, 1)): NEXT JJ
7480 GOSUB 2270: B(GNX2Y2(ZZ)) = B(GNX1Y1(ZZ)): B(GNX1Y1(ZZ)) = 0:
7490 GOSUB 2960: RETURN
' === Helper Fuctions ===
' The DEF GN() have been rewritten to also work with
' Qbasic, QB64, FreeBasic, and similar
' ===========================================================
Function GNA (ZZ) ' ABCD -> A
GNA = Int(ZZ / 1000)
End Function
Function GNABCD (AB, CD) ' AB, CD -> ABCD
GNABCD = AB * 100 + CD
End Function
Function GNB (ZZ) ' ABCD -> B
GNB = Int(ZZ / 100) Mod (10)
End Function
Function GNC (ZZ)
GNC = Int(ZZ / 10) Mod (10) ' ABCD -> C
End Function
Function GNCBI (ZWB, ZF, ZT, ZK) ' Move Info
GNCBI = ZWB * 1000 + 100 * Abs(ZF) + 10 * Abs(ZT) + ZK
End Function
Function GNCMT (ZF, ZT) ' Move Type
GNCMT = 2 * Sgn(ZF) + Sgn(ZT) + 4
End Function
Function GND (ZZ) ' ABCD -> D
GND = ZZ Mod (10)
End Function
Function GNEE (ZZ) ' East
GNEE = ZZ + 10
End Function
Function GNNE (ZZ) ' North-East
GNNE = ZZ + 9
End Function
Function GNNN (ZZ) ' North
GNNN = ZZ - 1
End Function
Function GNNW (ZZ) ' North-West
GNNW = ZZ - 11
End Function
Function GNSE (ZZ) ' South-East
GNSE = ZZ + 11
End Function
Function GNSS (ZZ) ' South
GNSS = ZZ + 1
End Function
Function GNSW (ZZ) ' Sourth-West
GNSW = ZZ - 9
End Function
Function GNUP$ (C$) ' Character to uppercase
GNUP$ = Chr$(Asc(C$) - 32 * (Asc(C$) > 96) * (Asc(C$) < 123))
End Function
Function GNWW (ZZ) ' West
GNWW = ZZ - 10
End Function
Function GNX (ZZ) ' XY -> X
GNX = Int(ZZ / 10)
End Function
Function GNX1Y1 (ZZ) ' ABCD -> AB
GNX1Y1 = Int(ZZ / 100)
End Function
Function GNX2Y2 (ZZ) ' ABCD -> CD
GNX2Y2 = ZZ Mod (100)
End Function
Function GNY (ZZ) ' XY -> Y
GNY = ZZ Mod (10)
End Function