Author Topic: A 90% complete chess engine  (Read 11297 times)

0 Members and 1 Guest are viewing this topic.

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: A 90% complete chess engine
« Reply #15 on: January 26, 2020, 05:11:01 pm »
OK I believe! 700+ lines of code is probably possible, specially no check, castle, pawn promo and stopping to play? :) still nice chunk of code to get done.

Is that about 6 hours? One long sitting...

The only way I could ever do 700+ lines of code in 1 day is to use my Picture to .BAS converter. It changes a picture to all PSET lines, 1 PSET per line.... like 10,000 lines or something like that.

Offline Richard Frost

  • Seasoned Forum Regular
  • Posts: 316
  • Needle nardle noo. - Peter Sellers
    • View Profile
Re: A 90% complete chess engine
« Reply #16 on: January 29, 2020, 12:44:05 am »
Update using Bplus's graphics.  Castling works properly.  Still no checkmate.  Has "t" for take back move.
Still a long way to go, like years of my spare time.

Code: QB64: [Select]
  1. _TITLE "Chess"
  2.  
  3. DEFINT A-Z
  4.  
  5. CONST true = -1, false = 0
  6. CONST Rook = 1, Knight = 2, Bishop = 3, Queen = 4, King = 5, Pawn = 6
  7.  
  8. COMMON SHARED WorB, Move, Score, Index, opening
  9. COMMON SHARED m$, i$, mess$
  10. COMMON SHARED MaxRow, xq, yq, xc, yc, xm, ym
  11. COMMON SHARED speed, WaitForKey, Studying
  12. COMMON SHARED Castle$, OtherK$, mkr, mkc, okr, okc, invert
  13. COMMON SHARED MasterLevel, SaveWorB
  14. COMMON SHARED GameFile$, RunWith, check, redo, b1, b2, b1$, b2$
  15. COMMON SHARED debug, DebugR, DebugC
  16. COMMON SHARED Start1&, Start2&, MaxElapse!
  17. COMMON SHARED human, humanc, OnAuto, sillyf, rflag
  18. COMMON SHARED boardwhite&, boardblack&
  19. COMMON SHARED black&, red&, green&, blue&, white&
  20. COMMON SHARED Enter$, Esc$, lf$, crlf$
  21. COMMON SHARED debug$, tbf, tbc
  22.  
  23. l = 5: p = 6: b = 8: q1 = 200: q2 = 500
  24. DIM SHARED b(b, b), t(b, b, l), o(b, b), mp$(p, 7), tb(b, b, 10)
  25. DIM SHARED Moves(l), Move$(l, q1), Score(l, q1), TieTo(l), Index(l, q1)
  26. DIM SHARED x(p, q2), y(p, q2), c(12, q2), MoveLog$(q2)
  27. DIM SHARED gm$(999)
  28. DIM SHARED cp&(32)
  29.  
  30. 'ON ERROR GOTO Oops
  31.  
  32. 'GameFile$ = "'chessx.alg"
  33.  
  34. sillyf = 1 '                                            Moire effect, toggle with "z", or just default this to 0
  35.  
  36. Begin:
  37. Init
  38. gm = 1
  39.     SaveWorB = WorB
  40.     IF LEN(GameFile$) THEN
  41.         opening = 1
  42.         ScanKey
  43.         m$ = gm$(gm)
  44.         'LOCATE 1, 1: PRINT gm; "*"; m$; "*";
  45.         _DISPLAY
  46.         SLEEP
  47.         Score = 0
  48.         IF RIGHT$(m$, 1) = "+" THEN
  49.             Score = 777
  50.             check = true
  51.             m$ = LEFT$(m$, LEN(m$) - 1)
  52.         END IF
  53.         gm = gm + 1
  54.         IF LEN(m$) = 0 THEN opening = 0: GameFile$ = ""
  55.     END IF
  56.  
  57.     'IF opening > 0 THEN
  58.     '    READ m$
  59.     'IF m$ = "end" THEN opening = 0
  60.     'END IF
  61.  
  62.     IF opening = 0 THEN
  63.         IF Start1& = 0 THEN Start1& = TIMER
  64.         Start2& = TIMER
  65.         SaveForTakeBack
  66.         redo:
  67.         WorB = WorB XOR 1
  68.         CheckBoard 1
  69.         WorB = WorB XOR 1
  70.         CheckBoard 0
  71.         IF Moves(0) = 0 THEN mess$ = "Stalemate"
  72.         IF LEN(mess$) > 0 THEN EXIT DO
  73.         'LOCATE 1, 1: PRINT debug$;
  74.         IF human AND (humanc = WorB) THEN
  75.             woof:
  76.             IF tbf THEN
  77.                 takeback
  78.                 PlotAll
  79.                 tbf = 0
  80.                 GOTO redo
  81.             END IF
  82.             'LOCATE 1, 1: PRINT tbc; " ";
  83.             HumanMove
  84.             IF tbf THEN GOTO woof
  85.             ok = 0
  86.             FOR i = 1 TO Moves(0)
  87.                 IF m$ = Move$(0, i) THEN ok = 1: EXIT FOR
  88.             NEXT i
  89.             IF ok = 0 THEN SOUND 200, 1: GOTO woof
  90.         ELSE
  91.             DebugR = 99
  92.             IF sillyf THEN silly
  93.             rflag = 1
  94.             Recurse 1
  95.             rflag = 0
  96.             TakeBest 0
  97.             IF debug THEN Debug1
  98.             PlotAll
  99.         END IF
  100.     END IF
  101.     WorB = SaveWorB
  102.     DispTime
  103.  
  104.     fr = VAL(MID$(m$, 2, 1)) '                                       from row
  105.     IF invert THEN fr = 9 - fr
  106.     fc = INSTR("abcdefgh", LEFT$(m$, 1)) '                           from column
  107.     IF invert THEN fc = 9 - fc
  108.     IF LEFT$(m$, 1) = "O" THEN
  109.         IF (WorB = 0) AND (humanc = 0) THEN
  110.             fr = mkr: fc = mkc
  111.         ELSE
  112.             fr = okr: fc = okc
  113.         END IF
  114.     END IF
  115.  
  116.     DO: _LIMIT 10
  117.         ic = (ic + 1) MOD 10
  118.         IF ic > 5 THEN f$ = "clockx.png" ELSE f$ = "clockx2.png"
  119.         IF f$ <> oldf$ THEN
  120.             i& = _LOADIMAGE(f$): _ICON i&: _FREEIMAGE i&
  121.             oldf$ = f$
  122.         END IF
  123.         zz = zz XOR 1
  124.         IF zz THEN
  125.             c1& = _RGB32(RND * 155 + 100, RND * 155 + 100, RND * 155 + 100)
  126.             c2& = _RGB32(RND * 155 + 100, RND * 155 + 100, RND * 155 + 100)
  127.         ELSE
  128.             c1& = black&: c2& = black&
  129.         END IF
  130.         x1 = xc + (fc - 5) * xq
  131.         y1 = yc + (4 - fr) * yq
  132.         x2 = x1 + xq
  133.         y2 = y1 + yq
  134.         LINE (x1 + 1, y1 + 1)-(x2 - 1, y2 - 1), c1&, B
  135.         LINE (x1 + 2, y1 + 2)-(x2 - 2, y2 - 2), c1&, B
  136.  
  137.         IF LEFT$(m$, 1) <> "O" THEN '                                    castling
  138.             tr = VAL(MID$(m$, 4, 1))
  139.             IF invert THEN tr = 9 - tr
  140.             tc = INSTR("abcdefgh", MID$(m$, 3, 1))
  141.             IF invert THEN tc = 9 - tc
  142.             x1 = xc + (tc - 5) * xq
  143.             y1 = yc + (4 - tr) * yq
  144.             x2 = x1 + xq
  145.             y2 = y1 + yq
  146.             LINE (x1 + 1, y1 + 1)-(x2 - 1, y2 - 1), c2&, B
  147.             LINE (x1 + 2, y1 + 2)-(x2 - 2, y2 - 2), c2&, B
  148.         END IF
  149.         _DISPLAY
  150.         _DELAY .01
  151.         IF NOT ((WorB <> humanc) AND (opening = 0)) THEN EXIT DO
  152.         ScanKey
  153.         'IF tbf THEN GOTO begin2
  154.     LOOP UNTIL i$ = Enter$
  155.     f$ = "chess3.png": i& = _LOADIMAGE(f$): _ICON i&: _FREEIMAGE i&
  156.  
  157.     MoveIt m$, -1
  158.     ShowAlgebraic m$
  159.     IF sillyf THEN silly ELSE PlotAll
  160.     _DISPLAY
  161.  
  162.     IF opening = 0 THEN
  163.         check = false
  164.         CheckBoard 0
  165.         LOCATE 1, 58
  166.         IF Score = 777 THEN
  167.             check = true
  168.             PRINT "Check!";
  169.         ELSE
  170.             PRINT "      ";
  171.         END IF
  172.     END IF
  173.  
  174.     WorB = SaveWorB XOR 1 '                                          toggle white/black
  175.     'IF LEN(GameFile$) > 0 THEN KeyGet
  176.     'IF humanc = WorB THEN KeyGet
  177.     'WaitForKey = true
  178. LOOP UNTIL Move = 500
  179.  
  180. IF Move = 500 THEN mess$ = "Over 500 moves...."
  181. tc = 60 - LEN(mess$) \ 2
  182. LOCATE 22, tc: PRINT mess$;
  183. PRINT #1, ""
  184. PRINT #1, mess$
  185. ' IF Studying THEN KeyGet
  186. GOTO Begin
  187.  
  188. o1:
  189. DATA e2e4,e7e5,g1f3,b8c6,f1b5,a7a6,b5a4,b7b5,a4b3,g8f6,b1c3,f8e7,f3g5,h7h6
  190. 'DATA g5f7,O-O
  191. 'DATA f7d8,g8h7
  192.  
  193. SetUp:
  194. DATA 1,2,3,4,5,3,2,1
  195. DATA 6,6,6,6,6,6,6,6
  196. DATA 0,0,0,0,0,0,0,0
  197. DATA 0,0,0,0,0,0,0,0
  198. DATA 0,0,0,0,0,0,0,0
  199. DATA 0,0,0,0,0,0,0,0
  200. DATA 12,12,12,12,12,12,12,12
  201. DATA 7,8,9,10,11,9,8,7
  202.  
  203. Legal:
  204. '       udlr,udlr,udlr,udlr,udlr,udlr,udlr,udlr
  205. DATA R,8000,0800,0080,0008,0000,0000,0000,0000
  206. DATA N,2010,2001,0210,0201,1020,1002,0120,0102
  207. DATA B,8080,8008,0880,0808,0000,0000,0000,0000
  208. DATA Q,8000,0800,0080,0008,8080,8008,0880,0808
  209. DATA K,1000,0100,0010,0001,1010,1001,0110,0101
  210. DATA P,1000,1001,1010,0000,0000,0000,0000,0000
  211.  
  212. PiecePatterns:
  213. DATA ........................
  214. DATA ........................
  215. DATA ........................
  216. DATA ........................
  217. DATA ....X..XX..XX..XX..X....
  218. DATA ....X..XX..XX..XX..X....
  219. DATA ....X..XX..XX..XX..X....
  220. DATA ....X..XX..XX..XX..X....
  221. DATA ....X..XX..XX..XX..X....
  222. DATA .....X.XX..XX..XX.X.....
  223. DATA ......XXXXXXXXXXXX......
  224. DATA .....XX..........XX.....
  225. DATA ......X.XXXXXXXX.X......
  226. DATA ......X.XXXXXXXX.X......
  227. DATA ......X.XXXXXXXX.X......
  228. DATA ......X.XXXXXXXX.X......
  229. DATA .....X............X.....
  230. DATA .....X..XXXXXXXX..X.....
  231. DATA ....X..............X....
  232. DATA ...X..XXXXXXXXXXXX..X...
  233. DATA ...X................X...
  234. DATA ...XXXXXXXXXXXXXXXXXX...
  235.  
  236. DATA ........................
  237. DATA ........................
  238. DATA ........................
  239. DATA ........................
  240. DATA ............XXX.........
  241. DATA ..........XX.X.X........
  242. DATA .........X..X.X.XX......
  243. DATA ........X.X.XX.X..X.....
  244. DATA .......X.XXXX.X.X..X....
  245. DATA .......X.X...XXX.X..X...
  246. DATA .....X..XX..X.XXX.X.X...
  247. DATA ....X.XXXXXXX.XXX.X..X..
  248. DATA ...X.XXXXXX.X..XX.X..X..
  249. DATA ...X.XX..XXX.X.XX.X..X..
  250. DATA ....X..XXXX..X.XX.X..X..
  251. DATA .....XX..X..X.XXX.X..X..
  252. DATA ........X..XX.XX.XX.X...
  253. DATA .......X..XX.XX.XX.X....
  254. DATA ......XXXXXXXXXXXXXX....
  255. DATA .....X..............X...
  256. DATA ....X................X..
  257. DATA .....XXXXXXXXXXXXXXXX...
  258.  
  259. DATA ........................
  260. DATA ........................
  261. DATA ........................
  262. DATA ............X...........
  263. DATA ...........X.X..........
  264. DATA ..........X.X.X.........
  265. DATA ........X...XX..X.......
  266. DATA .......X..X..XX..X......
  267. DATA .......X.XXX..XX.X......
  268. DATA .......X.XXXX..X.X......
  269. DATA ........X.......X.......
  270. DATA .......XX.X.X.X.XX......
  271. DATA ......X...........X.....
  272. DATA .......X.XXX.XX.XX......
  273. DATA ........X.XX.XX.X.......
  274. DATA .......X.XXX.XXX.X......
  275. DATA .......X.XXX.XXX.X......
  276. DATA ......X.X.......X.X.....
  277. DATA .....X.XXXXX.XXXXX.X....
  278. DATA .....X.XXXXX.XXXXX.X....
  279. DATA .....X.............X....
  280. DATA ......XXXXXXXXXXXXX.....
  281.  
  282. DATA ............X...........
  283. DATA ...........X.X..........
  284. DATA .....X....X.X.X....X....
  285. DATA ....X.X.XX.XXX..X.X.X...
  286. DATA ...X.X.X..XX.XXX.X.X.X..
  287. DATA ...X.XX.XXX.X.XXX.XX.X..
  288. DATA ...X.XXX.X.XXX.X.XXX.X..
  289. DATA ...X.XXXX.XXXXX.XXXX.X..
  290. DATA ....X.XXXXXX..XXXXX.X...
  291. DATA .....X.XXXXX..XXXX.X....
  292. DATA .....X.............X....
  293. DATA ......XXXXXXXXXXXXX.....
  294. DATA ....X...............X...
  295. DATA ......XX.XXXXXXX.XX.....
  296. DATA .......X.X.XXX.X.X......
  297. DATA ......X.XX.XXX.XX.X.....
  298. DATA ......X.XX.XXX.XX.X.....
  299. DATA .....XXXXXXXXXXXXXXX....
  300. DATA ....X...............X...
  301. DATA ...X..XX.XX.XX.XX.X..X..
  302. DATA ...X.................X..
  303. DATA ....XXXXXXXXXXXXXXXXX...
  304.  
  305. DATA ...........XX...........
  306. DATA .........XX..XX.........
  307. DATA .......XX.X..X.XX.......
  308. DATA .....XX.X......X.XX.....
  309. DATA ....X..XX.X..X.XX..X....
  310. DATA ...X...XXXX..XXXX...X...
  311. DATA ..X...XX........XX...X..
  312. DATA .X..XXX.XXX..XXX.XXX..X.
  313. DATA X..XXX..XXX..XXX..XXX..X
  314. DATA X.XXXX..XXX..XXXX.XXXX.X
  315. DATA X.XXXX.XXXX..XXXX.XXXX.X
  316. DATA X.XXXX..XXXXXXXX..XXXX.X
  317. DATA .X.XXXX..XXXXXX..XXXX.X.
  318. DATA .X..XXXX..XXXX..XXXX..X.
  319. DATA ..X..XXXX......XXXX..X..
  320. DATA ...X....X......X....X...
  321. DATA ...XXXXXXXXXXXXXXXXXX...
  322. DATA ..X..................X..
  323. DATA .X..XXXXXXXXXXXXXXXX..X.
  324. DATA .X..XXXXXXXXXXXXXXXX..X.
  325. DATA ..X..................X..
  326. DATA ...XXXXXXXXXXXXXXXXXX...
  327.  
  328. DATA ........................
  329. DATA ........................
  330. DATA ........................
  331. DATA ..........XXXX..........
  332. DATA .........X....X.........
  333. DATA ........X.XXXX.X........
  334. DATA ........X.XXXX.X........
  335. DATA .........X....X.........
  336. DATA ........XXXXXXXX........
  337. DATA .......X........X.......
  338. DATA ........XXXXXXXX........
  339. DATA .........X.XX.X.........
  340. DATA .........X.XX.X.........
  341. DATA .........X.XX.X.........
  342. DATA ........X..XX..X........
  343. DATA .......X..XXXX..X.......
  344. DATA ......X.XXXXXXXX.X......
  345. DATA ......X.XXXXXXXX.X......
  346. DATA .....X............X.....
  347. DATA ......XXXXXXXXXXXX......
  348. DATA ........................
  349. DATA ........................
  350.  
  351. rgb:
  352. DATA 0,0,0,0,""
  353. DATA 1,30,60,20,"board white"
  354. DATA 2,1,1,1,"board black"
  355. DATA 3,92,92,92,"white bright"
  356. DATA 4,22,22,92,"white hightlight"
  357. DATA 5,0,0,0,"black bright"
  358. DATA 6,62,22,22,"black hightlight"
  359. DATA 7,63,20,20,"red"
  360. DATA 8,0,63,0,"green"
  361. DATA 9,0,0,63,"blue"
  362. DATA 10,63,63,63,"white"
  363. DATA 11,20,20,20,""
  364. DATA 12,20,20,20,""
  365. DATA 13,20,20,20,""
  366. DATA 14,20,20,20,""
  367. DATA 15,30,30,30,"printing"
  368.  
  369. Oops:
  370. gronk = gronk + 1
  371. IF gronk < 900 THEN
  372.     RESUME
  373.     PRINT "Error "; DATE$; "  "; TIME$;
  374.     END
  375.  
  376. SUB AddIt (Level, tm$, Score)
  377.     Moves(Level) = Moves(Level) + 1 '                                count ok
  378.     Move$(Level, Moves(Level)) = tm$ '                               save move
  379.     Score(Level, Moves(Level)) = Score
  380.     Index(Level, Moves(Level)) = TieTo(Level)
  381.  
  382. SUB BoRestore (Level)
  383.     FOR r = 1 TO 8
  384.         FOR c = 1 TO 8
  385.             b(r, c) = t(r, c, Level)
  386.         NEXT c
  387.     NEXT r
  388.  
  389. SUB BoSave (Level)
  390.     FOR r = 1 TO 8
  391.         FOR c = 1 TO 8
  392.             t(r, c, Level) = b(r, c)
  393.         NEXT c
  394.     NEXT r
  395.  
  396. SUB CheckBoard (Level)
  397.     Moves(Level) = 0
  398.     tking = 5: oking = 11
  399.     IF WorB THEN SWAP tking, oking
  400.     FOR r = 1 TO 8
  401.         FOR c = 1 TO 8
  402.             IF b(r, c) = tking THEN
  403.                 mkr = r
  404.                 mkc = c
  405.             END IF
  406.             IF b(r, c) = tking THEN
  407.                 okr = r
  408.                 okc = c
  409.             END IF
  410.         NEXT c
  411.     NEXT r
  412.  
  413.     FOR r = 1 TO 8
  414.         FOR c = 1 TO 8
  415.             mp = b(r, c)
  416.             mc = -(mp > 6) - (mp = 0) * 2
  417.             IF mc = WorB THEN TryMove Level, r, c
  418.         NEXT c
  419.     NEXT r
  420.  
  421.     '  BBWW
  422.     '  QKQK
  423.     IF MID$(Castle$, WorB * 2 + 1, 1) = " " THEN cq = true ELSE cq = false ' blank means ok
  424.     IF MID$(Castle$, WorB * 2 + 2, 1) = " " THEN ck = true ELSE ck = false
  425.  
  426.     neks$ = "" '  not empty kingside
  427.     neqs$ = "" '  not empty queenside
  428.     qsc$ = "" '   queenside control
  429.     ksc$ = "" '   kingside control
  430.     kic$ = "" '   king in check
  431.     nok$ = "" '   king not there
  432.     nrq$ = "" '   no rook queenside
  433.     nrk$ = "" '   no rook kingside
  434.  
  435.     FOR Castle = 0 TO 1 '                                            queenside, then kingside
  436.         '                         bcd              fg
  437.         IF Castle = 0 THEN ca$ = "234" ELSE ca$ = "67" '             column number
  438.         IF WorB THEN rn$ = "1" ELSE rn$ = "8" '                      row number
  439.         tp = b(VAL(rn$), 5): tp = tp + (tp > 6) * 6
  440.         IF tp <> 5 THEN nok$ = "nok "
  441.         tp = b(VAL(rn$), 1): tp = tp + (tp > 6) * 6
  442.         IF tp <> 1 THEN nrq$ = "nrq "
  443.         tp = b(VAL(rn$), 8): tp = tp + (tp > 6) * 6
  444.         IF tp <> 1 THEN nrq$ = "nrk "
  445.         FOR cs = 1 TO LEN(ca$)
  446.             rn = VAL(rn$)
  447.             n$ = MID$(ca$, cs, 1)
  448.             cn = VAL(n$)
  449.             c$ = MID$("abcdefgh", cn, 1)
  450.             tp = b(rn, cn)
  451.             tp = tp + (tp > 6) * 6 '                                 convert >6 to 1-5
  452.             IF tp <> 0 THEN '                                        not empty
  453.                 IF Castle = 0 THEN cq = false ELSE ck = false
  454.                 IF Castle = 0 THEN neqs$ = neqs$ + "neq " + c$ + rn$ + " "
  455.                 IF Castle = 1 THEN neks$ = neks$ + "nek " + c$ + rn$ + " "
  456.             END IF
  457.             q$ = MID$("abcdefgh", cn, 1) + rn$
  458.             FOR lm = 1 TO Moves(1)
  459.                 IF q$ = RIGHT$(Move$(1, lm), 2) THEN
  460.                     IF Castle = 0 THEN cq = false ELSE ck = false
  461.                     IF Castle = 0 THEN qsc$ = "qsc" + Move$(1, lm) + " "
  462.                     IF Castle = 1 THEN ksc$ = "ksc " + Move$(1, lm) + " "
  463.                 END IF
  464.             NEXT lm
  465.             q$ = "e" + rn$
  466.             FOR lm = 1 TO Moves(1)
  467.                 IF q$ = RIGHT$(Move$(1, lm), 2) THEN cq = 0: ck = 0: kic$ = "kic " + Move$(1, lm) + " "
  468.             NEXT lm
  469.         NEXT cs
  470.     NEXT Castle
  471.     debug$ = nok$ + nrq$ + nrk$ + kic$ + neqs$ + neks$ + qsc$ + ksc$ + "     *"
  472.  
  473.     IF ck THEN AddIt Level, "O-O", 12
  474.     IF cq THEN AddIt Level, "O-O-O", 13
  475.  
  476.     'LOCATE 34 + WorB, 46: PRINT "*"; Castle$; "*";
  477.     'PRINT MID$("K ", ck + 2, 1);
  478.     'PRINT MID$("Q ", cq + 2, 1); cq; ck;
  479.  
  480.     TakeBest Level
  481.  
  482. SUB Debug1
  483.     sr = 32
  484.     r = sr
  485.     c = 4
  486.     FOR t = 1 TO 20
  487.         IF c < 75 THEN
  488.             LOCATE r, c: PRINT SPACE$(8);
  489.             IF t <= Moves(0) THEN
  490.                 LOCATE r, c
  491.                 PRINT Make4$(Move$(0, t)); rjust$(Score(0, t), 4);
  492.             END IF
  493.         END IF
  494.         r = r + 1
  495.         IF r > MaxRow THEN r = sr: c = c + 9
  496.     NEXT t
  497.  
  498. SUB Debug2 ()
  499.     'IF human AND (humanc = WorB) THEN EXIT SUB
  500.     DebugR = DebugR + 1
  501.     IF DebugR > MaxRow THEN
  502.         _DISPLAY
  503.         DebugR = 3: DebugC = 62
  504.         FOR r = 0 TO MaxRow - 2
  505.             LOCATE DebugR + r, DebugC
  506.             PRINT SPACE$(98 - DebugC);
  507.         NEXT r
  508.     END IF
  509.     ts = 0: s = 1
  510.     z$ = ""
  511.     FOR t = 1 TO 3
  512.         ti = TieTo(t)
  513.         z$ = z$ + Make4$(Move$(t - 1, ti)) + rjust$(Score(t - 1, ti), 3) + " "
  514.         ts = ts + Score(t - 1, ti) * s
  515.         's = -s
  516.     NEXT t
  517.     ts = ts - Score
  518.     z$ = z$ + Make4$(m$) + rjust$(Score, 3) + " " + rjust$(ts, 4)
  519.     LOCATE DebugR, DebugC
  520.     PRINT z$; "   ";
  521.     PRINT #7, z$
  522.  
  523. SUB DispText (zr, zc)
  524.     t$ = " RNBQKP"
  525.     LOCATE TextRow(zr), TextCol(zc)
  526.     IF b(zr, zc) > 6 THEN COLOR 0, 7
  527.     PRINT MID$(t$, TextVal(zr, zc) + 1, 1);
  528.     COLOR 7, 0
  529.  
  530. SUB DispTime
  531.     IF Start2& > 0 THEN
  532.         Elapse1! = TIMER - Start1&
  533.         Elapse2! = TIMER - Start2&
  534.         IF Elapse2! > MaxElapse! THEN MaxElapse! = Elapse2!
  535.         'ShowTime 3, Elapse1!, "Game:"
  536.         'ShowTime 4, Elapse2!, "This move:"
  537.         'ShowTime 5, MaxElapse!, "Max move:"
  538.     END IF
  539.  
  540. SUB FadePiece (tfr, tfc, ttr, ttc)
  541.     fr = tfr: fc = tfc: tr = ttr: tc = ttc
  542.     x1 = xc + (fc - 5) * xq
  543.     y1 = yc + (4 - fr) * yq
  544.     x2 = xc + (tc - 5) * xq
  545.     y2 = yc + (4 - tr) * yq
  546.     p = b(tr, tc)
  547.     IF invert THEN p = b(9 - tr, 9 - tc)
  548.     IF p > 6 THEN wb = 1: p = p - 6
  549.     i = p - (wb = 0) * 6
  550.  
  551.     FOR ps = 0 TO 1
  552.         IF ps = 0 THEN
  553.             c = fr + fc: tx = x1: ty = y1
  554.         ELSE
  555.             c = tr + tc: tx = x2: ty = y2
  556.         END IF
  557.         IF c MOD 2 THEN
  558.             LINE (tx, ty)-(tx + xq, ty + yq), boardwhite&, BF
  559.         ELSE
  560.             LINE (tx, ty)-(tx + xq, ty + yq), boardblack&, BF '      black square
  561.             LINE (tx, ty)-(tx + xq, ty + yq), boardwhite&, B '       border
  562.         END IF
  563.     NEXT ps
  564.  
  565.     FOR t = 1 TO c(p, 0)
  566.         tx = x1 + x(p, t) * 2
  567.         ty = y1 + y(p, t) * 2
  568.         LINE (tx, ty)-STEP(1, 1), cp&(c(i, t)), B
  569.     NEXT t
  570.  
  571. SUB HumanMove
  572.     getreal:
  573.     FOR i = 0 TO 1
  574.         IF i = 0 THEN
  575.             rr = 8: cc = 1
  576.             IF invert THEN rr = 9 - rr: cc = 9 - cc
  577.         ELSE
  578.             rr = fr: cc = fc
  579.         END IF
  580.         IF invert THEN rr = 9 - rr: cc = 9 - cc
  581.         mx = _MOUSEX
  582.         my = _MOUSEY
  583.         DO
  584.             x1 = xc - 4 * xq
  585.             y1 = yc - 4 * yq
  586.             x2 = xc + 4 * xq
  587.             y2 = yc + 4 * yq
  588.             LINE (x1, y1)-(x2, y2), boardwhite&, B
  589.             'LOCATE 1, 1: PRINT "Move ";
  590.             x1 = xc + (cc - 5) * xq
  591.             x2 = xc + (cc - 4) * xq
  592.             y1 = yc + (rr - 5) * yq
  593.             y2 = yc + (rr - 4) * yq
  594.             wc& = POINT(x1 + 1, y1 + 1)
  595.             FOR zz = 0 TO 1
  596.                 FOR zx = 1 TO 4
  597.                     IF zz THEN tc& = wc& ELSE tc& = red&
  598.                     LINE (x1 + zx, y1 + zx)-(x2 - zx, y2 - zx), tc&, B
  599.                 NEXT zx
  600.                 _DISPLAY
  601.                 _DELAY .01
  602.             NEXT zz
  603.             tmx = _MOUSEX
  604.             tmy = _MOUSEY
  605.             IF (ABS(mx - tmx) > 8) OR (ABS(my - tmy) > 8) THEN
  606.                 IF tmx > mx THEN cc = cc + 1
  607.                 IF tmx < mx THEN cc = cc - 1
  608.                 IF tmy > my THEN rr = rr + 1
  609.                 IF tmx < my THEN rr = rr - 1
  610.             END IF
  611.             ScanKey
  612.             IF tbf THEN EXIT SUB
  613.             IF LEN(i$) = 2 THEN
  614.                 kk = ASC(RIGHT$(i$, 1))
  615.                 cc = cc + (kk = 75) - (kk = 77) '                    left right
  616.                 rr = rr + (kk = 72) - (kk = 80) '                    up down
  617.             END IF
  618.             IF rr < 1 THEN rr = 1
  619.             IF rr > 8 THEN rr = 8
  620.             IF cc < 1 THEN cc = 1
  621.             IF cc > 8 THEN cc = 8
  622.         LOOP UNTIL (i$ = Enter$) OR (i$ = "d")
  623.         IF invert THEN rr = 9 - rr: cc = 9 - cc
  624.         IF i = 0 THEN
  625.             fr = rr: fc = cc
  626.         ELSE
  627.             tr = rr: tc = cc
  628.         END IF
  629.     NEXT i
  630.     fs$ = MID$("abcdefgh", fc, 1) + LTRIM$(STR$(9 - fr))
  631.     ts$ = MID$("abcdefgh", tc, 1) + LTRIM$(STR$(9 - tr))
  632.     'IF fs$ = ts$ THEN GOTO getreal
  633.     m$ = fs$ + ts$
  634.     IF m$ = "e1g1" THEN m$ = "O-O"
  635.     IF m$ = "e1c1" THEN m$ = "O-O-O"
  636.     IF m$ = "e8g1" THEN m$ = "O-O"
  637.     IF m$ = "e8c1" THEN m$ = "O-O-O"
  638.  
  639. SUB colorassign
  640.     black& = cp&(0)
  641.     boardwhite& = cp&(1)
  642.     boardblack& = cp&(2)
  643.     red& = _RGB32(255, 0, 0)
  644.     green& = cp&(8)
  645.     blue& = cp&(9)
  646.     white& = cp&(10)
  647.  
  648. SUB Init
  649.     IF highres THEN
  650.         xm = 1280: ym = 800
  651.     ELSE
  652.         xm = 800: ym = 600
  653.     END IF
  654.     SCREEN _NEWIMAGE(xm, ym, 32)
  655.     _DELAY .3
  656.     IF highres THEN _SCREENMOVE 0, 0 ELSE _SCREENMOVE 472, 20
  657.     MaxRow = ym \ 16 - 1
  658.     _DELAY .3
  659.  
  660.     f$ = "chess3.png": i& = _LOADIMAGE(f$): _ICON i&: _FREEIMAGE i&
  661.     _DELAY .3
  662.  
  663.     RESTORE rgb
  664.     FOR p = 0 TO 15
  665.         READ PalNum, r, g, b, Desc$
  666.         cp&(p) = _RGB32(r * 4, g * 4, b * 4)
  667.     NEXT p
  668.     colorassign '                                                    red&, green&, etc, easier to use than palette numbers
  669.  
  670.     RANDOMIZE TIMER '                                                seed generator
  671.     Move = 0
  672.     WorB = 1 '                                                       white=1, black=0
  673.     speed = 3
  674.     q = 28
  675.     q = q * 2
  676.     xq = q: yq = q
  677.     xc = 248: yc = 254 '                                             center of board
  678.  
  679.     Enter$ = CHR$(13)
  680.     Esc$ = CHR$(27) '                                                to quit program
  681.     lf$ = CHR$(10) '                                                 line feed
  682.     crlf$ = Enter$ + lf$
  683.  
  684.     Castle$ = SPACE$(4) '                                            flags QKQK (B then W)
  685.  
  686.     mess$ = ""
  687.     RESTORE PiecePatterns '                                          bit images
  688.     FOR p = 1 TO 6 ' RNBQKP
  689.         PRINT MID$("RNBQKP", p, 1); " ";
  690.         n = 0
  691.         FOR y = 0 TO 21 ' 22 rows
  692.             READ d$
  693.             p1 = INSTR(d$ + "X", "X") '                              find first "on" bit
  694.             FOR t = LEN(d$) TO 1 STEP -1 '                           find last "on" bit
  695.                 IF MID$(d$, t, 1) = "X" THEN
  696.                     p2 = t
  697.                     EXIT FOR
  698.                 END IF
  699.             NEXT t
  700.             FOR x = p1 TO p2
  701.                 pixel = INSTR(".X", MID$(d$, x, 1))
  702.                 n = n + 1
  703.                 IF pixel = 2 THEN c = 3 ELSE c = 4
  704.                 x(p, n) = x + 1
  705.                 y(p, n) = y + 2
  706.                 c(p, n) = c
  707.                 IF pixel = 2 THEN c = 5 ELSE c = 6
  708.                 c(p + 6, n) = c
  709.             NEXT x
  710.         NEXT y
  711.         c(p, 0) = n
  712.         FOR scram = 1 TO 256 '                                       scramble (moves nicer)
  713.             c1 = RND * (c(p, 0) - 1) + 1 '                           any bit
  714.             c2 = RND * (c(p, 0) - 1) + 1 '                           any other bit
  715.             SWAP x(p, c1), x(p, c2)
  716.             SWAP y(p, c1), y(p, c2)
  717.             SWAP c(p, c1), c(p, c2) '                                black
  718.             SWAP c(p + 6, c1), c(p + 6, c2) '                        white
  719.         NEXT scram
  720.     NEXT p
  721.  
  722.     RESTORE Legal '                                                  define how piece moves
  723.     FOR p = 1 TO 6 '                                                 RNBQKP
  724.         READ p$ '                                                    piece, not saved
  725.         FOR t = 0 TO 7 '                                             8 each
  726.             READ mp$(p, t) '                                         mp (move piece)
  727.         NEXT t
  728.     NEXT p
  729.  
  730.     RESTORE SetUp '                                                  initial board position
  731.     FOR r = 8 TO 1 STEP -1 '                                         row
  732.         FOR c = 1 TO 8 '                                             column
  733.             READ b(r, c)
  734.             o(r, c) = b(r, c)
  735.         NEXT c
  736.     NEXT r
  737.  
  738.     elim$ = " ,"
  739.     gm = 0: n = 0
  740.     IF LEN(GameFile$) > 0 THEN ReadGame
  741.     gm = 0
  742.  
  743.     f = f + 1
  744.     f$ = "chess" + LTRIM$(STR$(f))
  745.     OPEN f$ + ".alg" FOR OUTPUT AS #1 '                              algrebraic moves
  746.     OPEN "debug.txt" FOR OUTPUT AS #7
  747.     'MasterLevel = VAL(COMMAND$) '                                    only 4 really tested....
  748.     'GameFile$ = COMMAND$
  749.     'IF _FILEEXISTS(GameFile$) THEN ReadGame ELSE GameFile$ = ""
  750.     MasterLevel = VAL(COMMAND$)
  751.     IF MasterLevel = 0 THEN MasterLevel = 4
  752.     debug = true '                                                   someday I may turn this off
  753.  
  754.     m$ = "(w)hite  (b)lack  (n)one"
  755.     r = _HEIGHT \ 32: c = _WIDTH \ 16
  756.     CLS: LOCATE r, c - LEN(m$) \ 2: PRINT m$;
  757.     DO: _LIMIT 10
  758.         i$ = INKEY$
  759.         IF i$ = "" THEN i$ = " "
  760.         IF i$ = Esc$ THEN SYSTEM
  761.         p = INSTR("bwn", i$)
  762.     LOOP UNTIL p
  763.     IF p = 3 THEN
  764.         human = 0 '                                                  press n for none (watch computer play)
  765.     ELSE
  766.         human = 1
  767.         humanc = p - 1 '                                             0 black, 1 white
  768.         IF humanc = 0 THEN invert = 1 '                              if black, flip board to have black at bottom
  769.     END IF
  770.     CLS
  771.     PlotAll
  772.  
  773.     'opening = 1
  774.     'RESTORE o1
  775.  
  776. SUB KeyGet
  777.     EXIT SUB
  778.     sr = CSRLIN: sc = POS(0)
  779.     DO
  780.         ScanKey
  781.         star = star XOR 1
  782.         IF i$ > "" THEN star = 0
  783.         LOCATE sr, sc
  784.         IF LEN(GameFile$) = 0 THEN PRINT CHR$(32 + star * 10);
  785.     LOOP UNTIL i$ > ""
  786.     IF i$ = "s" THEN WaitForKey = false
  787.  
  788. FUNCTION Make4$ (t$)
  789.     Make4$ = LEFT$(t$ + SPACE$(4), 4)
  790.  
  791. SUB MoveIt (m$, real)
  792.     IF m$ = "res" THEN EXIT SUB '                                    resign?
  793.     fs$ = LEFT$(m$, 2) '                                             from square
  794.     ts$ = RIGHT$(m$, 2) '                                            to square
  795.     tzz = 1 - (LEFT$(m$, 1) = "O") '                                 two moves for a castle
  796.     FOR pass = 1 TO tzz
  797.         IF m$ = "O-O" THEN '                                         castle Kingside
  798.             IF WorB = 1 THEN '                                       white
  799.                 IF pass = 1 THEN '                                   first move of KS castle
  800.                     fs$ = "e1": ts$ = "g1"
  801.                 ELSE ' else 2nd
  802.                     fs$ = "h1": ts$ = "f1"
  803.                 END IF
  804.             ELSE ' black castle
  805.                 IF pass = 1 THEN
  806.                     fs$ = "e8": ts$ = "g8"
  807.                 ELSE
  808.                     fs$ = "h8": ts$ = "f8"
  809.                 END IF
  810.             END IF
  811.         END IF
  812.         IF m$ = "O-O-O" THEN '                                       castle Queenside
  813.             IF WorB THEN '                                           white
  814.                 IF pass = 1 THEN
  815.                     fs$ = "e1": ts$ = "c1"
  816.                 ELSE
  817.                     fs$ = "a1": ts$ = "d1"
  818.                 END IF
  819.             ELSE
  820.                 IF pass = 1 THEN
  821.                     fs$ = "e8": ts$ = "c8"
  822.                 ELSE
  823.                     fs$ = "a8": ts$ = "d8"
  824.                 END IF
  825.             END IF
  826.         END IF
  827.         fr = VAL(RIGHT$(fs$, 1)) '                                   from row
  828.         fc = INSTR("abcdefgh", LEFT$(fs$, 1)) '                      from column
  829.         pm = b(fr, fc) '                                             piece to move
  830.         p = pm + (pm > 6) * 6
  831.         tr = VAL(RIGHT$(ts$, 1)) '                                   to row
  832.         tc = INSTR("abcdefgh", LEFT$(ts$, 1)) '                      to column
  833.         b(tr, tc) = pm '                                             move piece in array
  834.         b(fr, fc) = 0 '                                              blank old array spot
  835.         IF real THEN
  836.             IF b(r, c) = o(r, c) THEN o(r, c) = -1
  837.             FadePiece fr, fc, tr, tc
  838.             IF p = King THEN MID$(Castle$, WorB * 2 + 1, 2) = "XX"
  839.             IF p = Rook THEN
  840.                 IF WorB = 0 THEN
  841.                     IF (fr = 8) AND (fc = 1) THEN MID$(Castle$, 1, 1) = "X"
  842.                     IF (fr = 8) AND (fc = 8) THEN MID$(Castle$, 2, 1) = "X"
  843.                 ELSE
  844.                     IF (fr = 1) AND (fc = 1) THEN MID$(Castle$, 3, 1) = "X"
  845.                     IF (fr = 1) AND (fc = 8) THEN MID$(Castle$, 4, 1) = "X"
  846.                 END IF
  847.             END IF
  848.         END IF
  849.         IF (p = Pawn) AND ((tr = 1) OR (tr = 8)) THEN
  850.             b(tr, tc) = Queen - (pm > 6) * 6 '                       promote to queen
  851.             IF real THEN FadePiece tr, tc, tr, tc '                  show queen
  852.         END IF
  853.     NEXT pass
  854.  
  855. SUB PlotAll
  856.     IF LEN(GameFile$) > 0 THEN
  857.         LOCATE 3, 40 - LEN(GameFile$) \ 2
  858.         PRINT GameFile$;
  859.     END IF
  860.     FOR zr = 1 TO 8
  861.         FOR zc = 1 TO 8
  862.             FadePiece zr, zc, zr, zc
  863.         NEXT zc
  864.     NEXT zr
  865.     'CIRCLE (xc, yc), 100, red&
  866.  
  867.     r = _RED32(boardwhite&) \ 2
  868.     g = _GREEN32(boardwhite&) \ 2
  869.     b = _BLUE32(boardwhite&) \ 2
  870.     COLOR _RGB32(r, g, b)
  871.     FOR i = 1 TO 8 '                                                 legend
  872.         IF invert THEN z = i ELSE z = 9 - i
  873.         n$ = LTRIM$(STR$(z))
  874.         IF invert THEN z = 9 - i ELSE z = i
  875.         a$ = MID$("abcdefgh", z, 1)
  876.         nx = xc - 4 * xq - 12
  877.         ny = yc + (i - 4) * yq - 34
  878.         ax = xc + (i - 5) * xq + 22
  879.         ay = yc + 4 * yq + 3
  880.         _PRINTSTRING (nx, ny), n$
  881.         _PRINTSTRING (ax, ay), a$
  882.     NEXT i
  883.     COLOR white&
  884.  
  885. SUB ReadGame
  886.     DIM g$(500)
  887.     CLS
  888.     OPEN GameFile$ FOR INPUT AS #8
  889.     WHILE NOT (EOF(8))
  890.         INPUT #8, mn, m1$, m2$
  891.         gm = gm + 1: g$(gm) = LTRIM$(m1$)
  892.         gm = gm + 1: g$(gm) = LTRIM$(m2$)
  893.         PRINT m1$; "*"; m2$
  894.     WEND
  895.     CLOSE #8
  896.     _DISPLAY
  897.     SLEEP
  898.     CLS
  899.     _DISPLAY
  900.  
  901. SUB Recurse (Level)
  902.     DispTime
  903.     IF Level = MasterLevel THEN EXIT SUB
  904.     'IF human AND (humanc = WorB) AND (Level = 2) THEN EXIT SUB
  905.  
  906.     FOR t = 1 TO Moves(Level - 1)
  907.         WorB = SaveWorB
  908.         IF (Level MOD 2) = 1 THEN WorB = WorB XOR 1
  909.         TieTo(Level) = t
  910.  
  911.         IF (Score(0, t) > -777) THEN
  912.             BoSave Level
  913.             m$ = Move$(Level - 1, t)
  914.             MoveIt m$, 0
  915.             t$ = rjust$(Moves(Level - 1), 3)
  916.             t$ = t$ + rjust$(t, 4) + " "
  917.             t$ = t$ + Make4$(m$)
  918.             t$ = t$ + rjust$(Score(Level - 1, t), 5)
  919.             ShowMe Level + 1, 24, t$
  920.             CheckBoard Level
  921.             Recurse Level + 1
  922.             TakeBest Level
  923.             Score = Score(Level, 1)
  924.             levm1 = Level - 1
  925.             i = Index
  926.             IF Score(levm, i) <> -777 THEN Score(levm1, i) = Score(levm1, i) - Score
  927.             IF Level = (MasterLevel - 1) THEN Debug2
  928.             BoRestore Level
  929.         END IF
  930.     NEXT t
  931.     ScanKey
  932.  
  933. FUNCTION rjust$ (t, n)
  934.     rjust$ = RIGHT$("   " + STR$(t), n)
  935.  
  936. SUB ScanKey
  937.     i$ = INKEY$
  938.     IF LEN(i$) = 1 THEN
  939.         IF i$ = Enter$ THEN EXIT SUB
  940.         IF i$ = Esc$ THEN CLOSE: SYSTEM
  941.         c = INSTR("123456789ABCDEF", i$)
  942.         IF c > 0 THEN cp&(c) = _RGB32(RND * 255, RND * 255, RND * 255): colorassign: PlotAll
  943.         IF i$ = "a" THEN OnAuto = NOT (OnAuto)
  944.         IF i$ = "i" THEN invert = invert XOR 1: PlotAll
  945.         IF i$ = "p" THEN
  946.             ShowMe 1, 72, "NoPause"
  947.             ShowMe 1, 72, "       "
  948.         END IF
  949.         IF i$ = "s" THEN SHELL _DONTWAIT "notepad debug.txt"
  950.         IF i$ = "t" THEN tbf = 1
  951.         IF i$ = "z" THEN
  952.             sillyf = sillyf XOR 1
  953.             IF sillyf = 0 THEN PlotAll
  954.         END IF
  955.         i$ = ""
  956.     END IF
  957.     IF sillyf AND (rflag = 0) THEN silly
  958.     IF rflag = 0 THEN _DISPLAY
  959.  
  960. SUB ShowAlgebraic (m$)
  961.     IF WorB THEN '                                                  white=1, black=0
  962.         Move = Move + 1 '                                            number the moves
  963.         PRINT #1, RIGHT$("  " + STR$(Move), 3);
  964.         PRINT #1, RIGHT$(SPACE$(10) + m$, 7);
  965.         MoveLog$(Move) = SPACE$(15)
  966.         MID$(MoveLog$(Move), 1, 3) = rjust$(Move, 3)
  967.         MID$(MoveLog$(Move), 5, LEN(m$)) = m$
  968.     ELSE
  969.         MID$(MoveLog$(Move), 11, LEN(m$)) = m$
  970.         PRINT #1, " "; m$
  971.         IF (Move MOD 5) = 0 THEN PRINT #1, ""
  972.     END IF
  973.  
  974.     BeginAt = Move - 18
  975.     IF BeginAt < 1 THEN BeginAt = 1
  976.     dr = 1
  977.     FOR t = BeginAt TO Move
  978.         ShowMe dr + 1, 1, MoveLog$(t)
  979.         dr = dr + 1
  980.     NEXT t
  981.  
  982. SUB ShowAsText (br)
  983.     FOR zr1 = 1 TO 8
  984.         FOR zc1 = 1 TO 8
  985.             zr2 = (10 - zr1) * 2 + 3
  986.             zc2 = zc1 * 3 + 17 + br * 32
  987.             tp = b(zr1, zc1)
  988.             IF tp = 0 THEN
  989.                 z$ = "  "
  990.             ELSEIF tp < 7 THEN
  991.                 z$ = "B" + MID$("RNBQKP", tp, 1)
  992.             ELSE
  993.                 z$ = "W" + MID$("RNBQKP", tp - 6, 1)
  994.             END IF
  995.             ShowMe zr2, zc2, z$
  996.         NEXT zc1
  997.     NEXT zr1
  998.  
  999. SUB ShowMe (dr, dc, t$)
  1000.     EXIT SUB
  1001.     sr = CSRLIN '                                                    save row
  1002.     sc = POS(0) '                                                    save column
  1003.     IF (dr > 0) AND (dr < MaxRow) AND (dc > 0) AND (dc < 76) THEN
  1004.         LOCATE dr, dc '                                              display row & column
  1005.         PRINT t$;
  1006.     END IF
  1007.     IF NOT (OnAuto) THEN KeyGet
  1008.     LOCATE sr, sc '                                                  restore to old location
  1009.     '   IF Pause THEN SLEEP
  1010.  
  1011. SUB ShowTime (trow, t!, Desc$)
  1012.     s! = t!
  1013.     SELECT CASE s!
  1014.         CASE IS > 3600
  1015.             unit$ = "h"
  1016.             s! = s! / 3600
  1017.         CASE IS > 60
  1018.             unit$ = "m"
  1019.             s! = s! / 60
  1020.         CASE ELSE
  1021.             unit$ = "s"
  1022.     END SELECT
  1023.     trow = trow + 3
  1024.     LOCATE trow, 34 - LEN(Desc$): PRINT Desc$;
  1025.     LOCATE trow, 34
  1026.     PRINT USING "###.#"; s!;
  1027.     PRINT unit$
  1028.  
  1029. SUB TakeBest (Level)
  1030.     FOR scram = 0 TO 99
  1031.         s1 = RND * (Moves(Level) - 1) + 1
  1032.         s2 = RND * (Moves(Level) - 1) + 1
  1033.         SWAP Score(Level, s1), Score(Level, s2)
  1034.         SWAP Move$(Level, s1), Move$(Level, s2)
  1035.         SWAP Index(Level, s1), Index(Level, s2)
  1036.     NEXT scram
  1037.  
  1038.     passes = 0
  1039.     ReSort:
  1040.     Score = -999 ' assume no moves
  1041.     DO
  1042.         Sorted = true
  1043.         FOR s = 2 TO Moves(Level)
  1044.             IF Score(Level, s - 1) < Score(Level, s) THEN
  1045.                 Sorted = false
  1046.                 SWAP Score(Level, s - 1), Score(Level, s)
  1047.                 SWAP Move$(Level, s - 1), Move$(Level, s)
  1048.                 SWAP Index(Level, s - 1), Index(Level, s)
  1049.             END IF
  1050.         NEXT s
  1051.     LOOP UNTIL Sorted
  1052.  
  1053.     m$ = Move$(Level, 1)
  1054.     Score = Score(Level, 1)
  1055.     Index = Index(Level, 1)
  1056.  
  1057.     'IF Level = -1 THEN
  1058.     '    FOR lb = 0 TO 2 '                                            stop repeats
  1059.     '        IF INSTR(MoveLog$(Move - lb), m$) THEN
  1060.     '            Score(Level, 1) = Score(Level, 2) - 1 '              best = 2nd best-1
  1061.     '            passes = passes + 1
  1062.     '            IF passes < 5 THEN GOTO ReSort '                     repeat may be only move
  1063.     '        END IF
  1064.     '    NEXT lb
  1065.     'END IF
  1066.  
  1067.     IF Level = 1 THEN
  1068.         IF Score = -777 THEN '                                       in check, no escape
  1069.             mess$ = "Mate"
  1070.         ELSEIF Score = -999 THEN '                                   no moves
  1071.             mess$ = "Stalemate"
  1072.         END IF
  1073.     END IF
  1074.  
  1075.     IF (Level = 1) AND (Score = 777) THEN Score(0, TieTo(1)) = -777
  1076.  
  1077. FUNCTION TextCol (xc)
  1078.     TextCol = (xc - 1) * 2 + 25
  1079.  
  1080. FUNCTION TextRow (xr)
  1081.     TextRow = (8 - xr) * 1 + 8
  1082.  
  1083. FUNCTION TextVal (xr, xc)
  1084.     i = b(xr, xc)
  1085.     i = i + (i > 6) * 6
  1086.     TextVal = i
  1087.  
  1088. SUB TryMove (Level, fr, fc) '                                        from row, from column
  1089.     mp = b(fr, fc)
  1090.     IF mp = 0 THEN END
  1091.     mc = -(mp > 6) - (mp = 0) * 2 '                                  moving color
  1092.     IF mc = 2 THEN END
  1093.     mp = mp + (mp > 6) * 6
  1094.     IF mc = 1 THEN s = -1 ELSE s = 1 '                               direction a pawn moves
  1095.  
  1096.     FOR n = 0 TO 7 '                                                 possible 8 dirs
  1097.         udlr$ = mp$(mp, n) '                                         up/down/left/right
  1098.         IF udlr$ = "0000" THEN EXIT FOR '                            added 2Jan95
  1099.         du = VAL(MID$(udlr$, 1, 1)) '                                direction up
  1100.         dd = VAL(MID$(udlr$, 2, 1)) '                                direction down
  1101.         dl = VAL(MID$(udlr$, 3, 1)) '                                direction left
  1102.         dr = VAL(MID$(udlr$, 4, 1)) '                                direction right
  1103.         IF mp <> Knight THEN '                                       not knight
  1104.             du = SGN(du) * s '                                       one square at a time
  1105.             dd = SGN(dd) * s
  1106.             dl = SGN(dl) * s
  1107.             dr = SGN(dr) * s
  1108.         END IF
  1109.         IF INSTR(udlr$, "8") THEN TrySq = 8 ELSE TrySq = 1
  1110.         IF (mp = Pawn) AND (n = 0) THEN '                            pawn first move?
  1111.             IF (fr = 2) AND (WorB = 1) THEN TrySq = 2 '              gambit for white
  1112.             IF (fr = 7) AND (WorB = 0) THEN TrySq = 2 '              gambit for black
  1113.         END IF
  1114.         tr = fr: tc = fc '                                           row, column
  1115.         IF TrySq = 0 THEN END
  1116.         FOR sq = 1 TO TrySq '                                        up to 8 loops
  1117.             cap = false
  1118.             Score = 0 '                                              must init
  1119.             tr = tr - du + dd '                                      row=row-up+down
  1120.             tc = tc - dl + dr '                                      column=column-left+right
  1121.             IF (tr < 1) OR (tr > 8) OR (tc < 1) OR (tc > 8) THEN EXIT FOR
  1122.             cp = b(tr, tc) '                                         capture piece
  1123.             cc = -(cp > 6) - (cp = 0) * 2 '                          capture color
  1124.             cp = cp + (cp > 6) * 6
  1125.             IF mc = cc THEN '                                        own piece!
  1126.                 EXIT FOR
  1127.             ELSEIF (mc XOR 1) = cc THEN '                            capture
  1128.                 IF (mp = Pawn) AND (n = 0) THEN EXIT FOR ' no diag, no cap!
  1129.                 cap = true
  1130.                 '                 RNBQKP
  1131.                 Score = VAL(MID$("533901", cp, 1)) * 10
  1132.                 IF (Score > 0) AND (Level = 0) THEN Score = Score + 2
  1133.                 IF Score = 0 THEN Score = 777 '                      king capture
  1134.                 ' IF redo AND (Score = 777) THEN Score = 25
  1135.             ELSE
  1136.                 IF (mp = Pawn) AND (n > 0) THEN EXIT FOR
  1137.             END IF
  1138.             IF mp = Pawn THEN
  1139.                 IF (tr = 1) OR (tr = 8) THEN '                       promote pawn
  1140.                     IF Score <> 777 THEN Score = Score + 99
  1141.                 END IF
  1142.             END IF
  1143.  
  1144.             ' usually not good to be moving the King
  1145.             IF mp = King THEN Score = Score - 4
  1146.  
  1147.             ' small plus for king moving out of check
  1148.             InCheck = (mc = SaveWorB) AND check
  1149.             IF (mp = King) AND InCheck THEN Score = Score + 2
  1150.  
  1151.             ' leave king cap scores, also normal bonuses if in check
  1152.             IF (Score <> 777) AND (NOT (InCheck)) AND (mp <> King) THEN
  1153.                 dis1 = ABS(fr - okr) + ABS(fc - okc) '                 get closer to king
  1154.                 dis2 = ABS(tr - okr) + ABS(tc - okc)
  1155.                 ' IF dis2 < dis1 THEN Score = Score + (dis1 - dis2)
  1156.                 Score = Score + dis1 - dis2
  1157.  
  1158.                 IF Move < 30 THEN
  1159.                     dir = SGN((fr - tr) * s)
  1160.                     IF dir = 1 THEN Score = Score + 2 '              move ahead at begin&mid
  1161.                 END IF
  1162.  
  1163.                 ' priority to getting a piece first moved
  1164.                 IF mp <> Rook THEN
  1165.                     IF b(fr, fc) = o(fr, fc) THEN Score = Score + 1
  1166.                 END IF
  1167.  
  1168.                 ' priority to getting a piece off the bottom rank
  1169.                 IF (fr = 1) AND (tr > 1) AND (WorB = 1) THEN Score = Score + 1
  1170.                 IF (fr = 8) AND (tf < 8) AND (WorB = 0) THEN Score = Score + 1
  1171.             END IF
  1172.  
  1173.             fs$ = MID$("abcdefgh", fc, 1) + CHR$(48 + fr) '          from square
  1174.             ts$ = MID$("abcdefgh", tc, 1) + CHR$(48 + tr) '          to square
  1175.             AddIt Level, fs$ + ts$, Score
  1176.             IF cap AND (mp <> Pawn) THEN EXIT FOR '                  stop looking
  1177.         NEXT sq
  1178.     NEXT n
  1179.  
  1180. SUB silly STATIC
  1181.     PlotAll
  1182.     br = 255
  1183.     zz = (zz + 1) MOD 50: IF zz = 1 THEN r! = RND: g! = RND: b! = RND
  1184.     x1 = xc - 4 * xq
  1185.     y1 = yc - 4 * yq
  1186.     x2 = x1 + 8 * xq
  1187.     y2 = y1 + 8 * yq
  1188.     'LINE (x1, y1)-(x2, y2), boardwhite&
  1189.     FOR sy = y1 TO y2
  1190.         FOR sx = x1 TO x2
  1191.             p& = POINT(sx, sy)
  1192.             IF p& = boardwhite& THEN
  1193.                 z = ABS((sx - xc - xq \ 2) * (sy - yc - yq \ 2))
  1194.                 PSET (sx, sy), _RGB32(br * SIN(.1 * r! * z + zz), br * SIN(.155 * g! * z + zz), br * SIN(2 * b! * z + zz))
  1195.             END IF
  1196.     NEXT sx: NEXT sy
  1197.  
  1198. SUB SaveForTakeBack STATIC
  1199.     FOR i = 10 TO 1 STEP -1
  1200.         FOR r = 1 TO 8
  1201.             FOR c = 1 TO 8
  1202.                 tb(r, c, i) = tb(r, c, i - 1)
  1203.             NEXT c
  1204.         NEXT r
  1205.     NEXT i
  1206.     FOR r = 1 TO 8
  1207.         FOR c = 1 TO 8
  1208.             tb(r, c, 0) = b(r, c)
  1209.         NEXT c
  1210.     NEXT r
  1211.     tbc = tbc + 1
  1212.     IF tbc > 10 THEN tbc = 10
  1213.  
  1214. SUB takeback
  1215.     IF tbc < 2 THEN EXIT SUB
  1216.     SOUND 777, 2
  1217.     FOR r = 1 TO 8
  1218.         FOR c = 1 TO 8
  1219.             b(r, c) = tb(r, c, 2)
  1220.         NEXT c
  1221.     NEXT r
  1222.     FOR i = 0 TO 9
  1223.         FOR r = 1 TO 8
  1224.             FOR c = 1 TO 8
  1225.                 tb(r, c, i) = tb(r, c, i + 1)
  1226.             NEXT c
  1227.         NEXT r
  1228.     NEXT i
  1229.     tbc = tbc - 1
  1230.  
