Author Topic: Chess developed from QB64 Samples  (Read 11421 times)

0 Members and 1 Guest are viewing this topic.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Chess developed from QB64 Samples
« on: August 20, 2018, 12:54:18 am »
We had come quite a distance from the sample program.
Code: QB64: [Select]
  1. _TITLE "Chess 2017-11-22 T .bas     Ctrl+K for Keyboard input"
  2. '2017-10-10 raw patch of Interface to Chess.bas post update with mouse troubles
  3.  
  4. ' 22 10 2017 New fix to Incheck function, I hope the last!
  5. ' 22 10 2017  empowered promotion by mouse
  6. ' 22 10 2017  fix promotion visible only after move of black
  7. ' 22 10 2017 castle by mouse
  8. ' 22 10 2017  empowered castling control, now you cannot castle if they are in check
  9. '             or across a square that is under Black control
  10. ' 22 10 2017 translated in sub Info_Help screen
  11. ' 22 10 2017  translate in sub Fellippe's Wait click and key
  12. ' 22 10 2017 added logical end to the main of program
  13. ' 22 10 2017 put away all code REMMED not yet used
  14.  
  15. '2017 10 24 changed board graphics, arranged alpha order subs, updated highlite square
  16. ' Thanks Adrian Huang
  17. ' http://www.thejoyfulprogrammer.com/qb64/forum/showthread.php?tid=401&rndtime=1508625987687357559
  18.  
  19. '2017 10 24 Incorporate TempodiBasic's legalShow and legalHide routines
  20. ' fix pawn promotions see Ppromote$
  21. ' count pieces captured and show with board
  22. ' install game recorder
  23.  
  24. ' 27 10 2017 color of chessboard are CONST
  25. ' resizing square and character size to  42
  26. ' moving list of piece captured at top right
  27. ' moving output at bottom right
  28. ' new SUB ShowSetup that shows whole setup to choose pieces for white and black,
  29. ' or only pieces capturable (No king because when a King falls game stops!)
  30. ' or only pieces for promotion (Knight Bishop Rook Queen) for both colors
  31. ' now if Black resigns the flow of program ends after main do loop to let replay the game
  32. ' play again label structure and initialization instruction (it is possible to use a DO LOOP)
  33. ' Added ButtonMenuBar at bottom using MakeButton SUB
  34. ' Button QUIT working, button PLAY works for now let us play only as WHITE
  35. ' Build an area for list of moves
  36. ' build an area for output/feedback of program
  37. ' Changed Helpscreen instruction including mouse selection
  38. ' >>>> wow lots of new stuff
  39.  
  40. '2017-10-29/30 fixed dots in empty squares, highlight piece clicked, thing crawling under board while computer thinks
  41. ' now if we can only get the colors ;-)) Outer loop to restart game, elimate some boxes, less cluttered looking.
  42. ' change title to version = date easier to track
  43.  
  44. '2017 10 31 T  Yes I follow you in using date also if in my country I use DD-MM-YYYY   :-)
  45. '  YES fixed BIG BUG about restart and Play Again lasting the last moves in memory... and in File Recorder
  46.  
  47. '2017-11-01 B review TempodiBasic's BIG BUG fix, clean up lines, comments and variables
  48. ' I (bplus) see some work also done in IO for checking checks, I assume.
  49.  
  50. '2017-11-03 B Move Intro to before main program loop, fix some things with promotion
  51. ' prompt for pieces, pWflag$, pBflag$ to add to move list
  52.  
  53. '2017-11-04 B hack AI this is just an experiment for my cat who is always curious specially
  54. ' because it exists in another universe.
  55.  
  56. '2017-11-06 A 2nd post (really posted 11-05) Added/revised code for rotating board to play Black.
  57. ' Adrain has change 5000 number to 9000 im several places and I don't know if this fixes castle
  58. ' It did fix notation in the moves list correctly
  59.  
  60. '2017-11-05 B  from Adrian's 2nd post 2017-11-06( posted 11-05) A #2   continuing with hackBlack hacks!
  61. ' I noticed that code changes were very alike and one fuction would save quite a bit of code FIXED
  62. ' I also noticed the captured pieces were backwards when Black plays FIXED
  63. ' I noticed Black cant castle yet BIGGEST FIX of them all!!!
  64. ' I noticed Ctrl+K for human playing Black did not work, well had to translate move back so
  65. ' IO can reverse again!!  FIXED!
  66. ' Check pawn promotion and track down source of mystery q added to computer's moves.
  67. ' Still allot of goofy things...
  68.  
  69. '2017-11-07 A - removed fake 1st move while playing black
  70.  
  71. '2017-11-07 B hack 2 using above mod but with EXIT SUB instead of GOTO
  72. ' fix capture counts so that only positive counts show
  73. ' Ah found source of allot of goofyness!  hackBlack > playBlack per Adrian
  74. ' I think I have this working correctly through Play Again Y/N?
  75.  
  76. '2017-11-07 T put away GOTO for label 100 to play again
  77. ' moved in main loop AI resign (strange as white it capture by King and then when you takes King it resign!!!
  78. ' GOOD first AI goes on playing without king :-)
  79. '
  80. '2017-11-07 2B removed 100 next to loop since no goto, fixed comments on separate line
  81. ' and added some comments, I think I have finally tracked down source of extra q's!!! FIXED
  82.  
  83. ' 2017-11-10 T  fixed promotion  failure with strange choose made clicking on the other side of window of program
  84. ' at the Y of piece to get by promotion
  85. '   Restored  MAXLEVEL at beginning of program to set power of AI
  86. '
  87. ' 2017-11-10 2T cutting some old comments no more useful for use about issues yet resolved
  88. ' packing the 2 initboard to one (they do the same work with 2 different labels)
  89. '
  90. '2017-11-11 B Put T comments on separate line from code.
  91. 'Recommend making MAXLEVEL a CONST if we will not change it ever.
  92. 'Tell why two different boards are needed to initialize the board positions.
  93. 'Fix pWfalg$ again! that AI has no business changing BUT OK save ElSE block because AI
  94. 'may need to plan for eventual pawn promotion and assuming a Queen is smart assumption.
  95. '
  96. ' 2017-11-13 T  fixed incheck failure and strange moves of king under check using a new shared flag Turn
  97. ' to let analize only the important pieces by INCHECK Function, they are different for White and for Black
  98. ' re-written in MAKEMOVE SUB (sub that makes the move on the board and check for promotion and makes the promotion if is the case
  99. ' the ELSE.. END IF part for white (Human) player is needed together INTFLAG  =1 humang chooses by himself piece in promotion, =0 autochoosed Queen
  100. ' also fixed extra q by inizilization of pWflag$ at start of SUB
  101. '
  102. '2017-11-15 B start work on Undo, Save and Load
  103. ' 2 functions cp2n(piece$), cn2p$(number), for converting a board to a bString$ letter and vice versa
  104. ' bString$ will get all board positions loaded in 64 character string
  105. ' bSetyp will setup a board from a bString$ used for UNDO, Save, Load and future SETUP
  106. ' Center text in a button
  107. ' Now reworked initBoard so initBlack sub can be eliminated and initBoard shrunk, now eliminated also!
  108. ' Now add stuff to make UNDO possible. new Boards$() array works along with Move$(), Boards$() has bString$ of board positions
  109. ' Incorp TempodiBasic changes to AI checking for Check (Chess 2_17-11-13 T) :
  110. '    Use new glabal varaible Turn = 1 for White's and -1 for Black, might come in handy! Yes on loading Game
  111. '        Eliminate the infinite crap I'd rather have AI King commiting suicide as a form of Resign for testing all other stuff
  112. '           Except Then AI plays old trick of putting oppenent into Check for which human is not allowed to take AI KING because in check!!! phooey!
  113. ' Moved ShowButton Bar and showMoveList into ShowBd and gave showMoveList a diet
  114. ' No more File recorder, eliminate Datetime, fix UNDO for trying to go less than 1
  115. ' Remove InitBoard sub, all done in getInput button section
  116.  
  117. ' Fix a ton of bugs to get all this integrated and working together but more keep popping up, blah!
  118. ' Make Result global to fix Y/N question to start over when Y
  119. ' Modify restart to clean slate the entire program, then use buttons to set particular settings needed
  120. ' Bug Loading a game right after Loading a game may cause an error
  121. ' Bug sometimes QB64 _FILEEXISTS says a real file that you typed correctly can't be found, just type it in again.
  122. ' I put a double _FILEEXISTS call in with delay between, helps but still the bug remains!!!
  123. ' Bug missing line when human loads a file playing black and starts game from there.
  124. ' Ugly fix that I doubt will work in other cases
  125.  
  126. '2017-11-16 A Tried to fix bug when AI is checkmated by modifying INCHECK function
  127. '             Minor changes - removed 1 set of board labels. display pieces centrally on squares
  128.  
  129. '2017-11-16 B Adrian some nice changes to board but please no PlayAgain: label, no GOTO unless best way
  130. ' I do not like ending the whole application in the InCheck sub,  nor do I think one time result <-2500 is cause to quit??
  131. ' Remember AI checks many moves with InCheck, I am afraid it might quit first time it gets result < -2500 with better result left.
  132. ' Also I fix my omission with loadFlag code in IO, and it turns out with UNDO we have to clear the capture amounts, fixed.
  133.  
  134. '2017-11-18 A1: Changed White King Value to 4500, Black King value to -9000. Added test for AI's resignation in IO SUB. This should fix the AI check bug, and probably means that the
  135. '           IN CHECK function need not check for checks to AI's king.
  136.  
  137. '2017-11-19 T: fixing the covering of the left border of buttonbar (Movelist too large passed from 700 to 680)
  138. ' 2017-11-22 T: fixing dummy _fileexists, it seems we don't need it yet
  139. ' 2017 11 22 T : coded manageDummySystem on save file, 1. now you can save only a game in progress  (no game = nothing to save)
  140. '                                                      2. now you can overwrite an existing file only if you confirm to overwrite it
  141. '                coded  feedback LoadFile in areaoutput
  142.  
  143.  
  144. CONST XMAX = 900
  145. CONST YMAX = 600
  146. CONST WHITE& = &HFFDDDDDD
  147. CONST BLACK& = &HFF000000
  148. CONST LITE& = &HFFFFFF00
  149. CONST LITE2& = _RGB32(78, 161, 72)
  150. CONST WHITES& = _RGB32(140, 160, 190)
  151. CONST BLACKS& = _RGB32(0, 130, 70)
  152. CONST SQ = 42
  153. 'T here (B out side of restart sub) we need a Maxlevel
  154. CONST MAXLEVEL = 5
  155. 'B might as well make constant!
  156.  
  157. 'B For fonts
  158. COMMON SHARED FW, FH, normal&, maxCol, bArial&, bFW, bFH
  159.  
  160. 'B For human playing Black
  161. COMMON SHARED playBlack, bmoves$, bFirst
  162.  
  163. 'B from original QB64 samples: chess.bas
  164. DIM SHARED BOARD(0 TO 7, 0 TO 7)
  165. DIM SHARED BESTA(0 TO 7), BESTB(0 TO 7), BESTX(0 TO 7), BESTY(0 TO 7)
  166. DIM SHARED LEVEL, SCORE, result
  167. DIM SHARED wcKsflag, wcQsflag, INTFLAG
  168. DIM SHARED wcKsold, wcQsold
  169.  
  170. 'B For saving moves to file
  171. DIM SHARED whiteMove$, blackMove$, pWflag$, pBflag$, GameFile$, Turn
  172.  
  173. 'B For displaying T's on screen list of moves, last 8 shown from Moves$() array
  174. DIM SHARED InGame, countMove, loadFlag
  175. REDIM SHARED Move$(1 TO 300)
  176.  
  177. 'B for Undo
  178. REDIM SHARED Boards$(1 TO 300)
  179.  
  180. 'B Using updated Graphics Screen instead of Screen 0 text program
  181. SCREEN _NEWIMAGE(XMAX, YMAX, 32)
  182. _SCREENMOVE 360, 60
  183.  
  184. 'B Checking fonts normal, big, and chess
  185. 'B load and check our normal font
  186. normal& = _LOADFONT("C:\windows\fonts\arial.ttf", 20)
  187. IF normal& <= 0 THEN PRINT "Trouble with arial.ttf size 16 file, goodbye.": SLEEP: END
  188. _FONT normal&
  189. FW = 11: FH = _FONTHEIGHT(normal&)
  190. maxCol = XMAX / FW
  191.  
  192. 'B load and check SQ size font
  193. bArial& = _LOADFONT("C:\windows\fonts\arial.ttf", SQ, "MONOSPACE")
  194. IF bArial& <= 0 THEN PRINT "Trouble with arial.ttf size "; SQ; " file, goodbye.": SLEEP: END
  195. bFW = _FONTWIDTH(bArial&): bFH = _FONTHEIGHT(bArial&)
  196.  
  197. Intro
  198. Wait_Click_Key
  199.     SCORE = 0
  200.     CALL IO(A, b, x, Y, result)
  201.     'B   HERE IS WHERE CHECKMATE NEEDS TO BE DETERMINED!!!
  202.     IF result < -2500 THEN
  203.         'T & B Human has won
  204.         AreaOutput "I RESIGN!! YOU WIN!!!", " Play Again? Y/N "
  205.         DO
  206.             Revenge$ = UCASE$(INKEY$)
  207.         LOOP UNTIL Revenge$ = "Y" OR Revenge$ = "N"
  208.         IF Revenge$ = "N" THEN
  209.             AreaOutput "Thanks for playing,", "Good Bye!"
  210.             SLEEP 2
  211.             SYSTEM
  212.         END IF
  213.         restart
  214.         InGame = 0
  215.     ELSE
  216.         result = EVALUATE(-1, 10000)
  217.         A = BESTA(1)
  218.         b = BESTB(1)
  219.         x = BESTX(1)
  220.         Y = BESTY(1)
  221.     END IF
  222.     CALL SHOWBD
  223.  
  224. '==========================================================
  225.  
  226. 'B sub for user communications area, T has made it for two strings
  227. SUB AreaOutput (outText$, out2$)
  228.     LINE (480, 510)-(XMAX, YMAX), BLACK&, BF
  229.     lp 26, 46, outText$
  230.     lp 27, 46, out2$
  231.  
  232. SUB BISHOP (A, B, XX(), YY(), NDX)
  233.     ID = SGN(BOARD(B, A))
  234.     FOR DXY = 1 TO 7
  235.         X = A - DXY
  236.         Y = B + DXY
  237.         IF X < 0 OR X > 7 OR Y < 0 OR Y > 7 THEN EXIT FOR
  238.         GOSUB 3
  239.         IF BOARD(Y, X) <> 0 THEN EXIT FOR
  240.     NEXT
  241.     FOR DXY = 1 TO 7
  242.         X = A + DXY
  243.         Y = B + DXY
  244.         IF X < 0 OR X > 7 OR Y < 0 OR Y > 7 THEN EXIT FOR
  245.         GOSUB 3
  246.         IF BOARD(Y, X) <> 0 THEN EXIT FOR
  247.     NEXT
  248.     FOR DXY = 1 TO 7
  249.         X = A - DXY
  250.         Y = B - DXY
  251.         IF X < 0 OR X > 7 OR Y < 0 OR Y > 7 THEN EXIT FOR
  252.         GOSUB 3
  253.         IF BOARD(Y, X) <> 0 THEN EXIT FOR
  254.     NEXT
  255.     FOR DXY = 1 TO 7
  256.         X = A + DXY
  257.         Y = B - DXY
  258.         IF X < 0 OR X > 7 OR Y < 0 OR Y > 7 THEN EXIT FOR
  259.         GOSUB 3
  260.         IF BOARD(Y, X) <> 0 THEN EXIT FOR
  261.     NEXT
  262.     EXIT SUB
  263.  
  264.     'sub gosub subroutine
  265.    3 REM
  266.     IF ID <> SGN(BOARD(Y, X)) THEN
  267.         NDX = NDX + 1
  268.         XX(NDX) = X
  269.         YY(NDX) = Y
  270.     END IF
  271.     RETURN
  272.  
  273. SUB bSetup (bStr$)
  274.     FOR X = 0 TO 7
  275.         FOR Y = 0 TO 7
  276.             p$ = MID$(bStr$, 8 * X + Y + 1, 1)
  277.             BOARD(X, Y) = cp2n(p$)
  278.         NEXT
  279.     NEXT
  280.  
  281. FUNCTION bString$
  282.     r$ = ""
  283.     FOR X = 0 TO 7
  284.         FOR Y = 0 TO 7
  285.             num = BOARD(X, Y)
  286.             r$ = r$ + cn2p$(num)
  287.         NEXT
  288.     NEXT
  289.     bString$ = r$
  290.  
  291. FUNCTION Castleincheck (x)
  292.     'T added to improve short castle control
  293.     IF playBlack THEN
  294.         BOARD(7, 1) = 4500
  295.         'T first square acrossed
  296.         null = INCHECK(x)
  297.         BOARD(7, 1) = 0
  298.         'T original square void
  299.         IF null = 0 THEN
  300.             'T if already in first test King is in check we skip second test
  301.             BOARD(7, 2) = 4500
  302.             'T second square acrossed
  303.             null = INCHECK(x)
  304.             BOARD(7, 2) = 0
  305.         END IF
  306.         Castleincheck = null
  307.     ELSE
  308.         BOARD(7, 6) = 4500
  309.         'T first square acrossed
  310.         null = INCHECK(x)
  311.         BOARD(7, 6) = 0
  312.         'T original square void
  313.         IF null = 0 THEN
  314.             'T if already in first test King is in check we skip second test
  315.             BOARD(7, 5) = 4500
  316.             'T second square acrossed
  317.             null = INCHECK(x)
  318.             BOARD(7, 5) = 0
  319.         END IF
  320.         Castleincheck = null
  321.     END IF
  322.  
  323. FUNCTION CastleincheckL (x)
  324.     'T added to improve long castle control
  325.     IF playBlack THEN
  326.         BOARD(7, 4) = 4500
  327.         null = INCHECK(x)
  328.         BOARD(7, 4) = 0
  329.         'T original square void
  330.         IF null = 0 THEN
  331.             'T if already in first test King is in check we skip second test
  332.             BOARD(7, 5) = 4500
  333.             'T C1 square
  334.             null = INCHECK(x)
  335.             BOARD(7, 5) = 0
  336.         END IF
  337.         CastleincheckL = null
  338.     ELSE
  339.         BOARD(7, 3) = 4500
  340.         'T or B or A D1 square
  341.         null = INCHECK(x)
  342.         BOARD(7, 3) = 0
  343.         'T original square void
  344.         IF null = 0 THEN
  345.             'T if already in first test King is in check we skip second test
  346.             BOARD(7, 2) = 4500
  347.             'T C1 square
  348.             null = INCHECK(x)
  349.             BOARD(7, 2) = 0
  350.         END IF
  351.         CastleincheckL = null
  352.     END IF
  353.  
  354. FUNCTION cn2p$ (n)
  355.     SELECT CASE n
  356.         CASE 0: r$ = "z"
  357.         CASE 100: r$ = "P"
  358.         CASE 270: r$ = "N"
  359.         CASE 300: r$ = "B"
  360.         CASE 500: r$ = "R"
  361.         CASE 900: r$ = "Q"
  362.         CASE 4500: r$ = "K"
  363.         CASE -100: r$ = "p"
  364.         CASE -270: r$ = "n"
  365.         CASE -300: r$ = "b"
  366.         CASE -500: r$ = "r"
  367.         CASE -900: r$ = "q"
  368.         CASE -9000: r$ = "k"
  369.     END SELECT
  370.     cn2p$ = r$
  371.  
  372. FUNCTION cp2n (piece$)
  373.     SELECT CASE piece$
  374.         CASE "z": r = 0
  375.         CASE "P": r = 100
  376.         CASE "N": r = 270
  377.         CASE "B": r = 300
  378.         CASE "R": r = 500
  379.         CASE "Q": r = 900
  380.         CASE "K": r = 4500
  381.         CASE "p": r = -100
  382.         CASE "n": r = -270
  383.         CASE "b": r = -300
  384.         CASE "r": r = -500
  385.         CASE "q": r = -900
  386.         CASE "k": r = -9000
  387.     END SELECT
  388.     cp2n = r
  389.  
  390. SUB cP (row, txt$)
  391.     'B on row center Print txt$
  392.     col = (maxCol - LEN(txt$)) / 2
  393.     _PRINTSTRING ((XMAX - _PRINTWIDTH(txt$)) / 2, row * FH), txt$
  394.  
  395. FUNCTION EVALUATE (ID, PRUNE)
  396.     DIM XX(0 TO 26), YY(0 TO 26)
  397.     LEVEL = LEVEL + 1
  398.     BESTSCORE = 10000 * ID
  399.     FOR b = 7 TO 0 STEP -1
  400.         FOR A = 7 TO 0 STEP -1
  401.             IF SGN(BOARD(b, A)) <> ID THEN GOTO 1
  402.             'Orig IF (LEVEL = 1) THEN CALL SHOWMAN(A, B)
  403.             'B this might be human versus human level?
  404.  
  405.             CALL MOVELIST(A, b, XX(), YY(), NDX)
  406.             FOR I = 0 TO NDX
  407.                 X = XX(I)
  408.                 Y = YY(I)
  409.                 IF LEVEL = 1 THEN
  410.                     AreaOutput "TRYING: " + CHR$(65 + A) + RIGHT$(STR$(8 - b), 1) + "-" + CHR$(65 + X) + RIGHT$(STR$(8 - Y), 1), ""
  411.                     'B Might as well make this look nice too, without the space
  412.                 END IF
  413.                 OLDSCORE = SCORE
  414.                 MOVER = BOARD(b, A)
  415.                 TARGET = BOARD(Y, X)
  416.                 CALL MAKEMOVE(A, b, X, Y)
  417.                 IF (LEVEL < MAXLEVEL) THEN SCORE = SCORE + EVALUATE(-ID, BESTSCORE - TARGET + ID * (8 - ABS(4 - X) - ABS(4 - Y)))
  418.                 SCORE = SCORE + TARGET - ID * (8 - ABS(4 - X) - ABS(4 - Y))
  419.                 IF (ID < 0 AND SCORE > BESTSCORE) OR (ID > 0 AND SCORE < BESTSCORE) THEN
  420.                     BESTA(LEVEL) = A
  421.                     BESTB(LEVEL) = b
  422.                     BESTX(LEVEL) = X
  423.                     BESTY(LEVEL) = Y
  424.                     BESTSCORE = SCORE
  425.                     IF (ID < 0 AND BESTSCORE >= PRUNE) OR (ID > 0 AND BESTSCORE <= PRUNE) THEN
  426.                         BOARD(b, A) = MOVER
  427.                         BOARD(Y, X) = TARGET
  428.                         SCORE = OLDSCORE
  429.                         LEVEL = LEVEL - 1
  430.                         EVALUATE = BESTSCORE
  431.                         EXIT FUNCTION
  432.                     END IF
  433.                 END IF
  434.                 BOARD(b, A) = MOVER
  435.                 BOARD(Y, X) = TARGET
  436.                 SCORE = OLDSCORE
  437.             NEXT
  438.        1 NEXT
  439.     NEXT
  440.     LEVEL = LEVEL - 1
  441.     EVALUATE = BESTSCORE
  442.  
  443. FUNCTION getInput$
  444.     DIM pieceChosen AS _BYTE
  445.     DO
  446.         'B Update board
  447.         SHOWBD
  448.  
  449.         'B gather mouse input
  450.         DO WHILE _MOUSEINPUT
  451.             mouseButton = _MOUSEBUTTON(1)
  452.             tx = _MOUSEX \ SQ - 1: ty = _MOUSEY \ SQ - 1
  453.             ux = tx: uy = ty
  454.         LOOP
  455.  
  456.         'T area of managing Button Bar
  457.         IF _MOUSEBUTTON(1) THEN
  458.             IF _MOUSEX > 700 THEN
  459.                 IF _MOUSEY < 120 THEN
  460.                     'B PLAY WHITE
  461.                     restart
  462.                     InGame = -1
  463.                     Turn = 1
  464.                     playBlack = 0
  465.                     bSetup "rnbqkbnrppppppppzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzPPPPPPPPRNBQKBNR"
  466.                     AreaOutput "Your move.", ""
  467.                     getInput$ = ""
  468.                     EXIT FUNCTION
  469.                 ELSEIF _MOUSEY < 180 THEN
  470.                     'B PLAY BLACK there was a FEN around here also
  471.  
  472.                     'T this is the FEN of initial game setup
  473.                     '  [rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1]
  474.                     restart
  475.                     InGame = -1
  476.                     Turn = -1
  477.                     playBlack = -1
  478.                     bSetup "rnbkqbnrppppppppzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzPPPPPPPPRNBKQBNR"
  479.                     getInput$ = ""
  480.                     EXIT FUNCTION
  481.                 ELSEIF _MOUSEY < 240 THEN
  482.                     'B UNDO
  483.                     IF countMove - 1 > 1 THEN
  484.                         Move$(countMove) = ""
  485.                         Boards$(countMove) = ""
  486.                         countMove = countMove - 1
  487.                         whiteMove$ = "": blackMove$ = "": bmoves$ = "": bFirst = -1
  488.                         bSetup Boards$(countMove)
  489.                         IF playBlack = 0 THEN AreaOutput "Your move.", ""
  490.                         '_DISPLAY
  491.                         EXIT FUNCTION
  492.                     END IF
  493.                 ELSEIF _MOUSEY < 300 THEN
  494.                     'B SAVE BOARD
  495.                     'T if you are not in game what are you saving in a file?
  496.                     IF InGame = 0 THEN EXIT FUNCTION
  497.                     ' T file exists, overwirte? Y/N
  498.                     DO
  499.                         in$ = ""
  500.                         in$ = screenInput(50 * FW, 4 * FH, "Enter Save Filename > ")
  501.                         IF _FILEEXISTS(in$) = -1 AND in$ <> "" THEN
  502.                             COLOR LITE&
  503.                             AreaOutput "File exists...", " Overwrite Y/N?"
  504.                             _DISPLAY
  505.                             COLOR WHITE&
  506.                             choice$ = UCASE$(INPUT$(1))
  507.                             IF choice$ = "Y" THEN EXIT DO
  508.                         ELSE
  509.                             ' case _fileexists(in$) = 0
  510.                             EXIT DO
  511.                         END IF
  512.  
  513.                     LOOP
  514.  
  515.                     OPEN in$ FOR OUTPUT AS #1
  516.                     IF playBlack THEN PRINT #1, "Black" ELSE PRINT #1, "White"
  517.                     PRINT #1, blackMove$
  518.                     'we need AI's move made if any since last Move$() entry
  519.                     FOR i = 1 TO countMove
  520.                         PRINT #1, Move$(i)
  521.                     NEXT
  522.                     FOR i = 1 TO countMove
  523.                         PRINT #1, Boards$(i)
  524.                     NEXT
  525.                     CLOSE #1
  526.                     AreaOutput "File " + ins$, "loaded"
  527.                     _DELAY 1
  528.                     IF playBlack = 0 THEN
  529.                         AreaOutput "Your move.", ""
  530.                     ELSE
  531.                         bmove$ = blackMove$
  532.                         bFirst = 0
  533.                     END IF
  534.                     getInput$ = ""
  535.                     EXIT FUNCTION
  536.                 ELSEIF _MOUSEY < 360 THEN
  537.                     'B  LOAD Board
  538.                     in$ = screenInput(50 * FW, 4 * FH, "Enter Load Filename > ")
  539.                     'B  for some damn reason the first time you try _FILEEXISTS with real file it says 0 nope!
  540.                     'B                 but try again and is OK ?????????????????????????????????????????
  541.                     'B                 So f... IT!
  542.                     ' dummy = _FILEEXISTS(in$)
  543.                     '_DELAY 1
  544.                     'B  once is not enough, damn this sucks!!!!!!
  545.                     'dummy = _FILEEXISTS(in$)
  546.                     '_DELAY 1
  547.                     'B  nope didn't help with 2nd call and delay, just try LOAD GAME again!
  548.                     IF _FILEEXISTS(in$) = -1 THEN
  549.  
  550.                         count = 0
  551.                         OPEN in$ FOR INPUT AS #1
  552.                         WHILE EOF(1) = 0
  553.                             INPUT #1, l$
  554.                             count = count + 1
  555.                         WEND
  556.                         CLOSE #1
  557.  
  558.                         ' T feedback to user
  559.                         COLOR LITE&
  560.                         AreaOutput "File loaded", in$
  561.                         COLOR WHITE&
  562.                         _DISPLAY
  563.                         _DELAY 1
  564.  
  565.                         restart
  566.                         countMove = (count - 2) / 2
  567.                         'B This gets needed data items before loading 2 arrays of size countMove
  568.                         OPEN in$ FOR INPUT AS #1
  569.                         INPUT #1, BW$
  570.                         IF LEFT$(BW$, 1) = "B" THEN playBlack = -1 ELSE playBlack = 0
  571.                         INPUT #1, blackMove$
  572.                         'B  this gets AI's last move (if any) not recorded in Move$()
  573.                         '   OK maybe we have to pretend the blackMove$ is whiteMove$ so IO can reverse it when recording in Move$()
  574.                         FOR i = 1 TO countMove
  575.                             INPUT #1, Move$(i)
  576.                         NEXT
  577.                         FOR i = 1 TO countMove
  578.                             INPUT #1, Boards$(i)
  579.                         NEXT
  580.                         CLOSE #1
  581.                         CLS
  582.                         bSetup Boards$(countMove)
  583.                         'B loadFlag is ugly way to fix a missing line in move list that occurs loading a game with human playing Black
  584.                         IF playBlack = 0 THEN AreaOutput "Your move.", "" ELSE loadFlag = -1
  585.                         InGame = -1
  586.                     ELSE
  587.                         AreaOutput in$, "File not found."
  588.                     END IF
  589.                 ELSEIF _MOUSEY < 420 THEN
  590.                     'B MANUAL SET
  591.                 ELSEIF _MOUSEY < 480 THEN
  592.                     'T quit
  593.                     getInput$ = "QUIT"
  594.                     EXIT FUNCTION
  595.                 END IF
  596.             END IF
  597.         END IF
  598.  
  599.         IF InGame = -1 THEN
  600.             IF pieceChosen = 0 THEN
  601.                 IF 1 <= ty AND ty <= 8 THEN
  602.                     'Fellippe or B translate hovered coordinate to chess notation letter + digit
  603.                     d$ = RIGHT$(STR$(9 - ty), 1)
  604.                     IF 1 <= tx AND tx <= 8 THEN
  605.                         l$ = CHR$(64 + tx)
  606.                         ld$ = l$ + d$
  607.                         'B letter + digit
  608.                         ld2xy ld$, bx, by
  609.                         'B translate notation to board$(x, y)
  610.                         IF BOARD(by, bx) > 0 THEN
  611.                             LegalShow bx, by
  612.                             highLightSq bx, by, LITE2&
  613.                             'Fellippe hover highlight
  614.                             IF mouseButton THEN
  615.                                 DO WHILE mouseButton
  616.                                     'Fellippe wait for release
  617.                                     i = _MOUSEINPUT
  618.                                     mouseButton = _MOUSEBUTTON(1)
  619.                                     newtx = _MOUSEX \ SQ - 1: newty = _MOUSEY \ SQ - 1
  620.                                 LOOP
  621.                                 IF newtx = tx AND newty = ty THEN
  622.                                     'Fellippe the mouse was released in the same square
  623.                                     pieceChosen = -1: chosenBX = bx: chosenBY = by
  624.                                 END IF
  625.                             END IF
  626.                         END IF
  627.                     END IF
  628.                 END IF
  629.             ELSE
  630.                 LegalShow chosenBX, chosenBY
  631.                 highLightSq chosenBX, chosenBY, LITE&
  632.                 IF 1 <= uy AND uy <= 8 THEN
  633.                     'B translate click to chess notation letter + digit
  634.                     d2$ = RIGHT$(STR$(9 - uy), 1)
  635.                     IF 1 <= ux AND ux <= 8 THEN
  636.                         l2$ = CHR$(64 + ux)
  637.                         ld2$ = l2$ + d2$
  638.                         'B letter + digit
  639.                         ld2xy ld2$, bx2, by2
  640.                         highLightSq bx2, by2, LITE2&
  641.                         'Fellippe hover highlight
  642.                         IF mouseButton THEN
  643.                             DO WHILE mouseButton
  644.                                 'Fellippe wait for release
  645.                                 i = _MOUSEINPUT
  646.                                 mouseButton = _MOUSEBUTTON(1)
  647.                                 newtx = _MOUSEX \ SQ - 1: newty = _MOUSEY \ SQ - 1
  648.                             LOOP
  649.                             IF newtx = tx AND newty = ty THEN
  650.                                 'Fellippe the mouse was released in the same square
  651.                                 IF ld$ <> ld2$ THEN
  652.                                     getInput$ = ld$ + "-" + ld2$
  653.                                     'T this let AI to castle for white
  654.                                     IF BOARD(by, bx) = 4500 THEN
  655.                                         IF ld$ = "E1" AND ld2$ = "G1" THEN getInput$ = "O-O"
  656.                                         IF ld$ = "E1" AND ld2$ = "C1" THEN getInput$ = "O-O-O"
  657.                                         IF playBlack = -1 THEN
  658.                                             IF ld$ = "D1" AND ld2$ = "B1" THEN getInput$ = "O-O"
  659.                                             IF ld$ = "D1" AND ld2$ = "F1" THEN getInput$ = "O-O-O"
  660.                                         END IF
  661.                                     END IF
  662.                                     _AUTODISPLAY
  663.                                     EXIT FUNCTION
  664.                                 ELSE
  665.                                     LegalHide bx, by
  666.                                     SHOWMAN bx, by
  667.                                     EXIT DO
  668.                                 END IF
  669.                                 'B ld compare
  670.                             END IF
  671.                         END IF
  672.                     END IF
  673.                     'B ux compare
  674.                 END IF
  675.                 'B uy compare
  676.             END IF
  677.             'B piece chosen yet
  678.  
  679.             'B handle keyboard input
  680.             k$ = INKEY$
  681.             IF k$ <> "" THEN
  682.                 IF LEN(k$) = 1 THEN
  683.                     IF ASC(k$) = 11 THEN
  684.                         in$ = screenInput(50 * FW, 4 * FH, "(Esc to quit) Enter Move > ")
  685.                         in$ = UCASE$(in$)
  686.                         spac = INSTR(in$, " ")
  687.                         IF spac THEN in$ = MID$(in$, 1, spac - 1) + "-" + MID$(in$, spac + 1)
  688.                         IF playBlack THEN in$ = w2b$(in$)
  689.                         getInput$ = in$
  690.                         EXIT FUNCTION
  691.                     ELSEIF ASC(k$) = 27 THEN
  692.                         END
  693.                     END IF
  694.                 END IF
  695.             END IF
  696.         END IF
  697.         'B if InGame
  698.         _DISPLAY
  699.     LOOP
  700.     lastLD$ = ""
  701.     getInput$ = in$
  702.  
  703. SUB highLightSq (bx, by, c&)
  704.     LINE ((bx + 2) * SQ, (by + 2) * SQ)-((bx + 3) * SQ, (by + 3) * SQ), , B
  705.     LINE ((bx + 2) * SQ + 1, (by + 2) * SQ + 1)-((bx + 3) * SQ - 1, (by + 3) * SQ - 1), c&, B
  706.     LINE ((bx + 2) * SQ + 2, (by + 2) * SQ + 2)-((bx + 3) * SQ - 2, (by + 3) * SQ - 2), c&, B
  707.  
  708. FUNCTION INCHECK (X)
  709.     DIM XX(27), YY(27), NDX
  710.     FOR b = 0 TO 7
  711.         FOR A = 0 TO 7
  712.  
  713.             IF BOARD(b, A) = 0 THEN GOTO 6
  714.             'T original code BOARD(b,A) >= 0  if white piece or void square skip test
  715.             'A: omit square skip test
  716.             'B Adrian next line is OK, it just skips empty spaces in board
  717.  
  718.             CALL MOVELIST(A, b, XX(), YY(), NDX)
  719.             FOR I = 0 TO NDX STEP 1
  720.                 X = XX(I)
  721.                 Y = YY(I)
  722.                 IF BOARD(Y, X) = 4500 AND Turn = 1 THEN
  723.                     'B ^^^ 2017-11-13 T has added and turn = 1 but turn = 1 is same as playBlack = 0
  724.                     AreaOutput "YOU ARE IN CHECK!", ""
  725.                     INCHECK = 1
  726.                     EXIT FUNCTION
  727.                 END IF
  728.                 IF BOARD(Y, X) = -9000 AND Turn = -1 THEN
  729.                     'B ^^^ 2017-11-13 T has added and turn = -1 but turn = -1 is same as playBlack = -1
  730.                     ' T in my last read of code posted playBack is used to note that Human plays as black
  731.                     ' T Turn is used for knowing if the move  has been made by black Turn = -1 or by White Turn = 1
  732.                     AreaOutput "I AM IN CHECK!", ""
  733.  
  734.                     'T this show Black status incheck
  735.                     INCHECK = -1 'A: this is probably no longer needed
  736.                     'T this should stop failed moves under check attack
  737.                     'EXIT FUNCTION
  738.                     'B exit now and get infinite loop?
  739.                     ' T AI force must exit from loop
  740.                 END IF
  741.             NEXT
  742.        6 NEXT
  743.     NEXT
  744.     INCHECK = 0
  745.  
  746. SUB initBoard
  747.     IF playBlack THEN
  748.         b$ = "rnbkqbnrppppppppzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzPPPPPPPPRNBKQBNR"
  749.     ELSE
  750.         b$ = "rnbqkbnrppppppppzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzPPPPPPPPRNBQKBNR"
  751.     END IF
  752.     bSetup b$
  753.  
  754. SUB Intro
  755.     'T better have a subroutine that we can use as many as we want
  756.     COLOR WHITE&, BLACK&
  757.     cP 3, "QB64 CHESS"
  758.     lp 5, 8, "CHESS is a game played between two players on a board of 64 squares."
  759.     lp 6, 4, "Chess was first invented in its current form in Europe during the late"
  760.     lp 7, 4, "fifteenth century. It evolved from much earlier forms invented in India"
  761.     lp 8, 4, "and Persia."
  762.     lp 9, 8, "The pieces are divided into Black and White.  Each player has 16 pieces:"
  763.     lp 10, 4, "1 king, 1 queen, 2 rooks, 2 bishops, 2 knights, and 8 pawns.  White makes"
  764.     lp 11, 4, "the first move.  The players alternate moving one piece at a time.  Pieces"
  765.     lp 12, 4, "are moved to an unoccupied square, or moved onto a square occupied by an"
  766.     lp 13, 4, "opponent's piece, capturing it.  When the king is under attack, he is in"
  767.     lp 14, 4, "CHECK.  The player cannot put his king in check.  The object is to CHECKMATE"
  768.     lp 15, 4, "the opponent.  This occurs when the king is in check and there is no way to"
  769.     lp 16, 4, "remove the king from attack."
  770.     lp 17, 8, "To move the pieces on the chessboard, click by mouse or type after Ctrl+K"
  771.     lp 18, 4, "notation, e.g. E2-E4 (not in English notation like P-K4).  To castle, type O-O"
  772.     lp 19, 4, "to castle kingside or O-O-O to castle queenside like in English notation."
  773.     lp 20, 4, "To exit the game, type QUIT or press ESCAPE key."
  774.     cP 25, "Click or press any key to continue."
  775.  
  776. SUB IO (A, B, X, Y, RESULT)
  777.     DIM XX(0 TO 26), YY(0 TO 26)
  778.     IF InGame THEN
  779.         'B ugly fix to get a missing line recorded in move list when load file and human playing black
  780.         IF loadFlag AND blackMove$ <> "" THEN
  781.             loadFlag = 0
  782.             countMove = countMove + 1
  783.             Move$(countMove) = blackMove$ + pBflag$ + "  " + whiteMove$ + pWflag$
  784.             'B this above is so ugly I even have to reverse black and white to get it right!
  785.             Boards$(countMove) = bString$
  786.             'B this above was omitted in versions before 11-16, still not right???
  787.         END IF
  788.  
  789.         IF A >= 0 THEN
  790.             Turn = -1
  791.             IF RESULT < -2500 THEN EXIT SUB 'AI should resign
  792.             PIECE = BOARD(Y, X)
  793.             CALL MAKEMOVE(A, B, X, Y)
  794.             'T (chess2_17-11-13 T) this will fix illegal moves of AI under check
  795.             NULL = INCHECK(0)
  796.             'T (chess2_17-11-13 T) we must search for check after choosing a move
  797.  
  798.             'B Adrian, can't have game end here, many moves are checked can't quit if one is bad
  799.             'IF NULL = -1 AND RESULT < -2500 THEN
  800.             '    AreaOutput "AI resigns!", ""
  801.             '    EXIT SUB
  802.             'END IF
  803.  
  804.             IF NULL THEN
  805.                 'T (chess2_17-11-13 T) if there is a check for AI we must restore situation before move
  806.                 BOARD(B, A) = BOARD(Y, X)
  807.                 BOARD(Y, X) = PIECE
  808.                 EXIT SUB
  809.                 'T (chess2_17-11-13 T) if it is check move is illegal
  810.             END IF
  811.             'T this show Black status incheck
  812.  
  813.             mymove$ = CHR$(65 + A) + RIGHT$(STR$(8 - B), 1) + "-" + CHR$(65 + X) + RIGHT$(STR$(8 - Y), 1)
  814.  
  815.             'B ??? next line not used
  816.             'AICHECK = 0 'reset AI check flag
  817.  
  818.             IF playBlack THEN mymove$ = w2b$(mymove$)
  819.             AreaOutput "MY MOVE: " + mymove$, ""
  820.             blackMove$ = mymove$
  821.             IF whiteMove$ <> "" THEN
  822.                 IF playBlack THEN whiteMove$ = w2b$(whiteMove$)
  823.             END IF
  824.             WriteEntry
  825.         END IF
  826.         'B & T >>> it saves the last moves to file and to list I move this IF HERE TO GET THE COUPLE WHITE+BLACK
  827.  
  828.         IF PIECE <> 0 THEN
  829.             s$ = "I TOOK YOUR "
  830.             IF PIECE = 100 THEN s$ = s$ + "PAWN           "
  831.             IF PIECE = 270 THEN s$ = s$ + "KNIGHT         "
  832.             IF PIECE = 300 THEN s$ = s$ + "BISHOP         "
  833.             IF PIECE = 500 THEN s$ = s$ + "ROOK           "
  834.             IF PIECE = 900 THEN s$ = s$ + "QUEEN          "
  835.             IF PIECE = 4500 THEN s$ = s$ + "KING          "
  836.             AreaOutput "", s$
  837.         END IF
  838.  
  839.     END IF
  840.  
  841.     DO
  842.         'B I think this was help from Adrian, so we didn't have to fake a move
  843.         IF playBlack = -1 AND countMove = 0 THEN countMove = 1: EXIT SUB
  844.  
  845.         'B Here we get Human's move but might be illegal so AI has to check before shown
  846.         in$ = getInput$
  847.         'T getinput$ takes user's input also for BUTTONBAR
  848.         'B which is why we have to have to check InGame
  849.  
  850.         IF UCASE$(in$) = "QUIT" THEN END
  851.  
  852.         IF InGame = -1 THEN
  853.             whiteMove$ = in$
  854.             'B ^^^ Human's move who now plays Black or White, don't be fooled by variable name>
  855.             'B Originally human always played white>
  856.             Turn = 1
  857.             IF UCASE$(in$) = "O-O" OR in$ = "0-0" THEN
  858.                 'T short castle rules... here we improve control of check and moves
  859.                 IF wcKsflag <> 0 THEN GOTO 16
  860.                 ' T it skips white castle king
  861.                 IF playBlack THEN
  862.                     IF BOARD(7, 0) <> 500 THEN GOTO 16
  863.                     IF BOARD(7, 1) <> 0 OR BOARD(7, 2) <> 0 THEN GOTO 16
  864.                 ELSE
  865.                     IF BOARD(7, 7) <> 500 THEN GOTO 16
  866.                     IF BOARD(7, 6) <> 0 OR BOARD(7, 5) <> 0 THEN GOTO 16
  867.                 END IF
  868.                 'T now we test if there is a check along the path of king
  869.                 NULL = Castleincheck(0)
  870.                 IF NULL = 0 THEN
  871.                     'B you can castle king side
  872.                     IF playBlack THEN
  873.                         BOARD(7, 1) = 4500
  874.                         BOARD(7, 3) = 0
  875.                         BOARD(7, 2) = 500
  876.                         BOARD(7, 0) = 0
  877.                         wcKsflag = -1
  878.                         'T black castle king side
  879.                         whiteMove$ = "O-O"
  880.                         EXIT SUB
  881.                     ELSE
  882.                         BOARD(7, 6) = 4500
  883.                         BOARD(7, 4) = 0
  884.                         BOARD(7, 5) = 500
  885.                         BOARD(7, 7) = 0
  886.                         wcKsflag = -1
  887.                         'T white castle king side
  888.                         whiteMove$ = "O-O"
  889.                         EXIT SUB
  890.                     END IF
  891.                 END IF
  892.             END IF
  893.             IF UCASE$(in$) = "O-O-O" OR in$ = "0-0-0" THEN
  894.                 'T long castle rules... here we improve control of check and moves
  895.                 IF wcQsflag <> 0 THEN GOTO 16
  896.                 IF playBlack THEN
  897.                     IF BOARD(7, 7) <> 500 THEN GOTO 16
  898.                     IF BOARD(7, 6) <> 0 OR BOARD(7, 5) <> 0 OR BOARD(7, 4) <> 0 THEN GOTO 16
  899.                 ELSE
  900.                     IF BOARD(7, 0) <> 500 THEN GOTO 16
  901.                     IF BOARD(7, 1) <> 0 OR BOARD(7, 2) <> 0 OR BOARD(7, 3) <> 0 THEN GOTO 16
  902.                 END IF
  903.                 'T now we test if there is a check along the path of king
  904.                 NULL = CastleincheckL(0)
  905.                 IF NULL = 0 THEN
  906.                     'B you can castle queen side
  907.                     IF playBlack THEN
  908.                         BOARD(7, 5) = 4500
  909.                         BOARD(7, 3) = 0
  910.                         BOARD(7, 4) = 500
  911.                         BOARD(7, 7) = 0
  912.                         wcQsflag = -1
  913.                         'T black castle queen side
  914.                         whiteMove$ = "O-O-O"
  915.                         EXIT SUB
  916.                     ELSE
  917.                         'T you can castle if there are no check to the king to the start or during the movement of castle
  918.                         BOARD(7, 2) = 4500
  919.                         BOARD(7, 4) = 0
  920.                         BOARD(7, 3) = 500
  921.                         BOARD(7, 0) = 0
  922.                         wcQsflag = -1
  923.                         'T white castle queen side
  924.                         whiteMove$ = "O-O-O"
  925.                         EXIT SUB
  926.                     END IF
  927.                 END IF
  928.             END IF
  929.             IF LEN(in$) < 5 THEN GOTO 16
  930.             B = 8 - (ASC(MID$(in$, 2, 1)) - 48)
  931.             A = ASC(UCASE$(MID$(in$, 1, 1))) - 65
  932.             X = ASC(UCASE$(MID$(in$, 4, 1))) - 65
  933.             Y = 8 - (ASC(MID$(in$, 5, 1)) - 48)
  934.             IF B > 7 OR B < 0 OR A > 7 OR A < 0 OR X > 7 OR X < 0 OR Y > 7 OR Y < 0 THEN GOTO 16
  935.             IF BOARD(B, A) <= 0 THEN GOTO 16
  936.             IF Y = 2 AND B = 3 AND (X = A - 1 OR X = A + 1) THEN
  937.                 IF BOARD(B, A) = 100 AND BOARD(Y, X) = 0 AND BOARD(Y + 1, X) = -100 THEN
  938.                     IF BESTB(1) = 1 AND BESTA(1) = X THEN
  939.                         MOVER = BOARD(B, A)
  940.                         TARGET = BOARD(Y, X)
  941.                         CALL MAKEMOVE(A, B, X, Y)
  942.                         BOARD(Y + 1, X) = 0
  943.                         ENPASSANT = -1
  944.                         GOTO 15
  945.                     END IF
  946.                 END IF
  947.             END IF
  948.             CALL MOVELIST(A, B, XX(), YY(), NDX)
  949.             FOR K = 0 TO NDX STEP 1
  950.                 IF X = XX(K) AND Y = YY(K) THEN
  951.                     MOVER = BOARD(B, A)
  952.                     TARGET = BOARD(Y, X)
  953.  
  954.                     INTFLAG = -1
  955.                     'B so this is where INTFLAG is set
  956.  
  957.                     CALL MAKEMOVE(A, B, X, Y)
  958.                     IF MOVER = 4500 THEN
  959.                         wcQsold = wcQsflag
  960.                         wcKsold = wcKsflag
  961.                         wcKsflag = -1
  962.                         wcQsflag = -1
  963.                     END IF
  964.                     IF (A = 0) AND (B = 7) AND (MOVER = 500) THEN
  965.                         wcQsold = wcQsflag
  966.                         wcQsflag = -1
  967.                     END IF
  968.                     IF (A = 7) AND (B = 7) AND (MOVER = 500) THEN
  969.                         wcKsold = wcKsflag
  970.                         wcKsflag = -1
  971.                     END IF
  972.  
  973.                     INTFLAG = 0
  974.                     'B and this is where INTFLAG is unset!
  975.  
  976.                     15 IF INCHECK(0) = 0 THEN EXIT SUB
  977.  
  978.                     BOARD(B, A) = MOVER
  979.                     BOARD(Y, X) = TARGET
  980.                     IF ENPASSANT THEN BOARD(Y + 1, X) = -100: ENPASSANT = 0
  981.                     IF (A = 0) AND (B = 7) AND (MOVER = 500) THEN wcQsflag = wcQsold
  982.                     IF (A = 7) AND (B = 7) AND (MOVER = 500) THEN wcKsflag = wcKsold
  983.                     IF MOVER = 4500 THEN wcQsflag = wcQsold
  984.                     GOTO 16
  985.                 END IF
  986.             NEXT
  987.         END IF
  988.        16
  989.  
  990.     LOOP
  991.     'B OK so this keeps looping until white makes legal move?
  992.  
  993.  
  994. FUNCTION isWhite (x, y)
  995.     'B for squares and old for chess font
  996.     yes = 0
  997.     IF y MOD 2 = 0 THEN
  998.         IF x MOD 2 = 0 THEN
  999.             yes = -1
  1000.         END IF
  1001.     ELSE
  1002.         IF x MOD 2 = 1 THEN
  1003.             yes = -1
  1004.         END IF
  1005.     END IF
  1006.     isWhite = yes
  1007.  
  1008. SUB KING (A, B, XX(), YY(), NDX)
  1009.     ID = SGN(BOARD(B, A))
  1010.     FOR DY = -1 TO 1
  1011.         IF B + DY < 0 OR B + DY > 7 THEN GOTO 12
  1012.         FOR DX = -1 TO 1
  1013.             IF A + DX < 0 OR A + DX > 7 THEN GOTO 11
  1014.             IF ID <> SGN(BOARD(B + DY, A + DX)) THEN
  1015.                 NDX = NDX + 1
  1016.                 XX(NDX) = A + DX
  1017.                 YY(NDX) = B + DY
  1018.             END IF
  1019.        11 NEXT
  1020.    12 NEXT
  1021.  
  1022. SUB KNIGHT (A, B, XX(), YY(), NDX)
  1023.     ID = SGN(BOARD(B, A))
  1024.     X = A - 1
  1025.     Y = B - 2
  1026.     GOSUB 5
  1027.     X = A - 2
  1028.     Y = B - 1
  1029.     GOSUB 5
  1030.     X = A + 1
  1031.     Y = B - 2
  1032.     GOSUB 5
  1033.     X = A + 2
  1034.     Y = B - 1
  1035.     GOSUB 5
  1036.     X = A - 1
  1037.     Y = B + 2
  1038.     GOSUB 5
  1039.     X = A - 2
  1040.     Y = B + 1
  1041.     GOSUB 5
  1042.     X = A + 1
  1043.     Y = B + 2
  1044.     GOSUB 5
  1045.     X = A + 2
  1046.     Y = B + 1
  1047.     GOSUB 5
  1048.     EXIT SUB
  1049.    5 REM
  1050.     IF X < 0 OR X > 7 OR Y < 0 OR Y > 7 THEN RETURN
  1051.     IF ID <> SGN(BOARD(Y, X)) THEN NDX = NDX + 1: XX(NDX) = X: YY(NDX) = Y
  1052.     RETURN
  1053.  
  1054. SUB ld2xy (ld$, dx, dy)
  1055.     'B dx and dy are going to be changed to find
  1056.     'B position (and thus type) of piece on the board from ld$
  1057.     letter$ = UCASE$(LEFT$(ld$, 1))
  1058.     dx = ASC(letter$) - 65
  1059.     digit = VAL(RIGHT$(ld$, 1))
  1060.     dy = 8 - digit
  1061.  
  1062. SUB LegalHide (x, y)
  1063.     DIM XX(0 TO 26), YY(0 TO 26)
  1064.     CALL MOVELIST(x, y, XX(), YY(), NDX)
  1065.     FOR a = 0 TO NDX STEP 1
  1066.         IF XX(a) >= 0 AND YY(a) >= 0 THEN SHOWMAN YY(a), XX(a)
  1067.     NEXT
  1068.  
  1069. 'T THIS SUB calculates legal position of piece in the board cell x,y
  1070. SUB LegalShow (x, y)
  1071.     DIM XX(0 TO 26), YY(0 TO 26)
  1072.     CALL MOVELIST(x, y, XX(), YY(), NDX)
  1073.     FOR a = 0 TO NDX STEP 1
  1074.         IF XX(a) >= 0 AND YY(a) >= 0 THEN highLightSq XX(a), YY(a), LITE2&
  1075.     NEXT
  1076.  
  1077. 'B graphics version of Locate col, row : Print txt$
  1078. SUB lp (row, col, txt$)
  1079.     _PRINTSTRING (col * FW, row * FH), txt$
  1080.  
  1081. SUB MakeButton (x1, y1, x2, y2, txt$, Col&)
  1082.     LINE (x1, y1)-(x2, y2), Col&, BF
  1083.     LINE (x1, y1)-(x2, y2), WHITE&, B
  1084.     LINE (x1 + 4, y2 - 4)-(x2 - 4, y2 - 4), _RGB32(222, 238, 227), B
  1085.     LINE (x2 - 4, y2 - 4)-(x2 - 4, y1 + 4), _RGB32(222, 238, 227), B
  1086.     'B VVV let's print button labels in middle of button
  1087.     _PRINTSTRING (x1 + 15, y2 - 1.35 * FH), txt$
  1088.  
  1089. SUB MAKEMOVE (A, B, X, Y)
  1090.     'B makemove is called many times, the last decides whether pBflag$ gets set or NOT
  1091.     'B the pWflag$ should only be set by user, no automatic setting allowed by AI.
  1092.     pBflag$ = ""
  1093.     BOARD(Y, X) = BOARD(B, A)
  1094.     BOARD(B, A) = 0
  1095.     IF Y = 0 AND BOARD(Y, X) = 100 THEN
  1096.         ' T it is the row 8
  1097.         IF INTFLAG THEN
  1098.             DO
  1099.                 AreaOutput "Promote to:", ""
  1100.                 I$ = Ppromote$
  1101.                 SELECT CASE UCASE$(I$)
  1102.                     CASE "KNIGHT", "N", "KT", "KT.", "N."
  1103.                         PROMOTE = 270: pWflag$ = "N"
  1104.                     CASE "BISHOP", "B", "B."
  1105.                         PROMOTE = 300: pWflag$ = "B"
  1106.                     CASE "ROOK", "R", "R."
  1107.                         PROMOTE = 500: pWflag$ = "R"
  1108.                     CASE "QUEEN", "Q", "Q."
  1109.                         PROMOTE = 900: pWflag$ = "Q"
  1110.                 END SELECT
  1111.             LOOP UNTIL PROMOTE <> 0
  1112.             IF playBlack THEN pWflag$ = LCASE$(pWflag$)
  1113.             'B       only the human can set the pWflag$
  1114.  
  1115.             BOARD(Y, X) = PROMOTE
  1116.             CLS
  1117.             SHOWBD
  1118.             _DISPLAY
  1119.         ELSE
  1120.             BOARD(Y, X) = 900
  1121.             'B ^^^^ OK AI need the line for checking FUTURE!!! moves
  1122.         END IF
  1123.     END IF
  1124.  
  1125.     IF Y = 7 AND BOARD(Y, X) = -100 THEN
  1126.         rap = -1
  1127.         BOARD(Y, X) = -900
  1128.         IF playBlack THEN pBflag$ = "Q" ELSE pBflag$ = "q"
  1129.     END IF
  1130.  
  1131.  
  1132. SUB MOVELIST (A, B, XX(), YY(), NDX)
  1133.     PIECE = INT(ABS(BOARD(B, A)))
  1134.     NDX = -1
  1135.     SELECT CASE PIECE
  1136.         CASE IS = 100
  1137.             CALL PAWN(A, B, XX(), YY(), NDX)
  1138.         CASE IS = 270
  1139.             CALL KNIGHT(A, B, XX(), YY(), NDX)
  1140.         CASE IS = 300
  1141.             CALL BISHOP(A, B, XX(), YY(), NDX)
  1142.         CASE IS = 500
  1143.             CALL ROOK(A, B, XX(), YY(), NDX)
  1144.         CASE IS = 900
  1145.             CALL QUEEN(A, B, XX(), YY(), NDX)
  1146.         CASE IS = 4500
  1147.             CALL KING(A, B, XX(), YY(), NDX)
  1148.         CASE IS = 9000
  1149.             CALL KING(A, B, XX(), YY(), NDX)
  1150.     END SELECT
  1151.  
  1152. SUB PAWN (A, B, XX(), YY(), NDX)
  1153.     ID = SGN(BOARD(B, A))
  1154.     ' T ID 1 for white piece and -1 for black piece
  1155.     IF (A - 1) >= 0 AND (A - 1) <= 7 AND (B - ID) >= 0 AND (B - ID) <= 7 THEN
  1156.         IF SGN(BOARD((B - ID), (A - 1))) = -ID THEN
  1157.             NDX = NDX + 1
  1158.             XX(NDX) = A - 1
  1159.             YY(NDX) = B - ID
  1160.         END IF
  1161.     END IF
  1162.     IF (A + 1) >= 0 AND (A + 1) <= 7 AND (B - ID) >= 0 AND (B - ID) <= 7 THEN
  1163.         IF SGN(BOARD((B - ID), (A + 1))) = -ID THEN
  1164.             NDX = NDX + 1
  1165.             XX(NDX) = A + 1
  1166.             YY(NDX) = B - ID
  1167.         END IF
  1168.     END IF
  1169.     IF A >= 0 AND A <= 7 AND (B - ID) >= 0 AND (B - ID) <= 7 THEN
  1170.         IF BOARD((B - ID), A) = 0 THEN
  1171.             NDX = NDX + 1
  1172.             XX(NDX) = A
  1173.             YY(NDX) = B - ID
  1174.             IF (ID < 0 AND B = 1) OR (ID > 0 AND B = 6) THEN
  1175.                 IF BOARD((B - ID - ID), A) = 0 THEN
  1176.                     NDX = NDX + 1
  1177.                     XX(NDX) = A
  1178.                     YY(NDX) = B - ID - ID
  1179.                 END IF
  1180.             END IF
  1181.         END IF
  1182.     END IF
  1183.  
  1184.  
  1185. 'B a pawn needs promotion to a piece, which? use mouse or keyboard
  1186. FUNCTION Ppromote$
  1187.     inp$ = "": ky = 0: oldtext$ = prompt$ + " {" + inp$ + "}"
  1188.     newText$ = oldtext$
  1189.     DO WHILE ky <> 13
  1190.         i = _MOUSEINPUT
  1191.         ty = (_MOUSEY + 24) / SQ
  1192.         ' T we must control also X dimension not only Y dimension for mouse in Area Promotion
  1193.         IF _MOUSEBUTTON(1) = -1 AND (_MOUSEX >= 500 AND _MOUSEX <= 700) THEN
  1194.             IF ty > 1 THEN
  1195.                 IF ty = 2 THEN inp$ = "Q": EXIT DO
  1196.                 IF ty = 3 THEN inp$ = "R": EXIT DO
  1197.                 IF ty = 4 THEN inp$ = "B": EXIT DO
  1198.                 IF ty = 5 THEN inp$ = "N": EXIT DO
  1199.             ELSE
  1200.                 inp$ = ""
  1201.                 'T no good click
  1202.             END IF
  1203.         END IF
  1204.         AreaOutput "Promote Enter Q R B N", newText$
  1205.         _DISPLAY
  1206.         oldtext$ = newText$
  1207.         k$ = INKEY$
  1208.         IF LEN(k$) THEN
  1209.             ky = ASC(RIGHT$(k$, 1))
  1210.             IF 31 < ky AND ky < 127 THEN
  1211.                 inp$ = inp$ + CHR$(ky)
  1212.             ELSEIF ky = 8 THEN
  1213.                 IF LEN(inp$) THEN inp$ = LEFT$(inp$, LEN(inp$) - 1)
  1214.             END IF
  1215.             newText$ = prompt$ + " {" + inp$ + "}"
  1216.         END IF
  1217.     LOOP
  1218.     Ppromote$ = inp$
  1219.     'B don't worry about case, it gets checked later
  1220.  
  1221. SUB QUEEN (A, B, XX(), YY(), NDX)
  1222.     CALL BISHOP(A, B, XX(), YY(), NDX)
  1223.     CALL ROOK(A, B, XX(), YY(), NDX)
  1224.  
  1225. SUB restart
  1226.     'B restart variables
  1227.     CLS
  1228.     ERASE BOARD
  1229.     REDIM Move$(1 TO 300)
  1230.     REDIM Boards$(1 TO 300)
  1231.     'B need to start array at 1 not 0
  1232.     result = -2500
  1233.     wcKsflag = 0: wcQsflag = 0: wcKsold = 0: wcQsold = 0
  1234.     LEVEL = 0: INTFLAG = 0: countMove = 0
  1235.     whiteMove$ = "": blackMove$ = "": bmoves$ = "": bFirst = -1
  1236.  
  1237. SUB ROOK (A, B, XX(), YY(), NDX)
  1238.     ID = SGN(BOARD(B, A))
  1239.     FOR X = A - 1 TO 0 STEP -1
  1240.         IF ID <> SGN(BOARD(B, X)) THEN
  1241.             NDX = NDX + 1
  1242.             XX(NDX) = X
  1243.             YY(NDX) = B
  1244.         END IF
  1245.         IF (BOARD(B, X)) <> 0 THEN EXIT FOR
  1246.     NEXT
  1247.     FOR X = A + 1 TO 7 STEP 1
  1248.         IF ID <> SGN(BOARD(B, X)) THEN
  1249.             NDX = NDX + 1
  1250.             XX(NDX) = X
  1251.             YY(NDX) = B
  1252.         END IF
  1253.         IF (BOARD(B, X)) <> 0 THEN EXIT FOR
  1254.     NEXT
  1255.     FOR Y = B - 1 TO 0 STEP -1
  1256.         IF ID <> SGN(BOARD(Y, A)) THEN
  1257.             NDX = NDX + 1
  1258.             XX(NDX) = A
  1259.             YY(NDX) = Y
  1260.         END IF
  1261.         IF (BOARD(Y, A)) <> 0 THEN EXIT FOR
  1262.     NEXT
  1263.     FOR Y = B + 1 TO 7 STEP 1
  1264.         IF ID <> SGN(BOARD(Y, A)) THEN
  1265.             NDX = NDX + 1
  1266.             XX(NDX) = A
  1267.             YY(NDX) = Y
  1268.         END IF
  1269.         IF (BOARD(Y, A)) <> 0 THEN EXIT FOR
  1270.     NEXT
  1271.  
  1272. 'B This is INPUT for graphic screens
  1273. FUNCTION screenInput$ (pixelX, pixelY, prompt$)
  1274.     inp$ = ""
  1275.     ky = 0: oldtext$ = prompt$ + " {" + inp$ + "}"
  1276.     newText$ = oldtext$
  1277.     COLOR LITE&
  1278.     WHILE ky <> 13
  1279.         AreaOutput newText$, ""
  1280.         _DISPLAY
  1281.         oldtext$ = newText$
  1282.         k$ = INKEY$
  1283.         IF LEN(k$) THEN
  1284.             ky = ASC(RIGHT$(k$, 1))
  1285.             IF 31 < ky AND ky < 127 THEN
  1286.                 inp$ = inp$ + CHR$(ky)
  1287.             ELSEIF ky = 8 THEN
  1288.                 IF LEN(inp$) THEN inp$ = LEFT$(inp$, LEN(inp$) - 1)
  1289.             END IF
  1290.             newText$ = prompt$ + " {" + inp$ + "}    "
  1291.         END IF
  1292.     WEND
  1293.     COLOR WHITE&
  1294.     screenInput$ = inp$
  1295.  
  1296. 'B show entire board captured pieces also used for pawn promotion, Move List, Buttons, Debug Info
  1297. SUB SHOWBD
  1298.     COLOR WHITE&, 0
  1299.     _FONT bArial&
  1300.     'B print board labels for files
  1301.     LOCATE 2, 3:
  1302.     IF playBlack = -1 THEN PRINT "HGFEDCBA" ELSE PRINT "ABCDEFGH";
  1303.     'LOCATE 11, 3:                                                          ' A: display 1 set of labels only
  1304.     'IF playBlack = -1 THEN PRINT "HGFEDCBA" ELSE PRINT "ABCDEFGH";
  1305.     'B print board labels for ranks
  1306.     FOR i = 8 TO 1 STEP -1
  1307.         BLR$ = RIGHT$(STR$(i), 1)
  1308.         IF playBlack THEN BLR$ = w2b$(BLR$)
  1309.         LOCATE 8 - i + 3, 2: PRINT BLR$;
  1310.         '    LOCATE 8 - i + 3, 11: PRINT BLR$;
  1311.     NEXT
  1312.     'B Count captures by start of standard set on board and deduct each piece on board
  1313.     DIM c(-6 TO 6)
  1314.     c(-6) = 1: c(-5) = 2: c(-4) = 2: c(-3) = 2: c(-2) = 8: c(-1) = 1
  1315.     c(6) = 1: c(5) = 2: c(4) = 2: c(3) = 2: c(2) = 8: c(1) = 1
  1316.     FOR x = 0 TO 7
  1317.         FOR y = 0 TO 7
  1318.             SHOWMAN x, y
  1319.             _FONT bArial&
  1320.             SELECT CASE BOARD(x, y)
  1321.                 CASE -900: IF c(-6) THEN c(-6) = c(-6) - 1
  1322.                 CASE -500: IF c(-5) THEN c(-5) = c(-5) - 1
  1323.                 CASE -300: IF c(-4) THEN c(-4) = c(-4) - 1
  1324.                 CASE -270: IF c(-3) THEN c(-3) = c(-3) - 1
  1325.                 CASE -100: IF c(-2) THEN c(-2) = c(-2) - 1
  1326.                 CASE -9000: IF c(-1) THEN c(-1) = c(-1) - 1
  1327.                 CASE 4500: IF c(1) THEN c(1) = c(1) - 1
  1328.                 CASE 100: IF c(2) THEN c(2) = c(2) - 1
  1329.                 CASE 270: IF c(3) THEN c(3) = c(3) - 1
  1330.                 CASE 300: IF c(4) THEN c(4) = c(4) - 1
  1331.                 CASE 500: IF c(5) THEN c(5) = c(5) - 1
  1332.                 CASE 900: IF c(6) THEN c(6) = c(6) - 1
  1333.             END SELECT
  1334.         NEXT
  1335.     NEXT
  1336.     'B below need to blackout captures in case UNDO undoes one
  1337.     LINE (12 * SQ, 0)-(700, 9 * SQ), BLACK&, BF
  1338.     'Draw Capture pieces section
  1339.     FOR b = 0 TO 4
  1340.         FOR a = 1 TO 2
  1341.             IF isWhite(a, b) THEN COLOR WHITES& ELSE COLOR BLACKS&
  1342.             LINE (((a * 2) + 10) * SQ, (b + 1) * SQ)-STEP(SQ, SQ), , BF
  1343.             PRESET (((a * 2) + 10) * SQ + 8, (b + 1) * SQ + 36) 'A: centralise pieces
  1344.             IF a = 2 THEN DRAW "C" + STR$(BLACK&) ELSE DRAW "C" + STR$(WHITE&)
  1345.             SELECT CASE b
  1346.                 'A  draw outlines for captured area
  1347.                 CASE 0: DRAW "R26U5H2L6E9U11G4H6G4H4G6H4D11F9L6G2D5"
  1348.                 CASE 1: DRAW "R26U5H2L5U7E3R4U10L6D3L4U3L6D3L4U3L6D10R4F3D7L5G2D5"
  1349.                 CASE 2: DRAW "R26U5H2L8E6U9H2G8H2E8H2L6G6D9F6L8G2D5"
  1350.                 CASE 3: DRAW "R26U5H2U4E2U9H6L9G10D4F2R4E3R4G8L4G2D5"
  1351.                 CASE 4: DRAW "R26U5H2L6U7E3U6H3L10G3D6F3D7L6G2D5"
  1352.                 CASE 5: DRAW "R26U5H2L5E7U6H4L5G3U5R2U2L2U2L2D2L2D2R2D5H3L5G4D6F7L5G2D5"
  1353.             END SELECT
  1354.             DRAW "BE2"
  1355.             'A  MOVE PEN INSIDE
  1356.             IF a = 2 THEN DRAW "P" + STR$(BLACK&) + "," + STR$(BLACK&)
  1357.             IF a = 1 THEN DRAW "P" + STR$(WHITE&) + "," + STR$(WHITE&)
  1358.             COLOR WHITE&, BLACK&
  1359.             IF a = 1 THEN cindex = 6 - b ELSE cindex = -1 * (6 - b)
  1360.             IF playBlack THEN cindex = cindex * -1
  1361.             digit$ = RIGHT$(STR$(c(cindex)), 1)
  1362.             IF digit$ <> "0" THEN LOCATE b + 2, (a * 2) + 12: PRINT digit$;
  1363.         NEXT
  1364.     NEXT
  1365.     COLOR WHITE&, BLACK&
  1366.     _FONT normal&
  1367.     showButtonBar
  1368.     showMoveList
  1369.     'B Some debug stuff also needed for UNDO  Save file
  1370.     LINE (0, 25 * FH)-(46 * FW, YMAX), BLACK&, BF
  1371.     lp 25, 2, "Last move by AI: " + blackMove$
  1372.     lp 26, 2, "Move Count:" + STR$(countMove) + "   Turn:" + STR$(Turn) + "   Result:" + STR$(result)
  1373.     lp 27, 2, "Castle: K flag:" + STR$(wcKsflag) + "   Q flag:" + STR$(wcQsflag) + "   K old:" + STR$(wcKsold) + "   Q old:" + STR$(wcQsold)
  1374.     lp 28, 2, "Last move by Human: " + whiteMove$
  1375.  
  1376. SUB showButtonBar
  1377.     MakeButton 700, 60, 880, 100, "PLAY WHITE", LITE2&
  1378.     MakeButton 700, 120, 880, 160, "PLAY BLACK", LITE2&
  1379.     MakeButton 700, 180, 880, 220, "UNDO", LITE2&
  1380.     MakeButton 700, 240, 880, 280, "SAVE GAME", LITE2&
  1381.     MakeButton 700, 300, 880, 340, "LOAD GAME", LITE2&
  1382.     MakeButton 700, 360, 880, 400, "MANUAL SETUP", LITE2&
  1383.     MakeButton 700, 420, 880, 460, "QUIT", LITE2&
  1384.  
  1385. 'B set this up with Adrian's Draw Strings
  1386. SUB SHOWMAN (A, B)
  1387.     IF isWhite(B, A) THEN COLOR WHITES& ELSE COLOR BLACKS&
  1388.     LINE ((A + 2) * SQ, (B + 2) * SQ)-STEP(SQ, SQ), , BF
  1389.     ZZ = ABS(BOARD(B, A))
  1390.     IF ZZ THEN
  1391.         PRESET ((A + 2) * SQ + 8, (B + 2) * SQ + 36) 'A: centralise pieces
  1392.         IF BOARD(B, A) < 0 THEN
  1393.             IF playBlack THEN DRAW "C" + STR$(WHITE&) ELSE DRAW "C" + STR$(BLACK&)
  1394.         ELSE
  1395.             IF playBlack THEN DRAW "C" + STR$(BLACK&) ELSE DRAW "C" + STR$(WHITE&)
  1396.         END IF
  1397.         SELECT CASE ZZ
  1398.             'A  draw outlines for pieces on board
  1399.             CASE 100: DRAW "R26U5H2L6U7E3U6H3L10G3D6F3D7L6G2D5"
  1400.             CASE 500: DRAW "R26U5H2L5U7E3R4U10L6D3L4U3L6D3L4U3L6D10R4F3D7L5G2D5"
  1401.             CASE 270: DRAW "R26U5H2U4E2U9H6L9G10D4F2R4E3R4G8L4G2D5"
  1402.             CASE 300: DRAW "R26U5H2L8E6U9H2G8H2E8H2L6G6D9F6L8G2D5"
  1403.             CASE 900: DRAW "R26U5H2L6E9U11G4H6G4H4G6H4D11F9L6G2D5"
  1404.             CASE 4500: DRAW "R26U5H2L5E7U6H4L5G3U5R2U2L2U2L2D2L2D2R2D5H3L5G4D6F7L5G2D5"
  1405.             CASE 9000: DRAW "R26U5H2L5E7U6H4L5G3U5R2U2L2U2L2D2L2D2R2D5H3L5G4D6F7L5G2D5"
  1406.         END SELECT
  1407.         DRAW "BE2"
  1408.         'A  MOVE PEN INSIDE and color fill
  1409.         IF BOARD(B, A) < 0 THEN
  1410.             IF playBlack THEN DRAW "P" + STR$(WHITE&) + "," + STR$(WHITE&) ELSE DRAW "P" + STR$(BLACK&) + "," + STR$(BLACK&)
  1411.         END IF
  1412.         IF BOARD(B, A) > 0 THEN
  1413.             IF playBlack THEN DRAW "P" + STR$(BLACK&) + "," + STR$(BLACK&) ELSE DRAW "P" + STR$(WHITE&) + "," + STR$(WHITE&)
  1414.         END IF
  1415.     END IF
  1416.     COLOR WHITE&, BLACK&
  1417.     _FONT normal&
  1418.  
  1419. 'B  T set this up to show last 8 moves of White and Black
  1420. SUB showMoveList
  1421.     IF countMove < 9 THEN z = 8 ELSE z = countMove
  1422.     LINE (500, 300)-(680, 500), BLACK&, BF ' T if we use 700 it covers left border of buttonbar
  1423.     COLOR _RGB(0, 180, 220)
  1424.     FOR a = 0 TO 7
  1425.         lp 22 - a, 46, Move$(z - a)
  1426.     NEXT
  1427.     COLOR WHITE&
  1428.  
  1429. 'B convert BINGO for human playing Black
  1430. FUNCTION w2b$ (s$)
  1431.     b$ = ""
  1432.     FOR i = 1 TO LEN(s$)
  1433.         here = INSTR("ABCDEFGH12345678", MID$(s$, i, 1))
  1434.         IF here THEN b$ = b$ + MID$("HGFEDCBA87654321", here, 1) ELSE b$ = b$ + MID$(s$, i, 1)
  1435.     NEXT
  1436.     w2b$ = b$
  1437.  
  1438. SUB Wait_Click_Key
  1439.     'B handy sub to reuse in other programs
  1440.     DO
  1441.         k = _KEYHIT
  1442.         WHILE _MOUSEINPUT: WEND
  1443.         _LIMIT 30
  1444.     LOOP UNTIL k <> 0 OR _MOUSEBUTTON(1)
  1445.  
  1446. SUB WriteEntry
  1447.     'B  Record game in both Move$() and Boards$() at countMove
  1448.     IF playBlack THEN
  1449.         IF bFirst THEN
  1450.             bFirst = 0
  1451.             bmoves$ = blackMove$ + pBflag$
  1452.         ELSE
  1453.             r$ = bmoves$ + "   " + whiteMove$ + pWflag$
  1454.             countMove = countMove + 1
  1455.             Move$(countMove) = r$
  1456.             bmoves$ = blackMove$ + pBflag$
  1457.         END IF
  1458.     ELSE
  1459.         countMove = countMove + 1
  1460.         Move$(countMove) = whiteMove$ + pWflag$ + " " + blackMove$ + pBflag$
  1461.     END IF
  1462.     Boards$(countMove) = bString$
  1463.     'B clear flags for promoted pawns
  1464.     pWflag$ = "": pBflag$ = ""
  1465.  