clockx.png
* clockx.png (Filesize: 11.62 KB, Dimensions: 512x512, Views: 207)
clockx2.png
* clockx2.png (Filesize: 21.49 KB, Dimensions: 512x512, Views: 198)
chess3.png
* chess3.png (Filesize: 1.85 KB, Dimensions: 225x225, Views: 208)
« Last Edit: January 29, 2020, 01:31:41 am by Richard Frost »
It works better if you plug it in.

Offline Richard Frost

  • Seasoned Forum Regular
  • Posts: 316
  • Needle nardle noo. - Peter Sellers
    • View Profile
Eh? (Canadian)
« Reply #17 on: January 29, 2020, 12:51:47 am »
Yes, I think the initial version only played itself, which is the ideal
way to improve the "smarts" of it.  The newest version posted lets
the user pick a side, or "none" for automation.  The purpose of
the initial post is to show the guts of an operating engine - the
approach I took with moving pieces legally and whatnot.  I still
don't even have the mouse working - arrow keys to move. 

I don't know how anyone got the notion that I created this in a day!
I got it to run in QB64 in a day.  It's old QB4.5 code of mine that
probably took me at least a  month to write.

How does one choose which resolution to use?  I had this in 1024*768
for awhile, but I like to see other windows, hence this 800*600.  The old
640*480 is too limiting - no room for big graphics AND text.  It's a problem
I never encounted with old QB4.5 - what to choose!  What factors do you
folk consider to choose a mode?  Or should everything be resizable?
« Last Edit: January 29, 2020, 02:04:53 am by Richard Frost »
It works better if you plug it in.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: A 90% complete chess engine
« Reply #18 on: January 29, 2020, 10:27:54 am »
Hi Richard Frost,

The comments about doing chess program in a day were meant for STxAxTIC whose post started this thread.

Hey! Your new one works (maybe I just needed to download png for icon file like for this one for last one. no, no png was provided) and it has a nicely sized board (800 x 600 is nice size until out grows all the options you start adding) and the vital question of doing something different with white squares has been answered! :D

 
Chess R Frost.PNG


So the AI calculates moves but you still have to press enter to get the oppositions pieces moved (after you see the blinking squares).

Hmm... how would plasma look for Black squares :)
« Last Edit: January 29, 2020, 10:42:02 am by bplus »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: A 90% complete chess engine
« Reply #19 on: January 29, 2020, 10:31:36 am »
Who wants a chess board that looks like half the tiles are high on mushrooms?  White/Red on Black is fine for me, as it seems less distracting and non-seizure inducing.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: A 90% complete chess engine
« Reply #20 on: January 29, 2020, 11:53:58 am »
Who wants a chess board that looks like half the tiles are high on mushrooms?  White/Red on Black is fine for me, as it seems less distracting and non-seizure inducing.

One is not stuck with mushrooms :D and it's not like he doesn't know silly ;-)
Code: QB64: [Select]
  1. sillyf = 1 '                                            Moire effect, toggle with "z", or just default this to 0
  2.  

Offline Richard Frost

  • Seasoned Forum Regular
  • Posts: 316
  • Needle nardle noo. - Peter Sellers
    • View Profile