Chess 2017-11-22 T.PNG
* Chess 2017-11-22 T.PNG (Filesize: 61.4 KB, Dimensions: 901x626, Views: 374)

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: Chess developed from QB64 Samples
« Reply #1 on: August 20, 2018, 03:39:38 am »
That's pretty cool. Nicely done! Of course I had to modify the 'font' locations, but other than that, I was still soundly beaten... lol

J
Logic is the beginning of wisdom.

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Chess developed from QB64 Samples
« Reply #2 on: August 22, 2018, 04:15:52 am »
Hi Guys
a screenshot for a revival game made with code posted by Bplus

.....
IMHO at the actual state of my learning about chessprogramming AI must be greater and
evaluate functions must be bigger as much as five times that is now, more fix little forbidden moves for black!


Good Coding
A REVIVAL GAME.png
* A REVIVAL GAME.png (Filesize: 124.96 KB, Dimensions: 1366x768, Views: 388)
Programming isn't difficult, only it's  consuming time and coffee

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Chess developed from QB64 Samples
« Reply #3 on: August 24, 2018, 07:23:53 pm »
Hi Bplus

I have found in my old notebook this mindmap about hystory and development of QB64chess.bas
Good Coding
* QB64CHESS.BAS.pdf (Filesize: 588.49 KB, Downloads: 278)
Programming isn't difficult, only it's  consuming time and coffee

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Chess developed from QB64 Samples
« Reply #4 on: August 24, 2018, 08:13:06 pm »
I haven't seen a mindmap in ages! Thanks Tempodibasic