Re: A 90% complete chess engine
« Reply #21 on: January 29, 2020, 12:51:54 pm »
Yes, the graphics are a bit distracting, until one gets used to it.  Normally I *do* have
it turned off.  I set the silly flag in the upload to make it easier for everyone to see
the mayhem without having to read or change any code. 

I saw a Queen jump across pawns to eat the other Queen recently....hope that bug isn't in
the upload.  And I'm wrong about the castling, it's still wonky. 

"Bugs spell job security." 
It works better if you plug it in.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: A 90% complete chess engine
« Reply #22 on: January 29, 2020, 01:23:18 pm »
Quote
"Bugs spell job security."

LOL played a decent game with White Castling, the moves see farther ahead than I which isn't saying too much.

Offline romichess

  • Forum Regular
  • Posts: 145
    • View Profile
Re: A 90% complete chess engine
« Reply #23 on: January 29, 2020, 05:02:58 pm »
Now that it works it is more interesting! :)

I was wondering how many moves deep my engine RomiChess would have to see in order to win. I started off RomiChess at 2 moves deep. Note that finishing off capture sequences is part of a 2 ply search and is hard coded. RomiChess played the black pieces. At 2 ply deep RomiChess plays each move instantly.

1. d3 e5 2. c3 Bc5 3. Be3 Bxe3 4. fxe3 Qh4+ 5. Kd2 Ne7 6. g3 Qf6 7. Qe1 Qb6
8. b3 Rf8 9. Bg2 Nbc6 10. Nf3 Nf5 11. d4 Qa5 12. Nxe5 Nxe5 13. dxe5 Qxe5
14. e4 Nd6 15. Na3 Nxe4+ 16. Bxe4 Qxe4 17. Rf1 d5 18. Rf4 Qe7 19. Rd4 Qxa3
20. Qf2 Qb2+ 21. Kd1 Qxa1+ 22. Kd2 Qxa2+ 23. Kd1 Qxb3+ 24. Kc1 Qxc3+ 25.
Kb1 Bf5+ 26. Ka2 Be4 27. e3 c5 28. Ra4 Qe5 29. Qb2 Qxb2+ 30. Kxb2 Ke7 31.
Ra5 Rfc8 32. Ra1 Ke6 33. h3 Ke5 34. Ra4 a5 35. Ra1 b5 36. Ra3 a4 37. Ra1 b4
38. Ra2 a3+ 39. Kb3 h5 40. Ra1 Re8 41. Ra2 Re7 42. Ra1 Rae8 43. Ra2 Rd8 44.
h4 Rde8 45. Ra1 Re6 46. Ra2 R8e7 47. Ra1 Rg6 48. Ra2 Rxg3 49. Re2 Rg1 50.
Ra2 Re1 51. Rd2 Rxe3+ 52. Ka4 Re1 53. Ra2 Bd3 54. Rd2 Kd4 55. Ra2 Rh1 56.
Rd2 Rxh4 57. Ra2 Rh1 58. Rd2 Rhe1 59. Ra2 Re8 60. Rd2 g5 61. Ra2 f5 62. Rd2
f4 63. Ra2 f3 64. Rd2 R8e7 65. Ra2 Bf5 66. Rd2+ Ke5 67. Ra2 Bd3 68. Rd2 Be4
69. Ra2 Bf5 70. Rd2 Re8 71. Ra2 Kd4 72. Rd2+ Bd3 73. Ra2 R8e7 74. Rd2 g4
75. Ra2 h4 76. Rd2 Re8 77. Ra2 h3 78. Rd2 g3 79. Ra2 f2 80. Rxf2 gxf2 81.
Ka5 f1=Q 82. Kb6 a2 83. Kc7 a1=Q 84. Kc6 h2 85. Kc7 h1=Q 86. Kb7 b3 87. Kc6
Qa7 88. Kd6 Qf6# 0-1

I will be doing more with my chess tutorial in the coming days. Maybe I'll just steal this interface for my tutorial! :)

P.S. Romi tried to castle on move 8 so I just moved 8 ... Rf8 instead. Please do not think that Romi made that terrible move on its own volition. lol

P.P.S. I decided to play a quick game with the black pieces.

1. d3 e5 2. a3 Bc5 3. Be3 Bxe3 4. fxe3 Nf6 5. Nd2 d5 6. d4 Nc6 7. dxe5 Nxe5
8. h3 Qd6 9. Ngf3 Neg4 10. Nc4 Qg3+ 11. Kd2 Nf2 12. Qc1 N6e4+ 13. Ke1 Nd3+
14. Kd1 Qe1+ 15. Nxe1 Ndf2# 0-1
« Last Edit: January 29, 2020, 05:50:06 pm by romichess »
My name is Michael, but you can call me Mike :)

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: A 90% complete chess engine
« Reply #24 on: February 02, 2020, 12:25:05 pm »
Yes I confirm that there is the bug of EnterKeypressing for get the Black move,
but why does AI prefer always the Nimzowitsch to open game of white ?
https://it.wikipedia.org/wiki/Difesa_Nimzowitsch It is a minor defence against E4!
I think you must use a book of opening to improve AI force.

Here my first game user's experience:

Fine the gameplay also if there are the distracting lights of white squares and  no support of mouse.
A big bug ... AI doesn't recognize the checkmate! See screenshot!
PS your program run away to Print key of Windows to capture the screen. So i must install SnapShot to get it...(I know that there is the SMcNeill Steve's library... but I don't want to write code, now I'm just a player)

 
NoCheckmate Recognition.jpg

Here the first game like White
Quote
1. e4 Nc6
2. d4 e6
3 Bc4 Na5
4 Bd3 Nc6
5 Nf3  h6
6 O-O Nge7
7 c4  Nb4
8 Be2 Nbc6
9 Nc3  b6
10 Re1 Bb7
11 d5 Nb8
12 dxe6 fxe6
13 e5  Nf5
14 g4  Nfe7
15 Nh4  g5
16 Nf3 Bg7
17 Bd3 O-O
18 Nc3 Qe8
19 Qe2 Qf7
20 Nxg5 hxg5
21 Nxg5 Qe8
22 Bh7+ Kh8
23 Qd3 Nc6
24 Qh3 Rd8
25 Bg6+ Bh6
26 Qxh6+ Kg8
27 Qh7#

moreover...
the game went on with this following moves...
Quote
27... Nb4
28 Qxg8 Qxg6

 
NoCheckmate Recognition2 No Black King.jpg

so if you want improve that AI
1. not only it must be build the rule of checkmate (the king is under attack and it will be captured to the next move and there is no defence to this)
2. but also you must build the rule without King there is gameover (No King is equal No game for that color/side)

Thanks to share you chessprogram with a intermediate AI and any lack of some rules




Programming isn't difficult, only it's  consuming time and coffee

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: A 90% complete chess engine
« Reply #25 on: February 02, 2020, 12:53:49 pm »
another bit feedback
in my first game as Black... I cannot castle
this is the sequence of moves
Quote
1 d3   d5
2 Be3  e5
3 a3   c5
4 c3  Nc6
5 Qb3 Nf6
6 f3  Bd6
7 Nd2

this is the screenshot
 
NocCastle for Blackside.jpg

here if I take King and I do 2 steps to the left the program takes my move but then it resets the input to me refusing my choice.

IMHO also this rules must be added to the AI (castle is for white and for black) .
I hope this is not so much for a positive feedback!
Programming isn't difficult, only it's  consuming time and coffee

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: A 90% complete chess engine
« Reply #26 on: February 02, 2020, 01:52:41 pm »
About CHESS.BAS that follows the QB64 package of example of QB and Qbasic code runnable under QB64..

I and Bplus have worked more on adjurnament of the interface and of the input adding mouse support to input the move, a set of buttons to choose how to play, showing avaiabled moves of the piece that the mouse is pointing, but not so much improving  the AI because without understanding how it is structured the original AI there are poor opportunity to empower something, it is simpler  write again with your way. In fact Bplus wrote the most of the code to let choose and play with the Black the gamer  vs AI. And it was not so clear to me how to use the system  implemented into original AI to play with Black. AI  uses an 8x8 chess table miming the fisical chessboard and no a single array of 64 (0-63) elements. The moves are calculated on fly and not with a offset.
Also with its all limitations the original AI recognize an impossible to continue setting on the chessboard. See screenshots

ChessBAS Bplus TdB 1.jpg
* ChessBAS Bplus TdB 1.jpg (Filesize: 179.1 KB, Dimensions: 906x629, Views: 201)
chessBAS Bplus TdB 2.jpg
* chessBAS Bplus TdB 2.jpg (Filesize: 97.66 KB, Dimensions: 775x542, Views: 220)
chessBAS Bplus TdB 3.jpg
* chessBAS Bplus TdB 3.jpg (Filesize: 117.01 KB, Dimensions: 901x589, Views: 191)
chessBAS Bplus TdB 4.jpg
* chessBAS Bplus TdB 4.jpg (Filesize: 109.9 KB, Dimensions: 903x626, Views: 216)
chessBAS Bplus TdB 5.jpg
* chessBAS Bplus TdB 5.jpg (Filesize: 120.73 KB, Dimensions: 902x623, Views: 198)
Programming isn't difficult, only it's  consuming time and coffee

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: A 90% complete chess engine
« Reply #27 on: February 02, 2020, 04:46:59 pm »
Bplus, I got pretty close to finishing a 2-person checkers game after a week of programming every day. But I can't figure out how to keep the king symbol on a king checker piece. The symbol shows up fine on it when you get to the other side, but then when you move again it's deleted. I'm sure I didn't do the variables the right way. I actually just tossed in variables not knowing exactly what they do which is totally not good. I also am getting hang-ups every once in awhile where it won't let you plot coordinates (I don't even use the mouse in this game). So, I will probably either take a long break on this game or just give up on it.
Feel free to have the code anyone, if you wish to do anything with it. Just remember the king symbol doesn't stay and once in awhile maybe it won't let you plot (not sure I may have fixed that). The only reason I'm posting the code today is to show everyone how good I actually did make it so far. You can jump, but only do 1 jump per move. So all in all, it's a very rough and bad way to play checkers, but it is the best one I've made so far. Oh also, it does say which player wins when they do win. I've only played 1 full game of it myself. And like 40 other tries of fixing things. lol Been a crazy little program. But for now, I'm finished with it myself.