Offline ExilePrisoner

  • Newbie
  • Posts: 6
    • View Profile
Re: Chess developed from QB64 Samples
« Reply #5 on: August 26, 2018, 09:34:31 am »
hello
I play this game as black and when i try to castle kingside the "last move by human" show  O-O but there is no castle position. I did not move the king befoe or try to castle when in illegal position. There is problem i think in game AI. Screen picture shows the actual board position.
chessProblem1.bmp
* chessProblem1.bmp (Filesize: 1.72 MB, Dimensions: 960x627, Views: 257)

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Chess developed from QB64 Samples
« Reply #6 on: August 26, 2018, 09:50:52 am »
Yes the AI was buggy from the get go, some moves fixed but human playing Black was a total hack!

We did not know enough about the AI to fix everything nice, so project was abandoned and we went off to find better Chess Engine or study and write an AI from scratch.

Sorry if I gave the impression this was a completed project.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Chess developed from QB64 Samples
« Reply #7 on: August 26, 2018, 02:03:17 pm »
Here is where the story of my Chess foray left off:
https://www.qb64.org/forum/index.php?topic=83.0

Don't know why v pulled all his dialog? It looked like a good recommendation.

FellippeHeitor

  • Guest
Re: Chess developed from QB64 Samples
« Reply #8 on: August 26, 2018, 02:10:33 pm »
Interestingly, it looks like v never deleted anything, especially because members don’t have that type of permission. If that had been before the edit restrictions, he’d have been able to delete the contents, but not the post. Also, deleting a first post would have deleted the whole thread.

Sounds like you started a new thread mentioning another post by v, could that be it?

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Chess developed from QB64 Samples
« Reply #9 on: August 26, 2018, 04:25:10 pm »
I don't know why I would start a post mentioning someone else post unless it was from net during a time net went down.

But I don't think V posts at net. Plus there is a missing conversation where someone, v?, suggested to try Chess engines at stockfish.

This was definitely before restrictions on modifications, way before! [banned user] had erased all his posts at one point between then and now.

Eh! so long ago... Is v around still?

FellippeHeitor

  • Guest
Re: Chess developed from QB64 Samples
« Reply #10 on: August 26, 2018, 04:28:50 pm »
Could be from network54; Vince did post there sometimes.

When [banned user] left the first time he didn’t erase the posts, but instead replaced their contents with “-“. The posts remained and were restored by Odin.

Doesn’t look like v to take something back anyway.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Chess developed from QB64 Samples
« Reply #11 on: August 26, 2018, 04:34:38 pm »
OK so where is his Chess program? I certainly was not at Network 54 in February.

Append: Hey maybe from Chat?

Very likely from chat (if not posted here) because it was in February and I was on it for a bit and explains the missing conversation.
« Last Edit: August 26, 2018, 04:49:10 pm by bplus »

FellippeHeitor

  • Guest

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Chess developed from QB64 Samples
« Reply #13 on: August 26, 2018, 05:03:16 pm »
Sort of why I stopped chatting, no records to go back and check.

Sorry, I was definitely wrong about v pulling out his part of conversation. I mis-remembered where the conversation took place.
« Last Edit: August 26, 2018, 05:19:57 pm by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Chess developed from QB64 Samples
« Reply #14 on: August 26, 2018, 06:03:42 pm »
Hi ExilePrisoner,

I had not noticed this was your first post.

Welcome to the forum!

Had you been a member at net? There was a conversation some time ago concerning a real QB64 chess program being written. I am thinking it was here... gone searching...

Append: ...no luck, must have been at net, it resulted in me reading a book on Jewish Mysticism, crazy turn of events!
« Last Edit: August 26, 2018, 06:08:56 pm by bplus »