Code: QB64: [Select]
  1. _TITLE "1 Jump - 2 Player Checkers - by Ken G."
  2. SCREEN _NEWIMAGE(800, 600, 32)
  3. DIM black2(88), red2(88), bking(88), rking(88)
  4.  
  5. 'Make checkerboard
  6. LINE (149, 49)-(651, 551), _RGB32(255, 255, 255), B
  7. FOR ly = 50 TO 487.5 STEP 125
  8.     FOR lx = 212.5 TO 650 STEP 125
  9.         LINE (lx - 62.5, ly)-(lx, ly + 62.5), _RGB32(255, 0, 0), BF
  10.     NEXT lx
  11.     FOR lx = 212.5 TO 650 STEP 125
  12.         LINE (lx, ly + 62.5)-(lx + 62.5, ly + 125), _RGB32(255, 0, 0), BF
  13.     NEXT lx
  14.     FOR lx = 275 TO 650 STEP 125
  15.         LINE (lx - 62.5, ly)-(lx, ly + 62.5), _RGB32(0, 0, 0), BF
  16.     NEXT lx
  17.     FOR lx = 150 TO 587.5 STEP 125
  18.         LINE (lx, ly + 62.5)-(lx + 62.5, ly + 125), _RGB32(0, 0, 0), BF
  19.     NEXT lx
  20. NEXT ly
  21. COLOR _RGB32(255, 255, 255)
  22. LOCATE 3, 87: PRINT "Red"
  23. LOCATE 4, 87: PRINT "From:"
  24. LOCATE 9, 87: PRINT "To:"
  25. LOCATE 3, 5: PRINT "Black"
  26. LOCATE 4, 5: PRINT "From:"
  27. LOCATE 9, 5: PRINT "To:"
  28.  
  29. COLOR _RGB32(127, 255, 255)
  30. FOR lx = 170 TO 607.5 STEP 62.5
  31.     h = h + 1
  32.     h$ = STR$(h)
  33.     _PRINTSTRING (lx, 30), h$
  34. NEXT lx
  35. COLOR _RGB32(128, 249, 127)
  36. FOR ly = 70 TO 507.5 STEP 62.5
  37.     v = v + 1
  38.     v$ = STR$(v)
  39.     _PRINTSTRING (120, ly), v$
  40. NEXT ly
  41. h = 0: v = 0
  42. COLOR _RGB32(127, 255, 255)
  43. FOR lx = 170 TO 607.5 STEP 62.5
  44.     h = h + 1
  45.     h$ = STR$(h)
  46.     _PRINTSTRING (lx, 560), h$
  47. NEXT lx
  48. COLOR _RGB32(128, 249, 127)
  49. FOR ly = 70 TO 507.5 STEP 62.5
  50.     v = v + 1
  51.     v$ = STR$(v)
  52.     _PRINTSTRING (660, ly), v$
  53. NEXT ly
  54.  
  55. 'setup pieces
  56. 'black
  57. ly = 50
  58. FOR lx = 212.5 TO 650 STEP 125
  59.     CIRCLE (lx + 31.25, ly + 31.25), 20, _RGB32(50, 50, 50)
  60.     PAINT (lx + 31.25, ly + 31.25), _RGB32(50, 50, 50)
  61. NEXT lx
  62. FOR lx = 212.5 TO 650 STEP 125
  63.     CIRCLE (lx - 31.25, ly + 93.75), 20, _RGB32(50, 50, 50)
  64.     PAINT (lx - 31.25, ly + 93.75), _RGB32(50, 50, 50)
  65. NEXT lx
  66. FOR lx = 212.5 TO 650 STEP 125
  67.     CIRCLE (lx + 31.25, ly + 156.25), 20, _RGB32(50, 50, 50)
  68.     PAINT (lx + 31.25, ly + 156.25), _RGB32(50, 50, 50)
  69. NEXT lx
  70. 'red
  71. ly = 206.25
  72. FOR lx = 212.5 TO 650 STEP 125
  73.     CIRCLE (lx - 31.25, ly + 187.5), 20, _RGB32(200, 50, 50)
  74.     PAINT (lx - 31.25, ly + 187.5), _RGB32(200, 50, 50)
  75. NEXT lx
  76. FOR lx = 212.5 TO 650 STEP 125
  77.     CIRCLE (lx + 31.25, ly + 250), 20, _RGB32(200, 50, 50)
  78.     PAINT (lx + 31.25, ly + 250), _RGB32(200, 50, 50)
  79. NEXT lx
  80. FOR lx = 212.5 TO 650 STEP 125
  81.     CIRCLE (lx - 31.25, ly + 312.5), 20, _RGB32(200, 50, 50)
  82.     PAINT (lx - 31.25, ly + 312.5), _RGB32(200, 50, 50)
  83. NEXT lx
  84.  
  85. 'The coordinate variables use a 2 digit number, the first digit is the horizon, the second is the vertical.
  86. black2(1) = 12
  87. black2(2) = 14
  88. black2(3) = 16
  89. black2(4) = 18
  90.  
  91. black2(5) = 21
  92. black2(6) = 23
  93. black2(7) = 25
  94. black2(8) = 27
  95.  
  96. black2(9) = 32
  97. black2(10) = 34
  98. black2(11) = 36
  99. black2(12) = 38
  100.  
  101. red2(9) = 81
  102. red2(10) = 83
  103. red2(11) = 85
  104. red2(12) = 87
  105.  
  106. red2(5) = 72
  107. red2(6) = 74
  108. red2(7) = 76
  109. red2(8) = 78
  110.  
  111. red2(1) = 61
  112. red2(2) = 63
  113. red2(3) = 65
  114. red2(4) = 67
  115.  
  116. '----------------------------------------------------------------------------
  117. 'Main Loop
  118.  
  119. _LIMIT 200
  120.  
  121. 'Player One
  122. one:
  123. COLOR _RGB32(128, 249, 127)
  124. LOCATE 5, 87: PRINT "Horizon": LOCATE 6, 87: INPUT ph
  125. IF ph > 8 OR ph < 1 THEN GOTO one:
  126. IF ph <> INT(ph) THEN GOTO one:
  127. COLOR _RGB32(127, 255, 255)
  128. LOCATE 7, 87: PRINT "Vertical": LOCATE 8, 87: INPUT pv
  129. IF pv > 8 OR pv < 1 THEN GOTO one:
  130. IF pv <> INT(pv) THEN GOTO one:
  131. ph$ = STR$(ph)
  132. pv$ = STR$(pv)
  133. sp$ = ph$ + pv$
  134. sp = VAL(sp$)
  135. FOR check = 1 TO 88
  136.     IF red2(check) = sp THEN ch = sp: GOTO move:
  137. NEXT check
  138. GOTO one:
  139.  
  140. 'Player Two
  141. two:
  142. COLOR _RGB32(128, 249, 127)
  143. LOCATE 5, 5: PRINT "Horizon": LOCATE 6, 5: INPUT ph3
  144. IF ph3 > 8 OR ph3 < 1 THEN GOTO two:
  145. IF ph3 <> INT(ph3) THEN GOTO two:
  146. COLOR _RGB32(127, 255, 255)
  147. LOCATE 7, 5: PRINT "Vertical": LOCATE 8, 5: INPUT pv3
  148. IF pv3 > 8 OR pv3 < 1 THEN GOTO two:
  149. IF pv3 <> INT(pv3) THEN GOTO two:
  150. ph3$ = STR$(ph3)
  151. pv3$ = STR$(pv3)
  152. sp3$ = ph3$ + pv3$
  153. sp3 = VAL(sp3$)
  154. FOR check2 = 1 TO 88
  155.     IF black2(check2) = sp3 THEN ch2 = sp3: GOTO move2:
  156. NEXT check2
  157. GOTO two:
  158.  
  159. '----------------------------------------------------------------------------
  160.  
  161. move:
  162. COLOR _RGB32(128, 249, 127)
  163. LOCATE 10, 87: PRINT "Horizon": LOCATE 11, 87: INPUT ph2
  164. IF ph2 > 8 OR ph2 < 1 THEN GOTO one:
  165. IF ph2 <> INT(ph2) THEN GOTO one:
  166.  
  167. COLOR _RGB32(127, 255, 255)
  168. LOCATE 12, 87: PRINT "Vertical": LOCATE 13, 87: INPUT pv2
  169. IF pv2 > 8 OR pv2 < 1 THEN GOTO one:
  170. IF pv2 <> INT(pv2) THEN GOTO one:
  171. ph2$ = STR$(ph2)
  172. pv2$ = STR$(pv2)
  173. sp2$ = ph2$ + pv2$
  174. sp2 = VAL(sp2$)
  175. IF sp = sp2 THEN GOTO one:
  176. IF pv = pv2 OR ph = ph2 THEN
  177.     COLOR _RGB32(255, 0, 0)
  178.     LOCATE 15, 87
  179.     PRINT "Illegal Move"
  180.     GOTO one:
  181.  
  182. 'Check for red squares.
  183. IF sp2 = 11 OR sp2 = 13 OR sp2 = 15 OR sp2 = 17 OR sp2 = 22 OR sp2 = 24 OR sp2 = 26 OR sp2 = 28 THEN
  184.     COLOR _RGB32(255, 0, 0)
  185.     LOCATE 15, 87
  186.     PRINT "Illegal Move"
  187.     GOTO one:
  188. IF sp2 = 31 OR sp2 = 33 OR sp2 = 35 OR sp2 = 37 OR sp2 = 42 OR sp2 = 44 OR sp2 = 46 OR sp2 = 48 THEN
  189.     COLOR _RGB32(255, 0, 0)
  190.     LOCATE 15, 87
  191.     PRINT "Illegal Move"
  192.     GOTO one:
  193. IF sp2 = 51 OR sp2 = 53 OR sp2 = 55 OR sp2 = 57 OR sp2 = 62 OR sp2 = 64 OR sp2 = 66 OR sp2 = 68 THEN
  194.     COLOR _RGB32(255, 0, 0)
  195.     LOCATE 15, 87
  196.     PRINT "Illegal Move"
  197.     GOTO one:
  198. IF sp2 = 71 OR sp2 = 73 OR sp2 = 75 OR sp2 = 77 OR sp2 = 82 OR sp2 = 84 OR sp2 = 86 OR sp2 = 88 THEN
  199.     COLOR _RGB32(255, 0, 0)
  200.     LOCATE 15, 87
  201.     PRINT "Illegal Move"
  202.     GOTO one:
  203.  
  204. red2(ch) = sp2
  205.  
  206. 'Draw player one checker in the new square.
  207. 'First erase the old checker.
  208. IF sp = 12 THEN CIRCLE (243.75, 81.25), 20, _RGB32(0, 0, 0): PAINT (243.75, 81.25), _RGB32(0, 0, 0): x1 = 243.75: y1 = 81.25
  209. IF sp = 14 THEN CIRCLE (368.75, 81.25), 20, _RGB32(0, 0, 0): PAINT (368.75, 81.25), _RGB32(0, 0, 0): x1 = 368.75: y1 = 81.25
  210. IF sp = 16 THEN CIRCLE (493.75, 81.25), 20, _RGB32(0, 0, 0): PAINT (493.75, 81.25), _RGB32(0, 0, 0): x1 = 493.75: y1 = 81.25
  211. IF sp = 18 THEN CIRCLE (618.75, 81.25), 20, _RGB32(0, 0, 0): PAINT (618.75, 81.25), _RGB32(0, 0, 0): x1 = 618.75: y1 = 81.25
  212. IF sp = 21 THEN CIRCLE (181.25, 143.75), 20, _RGB32(0, 0, 0): PAINT (181.25, 143.75), _RGB32(0, 0, 0): x1 = 181.25: y1 = 143.75
  213. IF sp = 23 THEN CIRCLE (306.25, 143.75), 20, _RGB32(0, 0, 0): PAINT (306.25, 143.75), _RGB32(0, 0, 0): x1 = 306.25: y1 = 143.75
  214. IF sp = 25 THEN CIRCLE (431.25, 143.75), 20, _RGB32(0, 0, 0): PAINT (431.25, 143.75), _RGB32(0, 0, 0): x1 = 431.25: y1 = 143.75
  215. IF sp = 27 THEN CIRCLE (556.25, 143.75), 20, _RGB32(0, 0, 0): PAINT (556.25, 143.75), _RGB32(0, 0, 0): x1 = 556.25: y1 = 143.75
  216. IF sp = 32 THEN CIRCLE (243.75, 206.25), 20, _RGB32(0, 0, 0): PAINT (243.75, 206.25), _RGB32(0, 0, 0): x1 = 243.75: y1 = 206.25
  217. IF sp = 34 THEN CIRCLE (368.75, 206.25), 20, _RGB32(0, 0, 0): PAINT (368.75, 206.25), _RGB32(0, 0, 0): x1 = 368.75: y1 = 206.25
  218. IF sp = 36 THEN CIRCLE (493.75, 206.25), 20, _RGB32(0, 0, 0): PAINT (493.75, 206.25), _RGB32(0, 0, 0): x1 = 493.75: y1 = 206.25
  219. IF sp = 38 THEN CIRCLE (618.75, 206.25), 20, _RGB32(0, 0, 0): PAINT (618.75, 206.25), _RGB32(0, 0, 0): x1 = 618.75: y1 = 206.25
  220. IF sp = 41 THEN CIRCLE (181.25, 268.75), 20, _RGB32(0, 0, 0): PAINT (181.25, 268.75), _RGB32(0, 0, 0): x1 = 181.25: y1 = 268.75
  221. IF sp = 43 THEN CIRCLE (306.25, 268.75), 20, _RGB32(0, 0, 0): PAINT (306.25, 268.75), _RGB32(0, 0, 0): x1 = 306.25: y1 = 268.75
  222. IF sp = 45 THEN CIRCLE (431.25, 268.75), 20, _RGB32(0, 0, 0): PAINT (431.25, 268.75), _RGB32(0, 0, 0): x1 = 431.25: y1 = 268.75
  223. IF sp = 47 THEN CIRCLE (556.25, 268.75), 20, _RGB32(0, 0, 0): PAINT (556.25, 268.75), _RGB32(0, 0, 0): x1 = 556.25: y1 = 268.75
  224. IF sp = 52 THEN CIRCLE (243.75, 331.25), 20, _RGB32(0, 0, 0): PAINT (243.75, 331.25), _RGB32(0, 0, 0): x1 = 243.75: y1 = 331.25
  225. IF sp = 54 THEN CIRCLE (368.75, 331.25), 20, _RGB32(0, 0, 0): PAINT (368.75, 331.25), _RGB32(0, 0, 0): x1 = 368.75: y1 = 331.25
  226. IF sp = 56 THEN CIRCLE (493.75, 331.25), 20, _RGB32(0, 0, 0): PAINT (493.75, 331.25), _RGB32(0, 0, 0): x1 = 493.75: y1 = 331.25
  227. IF sp = 58 THEN CIRCLE (618.75, 331.25), 20, _RGB32(0, 0, 0): PAINT (618.75, 331.25), _RGB32(0, 0, 0): x1 = 618.75: y1 = 331.25
  228. IF sp = 61 THEN CIRCLE (181.25, 393.75), 20, _RGB32(0, 0, 0): PAINT (181.25, 393.74), _RGB32(0, 0, 0): x1 = 181.25: y1 = 393.75
  229. IF sp = 63 THEN CIRCLE (306.25, 393.75), 20, _RGB32(0, 0, 0): PAINT (306.25, 393.75), _RGB32(0, 0, 0): x1 = 306.25: y1 = 393.75
  230. IF sp = 65 THEN CIRCLE (431.25, 393.75), 20, _RGB32(0, 0, 0): PAINT (431.25, 393.75), _RGB32(0, 0, 0): x1 = 431.25: y1 = 393.75
  231. IF sp = 67 THEN CIRCLE (556.25, 393.75), 20, _RGB32(0, 0, 0): PAINT (556.25, 393.75), _RGB32(0, 0, 0): x1 = 556.25: y1 = 393.75
  232. IF sp = 72 THEN CIRCLE (243.75, 456.25), 20, _RGB32(0, 0, 0): PAINT (243.75, 456.25), _RGB32(0, 0, 0): x1 = 243.75: y1 = 456.25
  233. IF sp = 74 THEN CIRCLE (368.75, 456.25), 20, _RGB32(0, 0, 0): PAINT (368.75, 456.25), _RGB32(0, 0, 0): x1 = 368.75: y1 = 456.25
  234. IF sp = 76 THEN CIRCLE (493.75, 456.25), 20, _RGB32(0, 0, 0): PAINT (493.75, 456.25), _RGB32(0, 0, 0): x1 = 493.75: y1 = 456.25
  235. IF sp = 78 THEN CIRCLE (618.75, 456.25), 20, _RGB32(0, 0, 0): PAINT (618.75, 456.25), _RGB32(0, 0, 0): x1 = 618.75: y1 = 456.25
  236. IF sp = 81 THEN CIRCLE (181.25, 518.75), 20, _RGB32(0, 0, 0): PAINT (181.25, 518.75), _RGB32(0, 0, 0): x1 = 181.25: y1 = 518.75
  237. IF sp = 83 THEN CIRCLE (306.25, 518.75), 20, _RGB32(0, 0, 0): PAINT (306.25, 518.75), _RGB32(0, 0, 0): x1 = 306.25: y1 = 518.75
  238. IF sp = 85 THEN CIRCLE (431.25, 518.75), 20, _RGB32(0, 0, 0): PAINT (431.25, 518.75), _RGB32(0, 0, 0): x1 = 431.25: y1 = 518.75
  239. IF sp = 87 THEN CIRCLE (556.25, 518.75), 20, _RGB32(0, 0, 0): PAINT (556.25, 518.75), _RGB32(0, 0, 0): x1 = 556.25: y1 = 518.75
  240.  
  241. 'Now draw the new checker.
  242. IF sp2 = 12 THEN CIRCLE (243.75, 81.25), 20, _RGB32(200, 50, 50): PAINT (243.75, 81.25), _RGB32(200, 50, 50): x2 = 243.75: y2 = 81.25
  243. IF sp2 = 14 THEN CIRCLE (368.75, 81.25), 20, _RGB32(200, 50, 50): PAINT (368.75, 81.25), _RGB32(200, 50, 50): x2 = 368.75: y2 = 81.25
  244. IF sp2 = 16 THEN CIRCLE (493.75, 81.25), 20, _RGB32(200, 50, 50): PAINT (493.75, 81.25), _RGB32(200, 50, 50): x2 = 493.75: y2 = 81.25
  245. IF sp2 = 18 THEN CIRCLE (618.75, 81.25), 20, _RGB32(200, 50, 50): PAINT (618.75, 81.25), _RGB32(200, 50, 50): x2 = 618.75: y2 = 81.25
  246. IF sp2 = 21 THEN CIRCLE (181.25, 143.75), 20, _RGB32(200, 50, 50): PAINT (181.25, 143.75), _RGB32(200, 50, 50): x2 = 181.25: y2 = 143.75
  247. IF sp2 = 23 THEN CIRCLE (306.25, 143.75), 20, _RGB32(200, 50, 50): PAINT (306.25, 143.75), _RGB32(200, 50, 50): x2 = 306.25: y2 = 143.75
  248. IF sp2 = 25 THEN CIRCLE (431.25, 143.75), 20, _RGB32(200, 50, 50): PAINT (431.25, 143.75), _RGB32(200, 50, 50): x2 = 431.25: y2 = 143.75
  249. IF sp2 = 27 THEN CIRCLE (556.25, 143.75), 20, _RGB32(200, 50, 50): PAINT (556.25, 143.75), _RGB32(200, 50, 50): x2 = 556.25: y2 = 143.75
  250. IF sp2 = 32 THEN CIRCLE (243.75, 206.25), 20, _RGB32(200, 50, 50): PAINT (243.75, 206.25), _RGB32(200, 50, 50): x2 = 243.75: y2 = 206.25
  251. IF sp2 = 34 THEN CIRCLE (368.75, 206.25), 20, _RGB32(200, 50, 50): PAINT (368.75, 206.25), _RGB32(200, 50, 50): x2 = 368.75: y2 = 206.25
  252. IF sp2 = 36 THEN CIRCLE (493.75, 206.25), 20, _RGB32(200, 50, 50): PAINT (493.75, 206.25), _RGB32(200, 50, 50): x2 = 493.75: y2 = 206.25
  253. IF sp2 = 38 THEN CIRCLE (618.75, 206.25), 20, _RGB32(200, 50, 50): PAINT (618.75, 206.25), _RGB32(200, 50, 50): x2 = 618.75: y2 = 206.25
  254. IF sp2 = 41 THEN CIRCLE (181.25, 268.75), 20, _RGB32(200, 50, 50): PAINT (181.25, 268.75), _RGB32(200, 50, 50): x2 = 181.25: y2 = 268.75
  255. IF sp2 = 43 THEN CIRCLE (306.25, 268.75), 20, _RGB32(200, 50, 50): PAINT (306.25, 268.75), _RGB32(200, 50, 50): x2 = 306.25: y2 = 268.75
  256. IF sp2 = 45 THEN CIRCLE (431.25, 268.75), 20, _RGB32(200, 50, 50): PAINT (431.25, 268.75), _RGB32(200, 50, 50): x2 = 431.25: y2 = 268.75
  257. IF sp2 = 47 THEN CIRCLE (556.25, 268.75), 20, _RGB32(200, 50, 50): PAINT (556.25, 268.75), _RGB32(200, 50, 50): x2 = 556.25: y2 = 268.75
  258. IF sp2 = 52 THEN CIRCLE (243.75, 331.25), 20, _RGB32(200, 50, 50): PAINT (243.75, 331.25), _RGB32(200, 50, 50): x2 = 243.75: y2 = 331.25
  259. IF sp2 = 54 THEN CIRCLE (368.75, 331.25), 20, _RGB32(200, 50, 50): PAINT (368.75, 331.25), _RGB32(200, 50, 50): x2 = 368.75: y2 = 331.25
  260. IF sp2 = 56 THEN CIRCLE (493.75, 331.25), 20, _RGB32(200, 50, 50): PAINT (493.75, 331.25), _RGB32(200, 50, 50): x2 = 493.75: y2 = 331.25
  261. IF sp2 = 58 THEN CIRCLE (618.75, 331.25), 20, _RGB32(200, 50, 50): PAINT (618.75, 331.25), _RGB32(200, 50, 50): x2 = 618.75: y2 = 331.25
  262. IF sp2 = 61 THEN CIRCLE (181.25, 393.75), 20, _RGB32(200, 50, 50): PAINT (181.25, 393.74), _RGB32(200, 50, 50): x2 = 181.25: y2 = 393.75
  263. IF sp2 = 63 THEN CIRCLE (306.25, 393.75), 20, _RGB32(200, 50, 50): PAINT (306.25, 393.75), _RGB32(200, 50, 50): x2 = 306.25: y2 = 393.75
  264. IF sp2 = 65 THEN CIRCLE (431.25, 393.75), 20, _RGB32(200, 50, 50): PAINT (431.25, 393.75), _RGB32(200, 50, 50): x2 = 431.25: y2 = 393.75
  265. IF sp2 = 67 THEN CIRCLE (556.25, 393.75), 20, _RGB32(200, 50, 50): PAINT (556.25, 393.75), _RGB32(200, 50, 50): x2 = 556.25: y2 = 393.75
  266. IF sp2 = 72 THEN CIRCLE (243.75, 456.25), 20, _RGB32(200, 50, 50): PAINT (243.75, 456.25), _RGB32(200, 50, 50): x2 = 243.75: y2 = 456.25
  267. IF sp2 = 74 THEN CIRCLE (368.75, 456.25), 20, _RGB32(200, 50, 50): PAINT (368.75, 456.25), _RGB32(200, 50, 50): x2 = 368.75: y2 = 456.25
  268. IF sp2 = 76 THEN CIRCLE (493.75, 456.25), 20, _RGB32(200, 50, 50): PAINT (493.75, 456.25), _RGB32(200, 50, 50): x2 = 493.75: y2 = 456.25
  269. IF sp2 = 78 THEN CIRCLE (618.75, 456.25), 20, _RGB32(200, 50, 50): PAINT (618.75, 456.25), _RGB32(200, 50, 50): x2 = 618.75: y2 = 456.25
  270. IF sp2 = 81 THEN CIRCLE (181.25, 518.75), 20, _RGB32(200, 50, 50): PAINT (181.25, 518.75), _RGB32(200, 50, 50): x2 = 181.25: y2 = 518.75
  271. IF sp2 = 83 THEN CIRCLE (306.25, 518.75), 20, _RGB32(200, 50, 50): PAINT (306.25, 518.75), _RGB32(200, 50, 50): x2 = 306.25: y2 = 518.75
  272. IF sp2 = 85 THEN CIRCLE (431.25, 518.75), 20, _RGB32(200, 50, 50): PAINT (431.25, 518.75), _RGB32(200, 50, 50): x2 = 431.25: y2 = 518.75
  273. IF sp2 = 87 THEN CIRCLE (556.25, 518.75), 20, _RGB32(200, 50, 50): PAINT (556.25, 518.75), _RGB32(200, 50, 50): x2 = 556.25: y2 = 518.75
  274.  
  275. 'Check for a jump.
  276. IF pv - pv2 = 2 OR pv2 - pv = 2 THEN
  277.     IF ph - ph2 = 2 OR ph2 - ph = 2 THEN
  278.         IF x1 > x2 THEN stp = -.25
  279.         IF x1 < x2 THEN stp = .25
  280.         IF y1 > y2 THEN stp2 = -.25
  281.         IF y1 < y2 THEN stp2 = .25
  282.         yy = y1
  283.         FOR xx = x1 TO x2 STEP stp
  284.             yy = yy + stp2
  285.             IF POINT(xx, yy) = _RGB32(50, 50, 50) THEN
  286.                 PAINT (xx, yy), _RGB32(0, 0, 0)
  287.                 GOTO nex:
  288.             END IF
  289.         NEXT xx
  290.     END IF
  291. nex:
  292.  
  293.  
  294. 'Check for a King.
  295. IF ph2 = 1 THEN
  296.     k1 = k1 + 1
  297.     rking(k1) = red2(ch)
  298.     GOSUB drawking:
  299. FOR cch = 1 TO 88
  300.     IF rking(cch) = red2(cch) AND rking(cch) <> 0 THEN GOSUB drawking:
  301. NEXT cch
  302.  
  303.  
  304. 'Check for a win.
  305. FOR wx = 0 TO 800
  306.     FOR wy = 0 TO 600
  307.         IF POINT(wx, wy) = _RGB32(50, 50, 50) THEN GOTO nex3:
  308.     NEXT wy
  309. NEXT wx
  310. COLOR _RGB32(255, 0, 0)
  311. LOCATE 3, 87: PRINT "Red Wins!"
  312.  
  313. nex3:
  314. LOCATE 5, 87: PRINT "           ": LOCATE 6, 87: PRINT "            "
  315. LOCATE 7, 87: PRINT "           ": LOCATE 8, 87: PRINT "            "
  316. LOCATE 10, 87: PRINT "           ": LOCATE 11, 87: PRINT "            "
  317. LOCATE 12, 87: PRINT "           ": LOCATE 13, 87: PRINT "            "
  318. LOCATE 15, 87: PRINT "            "
  319. GOTO two:
  320.  
  321. '-----------------------------------------------------------------------------------------------------------
  322. 'Player Two
  323.  
  324. move2:
  325. COLOR _RGB32(128, 249, 127)
  326. LOCATE 10, 5: PRINT "Horizon": LOCATE 11, 5: INPUT ph4
  327. IF ph4 > 8 OR ph4 < 1 THEN GOTO two:
  328. IF ph4 <> INT(ph4) THEN GOTO two:
  329. COLOR _RGB32(127, 255, 255)
  330. LOCATE 12, 5: PRINT "Vertical": LOCATE 13, 5: INPUT pv4
  331.  
  332. IF pv4 > 8 OR pv4 < 1 THEN GOTO two:
  333. IF pv4 <> INT(pv4) THEN GOTO two:
  334. ph4$ = STR$(ph4)
  335. pv4$ = STR$(pv4)
  336. sp4$ = ph4$ + pv4$
  337. sp4 = VAL(sp4$)
  338. IF sp3 = sp4 THEN GOTO two:
  339. IF pv3 = pv4 OR ph3 = ph4 THEN
  340.     COLOR _RGB32(255, 0, 0)
  341.     LOCATE 15, 5
  342.     PRINT "Illegal Move"
  343.     GOTO one:
  344.  
  345. 'Check for red squares.
  346. IF sp4 = 11 OR sp4 = 13 OR sp4 = 15 OR sp4 = 17 OR sp4 = 22 OR sp4 = 24 OR sp4 = 26 OR sp4 = 28 THEN
  347.     COLOR _RGB32(255, 0, 0)
  348.     LOCATE 15, 5
  349.     PRINT "Illegal Move"
  350.     GOTO two:
  351. IF sp4 = 31 OR sp4 = 33 OR sp4 = 35 OR sp4 = 37 OR sp4 = 42 OR sp4 = 44 OR sp4 = 46 OR sp4 = 48 THEN
  352.     COLOR _RGB32(255, 0, 0)
  353.     LOCATE 15, 5
  354.     PRINT "Illegal Move"
  355.     GOTO two:
  356. IF sp4 = 51 OR sp4 = 53 OR sp4 = 55 OR sp4 = 57 OR sp4 = 62 OR sp4 = 64 OR sp4 = 66 OR sp4 = 68 THEN
  357.     COLOR _RGB32(255, 0, 0)
  358.     LOCATE 15, 5
  359.     PRINT "Illegal Move"
  360.     GOTO two:
  361. IF sp4 = 71 OR sp4 = 73 OR sp4 = 75 OR sp4 = 77 OR sp4 = 82 OR sp4 = 84 OR sp4 = 86 OR sp4 = 88 THEN
  362.     COLOR _RGB32(255, 0, 0)
  363.     LOCATE 15, 5
  364.     PRINT "Illegal Move"
  365.     GOTO two:
  366.  
  367. black2(ch2) = sp4
  368.  
  369. 'Draw player two checker in the new square.
  370. 'First erase the old checker.
  371. IF sp3 = 12 THEN CIRCLE (243.75, 81.25), 20, _RGB32(0, 0, 0): PAINT (243.75, 81.25), _RGB32(0, 0, 0): x1 = 243.75: y1 = 81.25
  372. IF sp3 = 14 THEN CIRCLE (368.75, 81.25), 20, _RGB32(0, 0, 0): PAINT (368.75, 81.25), _RGB32(0, 0, 0): x1 = 368.75: y1 = 81.25
  373. IF sp3 = 16 THEN CIRCLE (493.75, 81.25), 20, _RGB32(0, 0, 0): PAINT (493.75, 81.25), _RGB32(0, 0, 0): x1 = 493.75: y1 = 81.25
  374. IF sp3 = 18 THEN CIRCLE (618.75, 81.25), 20, _RGB32(0, 0, 0): PAINT (618.75, 81.25), _RGB32(0, 0, 0): x1 = 618.75: y1 = 81.25
  375. IF sp3 = 21 THEN CIRCLE (181.25, 143.75), 20, _RGB32(0, 0, 0): PAINT (181.25, 143.75), _RGB32(0, 0, 0): x1 = 181.25: y1 = 143.75
  376. IF sp3 = 23 THEN CIRCLE (306.25, 143.75), 20, _RGB32(0, 0, 0): PAINT (306.25, 143.75), _RGB32(0, 0, 0): x1 = 306.25: y1 = 143.75
  377. IF sp3 = 25 THEN CIRCLE (431.25, 143.75), 20, _RGB32(0, 0, 0): PAINT (431.25, 143.75), _RGB32(0, 0, 0): x1 = 431.25: y1 = 143.75
  378. IF sp3 = 27 THEN CIRCLE (556.25, 143.75), 20, _RGB32(0, 0, 0): PAINT (556.25, 143.75), _RGB32(0, 0, 0): x1 = 556.25: y1 = 143.75
  379. IF sp3 = 32 THEN CIRCLE (243.75, 206.25), 20, _RGB32(0, 0, 0): PAINT (243.75, 206.25), _RGB32(0, 0, 0): x1 = 243.75: y1 = 206.25
  380. IF sp3 = 34 THEN CIRCLE (368.75, 206.25), 20, _RGB32(0, 0, 0): PAINT (368.75, 206.25), _RGB32(0, 0, 0): x1 = 368.75: y1 = 206.25
  381. IF sp3 = 36 THEN CIRCLE (493.75, 206.25), 20, _RGB32(0, 0, 0): PAINT (493.75, 206.25), _RGB32(0, 0, 0): x1 = 493.75: y1 = 206.25
  382. IF sp3 = 38 THEN CIRCLE (618.75, 206.25), 20, _RGB32(0, 0, 0): PAINT (618.75, 206.25), _RGB32(0, 0, 0): x1 = 618.75: y1 = 206.25
  383. IF sp3 = 41 THEN CIRCLE (181.25, 268.75), 20, _RGB32(0, 0, 0): PAINT (181.25, 268.75), _RGB32(0, 0, 0): x1 = 181.25: y1 = 268.75
  384. IF sp3 = 43 THEN CIRCLE (306.25, 268.75), 20, _RGB32(0, 0, 0): PAINT (306.25, 268.75), _RGB32(0, 0, 0): x1 = 306.25: y1 = 268.75
  385. IF sp3 = 45 THEN CIRCLE (431.25, 268.75), 20, _RGB32(0, 0, 0): PAINT (431.25, 268.75), _RGB32(0, 0, 0): x1 = 431.25: y1 = 268.75
  386. IF sp3 = 47 THEN CIRCLE (556.25, 268.75), 20, _RGB32(0, 0, 0): PAINT (556.25, 268.75), _RGB32(0, 0, 0): x1 = 556.25: y1 = 268.75
  387. IF sp3 = 52 THEN CIRCLE (243.75, 331.25), 20, _RGB32(0, 0, 0): PAINT (243.75, 331.25), _RGB32(0, 0, 0): x1 = 243.75: y1 = 331.25
  388. IF sp3 = 54 THEN CIRCLE (368.75, 331.25), 20, _RGB32(0, 0, 0): PAINT (368.75, 331.25), _RGB32(0, 0, 0): x1 = 368.75: y1 = 331.25
  389. IF sp3 = 56 THEN CIRCLE (493.75, 331.25), 20, _RGB32(0, 0, 0): PAINT (493.75, 331.25), _RGB32(0, 0, 0): x1 = 493.75: y1 = 331.25
  390. IF sp3 = 58 THEN CIRCLE (618.75, 331.25), 20, _RGB32(0, 0, 0): PAINT (618.75, 331.25), _RGB32(0, 0, 0): x1 = 618.75: y1 = 331.25
  391. IF sp3 = 61 THEN CIRCLE (181.25, 393.75), 20, _RGB32(0, 0, 0): PAINT (181.25, 393.74), _RGB32(0, 0, 0): x1 = 181.25: y1 = 393.75
  392. IF sp3 = 63 THEN CIRCLE (306.25, 393.75), 20, _RGB32(0, 0, 0): PAINT (306.25, 393.75), _RGB32(0, 0, 0): x1 = 306.25: y1 = 393.75
  393. IF sp3 = 65 THEN CIRCLE (431.25, 393.75), 20, _RGB32(0, 0, 0): PAINT (431.25, 393.75), _RGB32(0, 0, 0): x1 = 431.25: y1 = 393.75
  394. IF sp3 = 67 THEN CIRCLE (556.25, 393.75), 20, _RGB32(0, 0, 0): PAINT (556.25, 393.75), _RGB32(0, 0, 0): x1 = 556.25: y1 = 393.75
  395. IF sp3 = 72 THEN CIRCLE (243.75, 456.25), 20, _RGB32(0, 0, 0): PAINT (243.75, 456.25), _RGB32(0, 0, 0): x1 = 243.75: y1 = 456.25
  396. IF sp3 = 74 THEN CIRCLE (368.75, 456.25), 20, _RGB32(0, 0, 0): PAINT (368.75, 456.25), _RGB32(0, 0, 0): x1 = 368.75: y1 = 456.25
  397. IF sp3 = 76 THEN CIRCLE (493.75, 456.25), 20, _RGB32(0, 0, 0): PAINT (493.75, 456.25), _RGB32(0, 0, 0): x1 = 493.75: y1 = 456.25
  398. IF sp3 = 78 THEN CIRCLE (618.75, 456.25), 20, _RGB32(0, 0, 0): PAINT (618.75, 456.25), _RGB32(0, 0, 0): x1 = 618.75: y1 = 456.25
  399. IF sp3 = 81 THEN CIRCLE (181.25, 518.75), 20, _RGB32(0, 0, 0): PAINT (181.25, 518.75), _RGB32(0, 0, 0): x1 = 181.25: y1 = 518.75
  400. IF sp3 = 83 THEN CIRCLE (306.25, 518.75), 20, _RGB32(0, 0, 0): PAINT (306.25, 518.75), _RGB32(0, 0, 0): x1 = 306.25: y1 = 518.75
  401. IF sp3 = 85 THEN CIRCLE (431.25, 518.75), 20, _RGB32(0, 0, 0): PAINT (431.25, 518.75), _RGB32(0, 0, 0): x1 = 431.25: y1 = 518.75
  402. IF sp3 = 87 THEN CIRCLE (556.25, 518.75), 20, _RGB32(0, 0, 0): PAINT (556.25, 518.75), _RGB32(0, 0, 0): x1 = 556.25: y1 = 518.75
  403.  
  404. 'Now draw the new checker.
  405. IF sp4 = 12 THEN CIRCLE (243.75, 81.25), 20, _RGB32(50, 50, 50): PAINT (243.75, 81.25), _RGB32(50, 50, 50): x2 = 243.75: y2 = 81.25
  406. IF sp4 = 14 THEN CIRCLE (368.75, 81.25), 20, _RGB32(50, 50, 50): PAINT (368.75, 81.25), _RGB32(50, 50, 50): x2 = 368.75: y2 = 81.25
  407. IF sp4 = 16 THEN CIRCLE (493.75, 81.25), 20, _RGB32(50, 50, 50): PAINT (493.75, 81.25), _RGB32(50, 50, 50): x2 = 493.75: y2 = 81.25
  408. IF sp4 = 18 THEN CIRCLE (618.75, 81.25), 20, _RGB32(50, 50, 50): PAINT (618.75, 81.25), _RGB32(50, 50, 50): x2 = 618.75: y2 = 81.25
  409. IF sp4 = 21 THEN CIRCLE (181.25, 143.75), 20, _RGB32(50, 50, 50): PAINT (181.25, 143.75), _RGB32(50, 50, 50): x2 = 181.25: y2 = 143.75
  410. IF sp4 = 23 THEN CIRCLE (306.25, 143.75), 20, _RGB32(50, 50, 50): PAINT (306.25, 143.75), _RGB32(50, 50, 50): x2 = 306.25: y2 = 143.75
  411. IF sp4 = 25 THEN CIRCLE (431.25, 143.75), 20, _RGB32(50, 50, 50): PAINT (431.25, 143.75), _RGB32(50, 50, 50): x2 = 431.25: y2 = 143.75
  412. IF sp4 = 27 THEN CIRCLE (556.25, 143.75), 20, _RGB32(50, 50, 50): PAINT (556.25, 143.75), _RGB32(50, 50, 50): x2 = 556.25: y2 = 143.75
  413. IF sp4 = 32 THEN CIRCLE (243.75, 206.25), 20, _RGB32(50, 50, 50): PAINT (243.75, 206.25), _RGB32(50, 50, 50): x2 = 243.75: y2 = 206.25
  414. IF sp4 = 34 THEN CIRCLE (368.75, 206.25), 20, _RGB32(50, 50, 50): PAINT (368.75, 206.25), _RGB32(50, 50, 50): x2 = 368.75: y2 = 206.25
  415. IF sp4 = 36 THEN CIRCLE (493.75, 206.25), 20, _RGB32(50, 50, 50): PAINT (493.75, 206.25), _RGB32(50, 50, 50): x2 = 493.75: y2 = 206.25
  416. IF sp4 = 38 THEN CIRCLE (618.75, 206.25), 20, _RGB32(50, 50, 50): PAINT (618.75, 206.25), _RGB32(50, 50, 50): x2 = 618.75: y2 = 206.25
  417. IF sp4 = 41 THEN CIRCLE (181.25, 268.75), 20, _RGB32(50, 50, 50): PAINT (181.25, 268.75), _RGB32(50, 50, 50): x2 = 181.25: y2 = 268.75
  418. IF sp4 = 43 THEN CIRCLE (306.25, 268.75), 20, _RGB32(50, 50, 50): PAINT (306.25, 268.75), _RGB32(50, 50, 50): x2 = 306.25: y2 = 268.75
  419. IF sp4 = 45 THEN CIRCLE (431.25, 268.75), 20, _RGB32(50, 50, 50): PAINT (431.25, 268.75), _RGB32(50, 50, 50): x2 = 431.25: y2 = 268.75
  420. IF sp4 = 47 THEN CIRCLE (556.25, 268.75), 20, _RGB32(50, 50, 50): PAINT (556.25, 268.75), _RGB32(50, 50, 50): x2 = 556.25: y2 = 268.75
  421. IF sp4 = 52 THEN CIRCLE (243.75, 331.25), 20, _RGB32(50, 50, 50): PAINT (243.75, 331.25), _RGB32(50, 50, 50): x2 = 243.75: y2 = 331.25
  422. IF sp4 = 54 THEN CIRCLE (368.75, 331.25), 20, _RGB32(50, 50, 50): PAINT (368.75, 331.25), _RGB32(50, 50, 50): x2 = 368.75: y2 = 331.25
  423. IF sp4 = 56 THEN CIRCLE (493.75, 331.25), 20, _RGB32(50, 50, 50): PAINT (493.75, 331.25), _RGB32(50, 50, 50): x2 = 493.75: y2 = 331.25
  424. IF sp4 = 58 THEN CIRCLE (618.75, 331.25), 20, _RGB32(50, 50, 50): PAINT (618.75, 331.25), _RGB32(50, 50, 50): x2 = 618.75: y2 = 331.25
  425. IF sp4 = 61 THEN CIRCLE (181.25, 393.75), 20, _RGB32(50, 50, 50): PAINT (181.25, 393.74), _RGB32(50, 50, 50): x2 = 181.25: y2 = 393.75
  426. IF sp4 = 63 THEN CIRCLE (306.25, 393.75), 20, _RGB32(50, 50, 50): PAINT (306.25, 393.75), _RGB32(50, 50, 50): x2 = 306.25: y2 = 393.75
  427. IF sp4 = 65 THEN CIRCLE (431.25, 393.75), 20, _RGB32(50, 50, 50): PAINT (431.25, 393.75), _RGB32(50, 50, 50): x2 = 431.25: y2 = 393.75
  428. IF sp4 = 67 THEN CIRCLE (556.25, 393.75), 20, _RGB32(50, 50, 50): PAINT (556.25, 393.75), _RGB32(50, 50, 50): x2 = 556.25: y2 = 393.75
  429. IF sp4 = 72 THEN CIRCLE (243.75, 456.25), 20, _RGB32(50, 50, 50): PAINT (243.75, 456.25), _RGB32(50, 50, 50): x2 = 243.75: y2 = 456.25
  430. IF sp4 = 74 THEN CIRCLE (368.75, 456.25), 20, _RGB32(50, 50, 50): PAINT (368.75, 456.25), _RGB32(50, 50, 50): x2 = 368.75: y2 = 456.25
  431. IF sp4 = 76 THEN CIRCLE (493.75, 456.25), 20, _RGB32(50, 50, 50): PAINT (493.75, 456.25), _RGB32(50, 50, 50): x2 = 493.75: y2 = 456.25
  432. IF sp4 = 78 THEN CIRCLE (618.75, 456.25), 20, _RGB32(50, 50, 50): PAINT (618.75, 456.25), _RGB32(50, 50, 50): x2 = 618.75: y2 = 456.25
  433. IF sp4 = 81 THEN CIRCLE (181.25, 518.75), 20, _RGB32(50, 50, 50): PAINT (181.25, 518.75), _RGB32(50, 50, 50): x2 = 181.25: y2 = 518.75
  434. IF sp4 = 83 THEN CIRCLE (306.25, 518.75), 20, _RGB32(50, 50, 50): PAINT (306.25, 518.75), _RGB32(50, 50, 50): x2 = 306.25: y2 = 518.75
  435. IF sp4 = 85 THEN CIRCLE (431.25, 518.75), 20, _RGB32(50, 50, 50): PAINT (431.25, 518.75), _RGB32(50, 50, 50): x2 = 431.25: y2 = 518.75
  436. IF sp4 = 87 THEN CIRCLE (556.25, 518.75), 20, _RGB32(50, 50, 50): PAINT (556.25, 518.75), _RGB32(50, 50, 50): x2 = 556.25: y2 = 518.75
  437.  
  438. 'Check for a jump.
  439. IF pv3 - pv4 = 2 OR pv4 - pv3 = 2 THEN
  440.     IF ph3 - ph4 = 2 OR ph4 - ph3 = 2 THEN
  441.         IF x1 > x2 THEN stp = -.25
  442.         IF x1 < x2 THEN stp = .25
  443.         IF y1 > y2 THEN stp2 = -.25
  444.         IF y1 < y2 THEN stp2 = .25
  445.         yy = y1
  446.         FOR xx = x1 TO x2 STEP stp
  447.             yy = yy + stp2
  448.             IF POINT(xx, yy) = _RGB32(200, 50, 50) THEN
  449.                 PAINT (xx, yy), _RGB32(0, 0, 0)
  450.                 GOTO nex2:
  451.             END IF
  452.         NEXT xx
  453.     END IF
  454. nex2:
  455.  
  456. 'Check for a King.
  457. IF ph4 = 8 THEN
  458.     k2 = k2 + 1
  459.     bking(k2) = black2(ch2)
  460.     GOSUB drawking:
  461. FOR cch = 1 TO 88
  462.     IF bking(cch) = black2(cch) AND bking(cch) <> 0 THEN GOSUB drawking:
  463. NEXT cch
  464.  
  465. 'Check for a win.
  466. FOR wx = 0 TO 800
  467.     FOR wy = 0 TO 600
  468.         IF POINT(wx, wy) = _RGB32(200, 50, 50) THEN GOTO nex4:
  469.     NEXT wy
  470. NEXT wx
  471. COLOR _RGB32(255, 0, 0)
  472. LOCATE 3, 87: PRINT "Black Wins!"
  473.  
  474. nex4:
  475. LOCATE 5, 5: PRINT "           ": LOCATE 6, 5: PRINT "            "
  476. LOCATE 7, 5: PRINT "           ": LOCATE 8, 5: PRINT "            "
  477. LOCATE 10, 5: PRINT "           ": LOCATE 11, 5: PRINT "            "
  478. LOCATE 12, 5: PRINT "           ": LOCATE 13, 5: PRINT "            "
  479. LOCATE 15, 5: PRINT "            "
  480.  
  481. 'Go back to Player One
  482. GOTO one:
  483.  
  484. 'Draw the king symbol on the piece.
  485. drawking:
  486. LINE (x2 - 10, y2 + 10)-(x2 + 10, y2 + 10), _RGB32(255, 255, 255)
  487. LINE (x2 - 10, y2 + 7)-(x2 + 10, y2 + 7), _RGB32(255, 255, 255)
  488. LINE (x2 - 10, y2 + 7)-(x2 - 15, y2 - 2), _RGB32(255, 255, 255)
  489. CIRCLE (x2 - 15, y2 - 5), 3, _RGB32(255, 255, 255)
  490. LINE (x2 - 15, y2 - 2)-(x2 - 5, y2), _RGB32(255, 255, 255)
  491. LINE (x2 - 5, y2)-(x2, y2 - 4), _RGB32(255, 255, 255)
  492. CIRCLE (x2, y2 - 7), 3, _RGB32(255, 255, 255)
  493. LINE (x2 + 10, y2 + 7)-(x2 + 15, y2 - 2), _RGB32(255, 255, 255)
  494. CIRCLE (x2 + 15, y2 - 5), 3, _RGB32(255, 255, 255)
  495. LINE (x2 + 15, y2 - 2)-(x2 + 5, y2), _RGB32(255, 255, 255)
  496. LINE (x2 + 5, y2)-(x2, y2 - 4), _RGB32(255, 255, 255)
  497.  


Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: A 90% complete chess engine
« Reply #28 on: February 02, 2020, 04:50:27 pm »
Hi Ken,

Ah so that's what you've been up to! I wish you started a new thread, so I could join in. This one is already all over the place with chess.

I look forward to checking it out, thanks.

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: A 90% complete chess engine
« Reply #29 on: February 02, 2020, 05:40:47 pm »
I'll make a new thread for it.