Author Topic: Chess game project : King + Rook vs King endgame  (Read 1824 times)

0 Members and 1 Guest are viewing this topic.

Offline Adrian

  • Newbie
  • Posts: 39
Chess game project : King + Rook vs King endgame
« on: January 05, 2021, 01:21:30 pm »
Another year, another chess project :) This time, the challenge is to write or tweak a *simple* program so that the computer is smart enough to checkmate a lone king with king and rook. This is a trivial endgame that all human chess beginners quickly learn, but strangely where weak chess engines almost always fail. As a starting point, I'll be using a stripped down version of Dean Menezes' popular chess program chess.bas bundled together with QB64. At the moment, it relies on its original AI, which has absolutely no clue how to force the simple checkmate.

Code: QB64: [Select]
  1. DEFINT A-Z
  2. DECLARE SUB SQUARE (A, B, C)
  3. DECLARE SUB SHOWMAN (A, B, FLAG)
  4. DECLARE SUB SHOWBD ()
  5. DECLARE SUB IO (A, B, X, Y, RESULT)
  6. DECLARE FUNCTION INCHECK (X)
  7. DECLARE SUB MAKEMOVE (A, B, X, Y)
  8. DECLARE SUB KING (A, B, XX(), YY(), NDX)
  9. DECLARE SUB ROOK (A, B, XX(), YY(), NDX)
  10. DECLARE SUB MOVELIST (A, B, XX(), YY(), NDX)
  11. DECLARE FUNCTION EVALUATE (ID, PRUNE)
  12. DIM SHARED BOARD(0 TO 7, 0 TO 7)
  13. DIM SHARED BESTA(0 TO 7), BESTB(0 TO 7), BESTX(0 TO 7), BESTY(0 TO 7)
  14. DIM SHARED LEVEL, MAXLEVEL, SCORE
  15. DIM SHARED WCKSFLAG, WCQSFLAG, INTFLAG
  16. DIM SHARED WCKSOLD, WCQSOLD
  17. LEVEL = 0
  18. MAXLEVEL = 5
  19. DATA -500,0,0,0,0,0,0,-7500
  20. DATA 0,0,0,0,0,0,0,0
  21. DATA 0,0,0,0,0,0,0,0
  22. DATA 0,0,0,0,0,0,0,0
  23. DATA 0,0,0,5000,0,0,0,0
  24. DATA 0,0,0,0,0,0,0,0
  25. DATA 0,0,0,0,0,0,0,0
  26. DATA 0,0,0,0,0,0,0,0
  27. FOR X = 0 TO 7
  28.     FOR Y = 0 TO 7
  29.         READ Z
  30.         BOARD(X, Y) = Z
  31.     NEXT Y
  32. A = -1
  33. RESULT = 0
  34. PRINT "      SIMPLE CHESS ENDINGS : CHECKMATE WITH KING AND ROOK VS KING"
  35. PRINT "     In this game, you play White with only a King and I play Black "
  36. PRINT "     with King and Rook. I will try to checkmate you within 50 moves."
  37. PRINT "     To move the pieces on the chessboard, type in your move in "
  38. PRINT "     coordinate notation, e.g. E2E3 . To exit the game, type QUIT."
  39. PRINT "                   Press any key to continue."
  40. Z$ = INPUT$(1)
  41.     SCORE = 0
  42.     CALL IO(A, B, X, Y, RESULT)
  43.     CLS
  44.     CALL SHOWBD
  45.     RESULT = EVALUATE(-1, 10000)
  46.     A = BESTA(1)
  47.     B = BESTB(1)
  48.     X = BESTX(1)
  49.     Y = BESTY(1)
  50.  
  51.  
  52. FUNCTION EVALUATE (ID, PRUNE)
  53.     DIM XX(0 TO 26), YY(0 TO 26)
  54.     LEVEL = LEVEL + 1
  55.     BESTSCORE = 10000 * ID
  56.     FOR B = 7 TO 0 STEP -1
  57.         FOR A = 7 TO 0 STEP -1
  58.             IF SGN(BOARD(B, A)) <> ID THEN GOTO 1
  59.             CALL MOVELIST(A, B, XX(), YY(), NDX)
  60.             FOR I = 0 TO NDX
  61.                 X = XX(I)
  62.                 Y = YY(I)
  63.                 OLDSCORE = SCORE
  64.                 MOVER = BOARD(B, A)
  65.                 TARGET = BOARD(Y, X)
  66.                 CALL MAKEMOVE(A, B, X, Y)
  67.                 IF (LEVEL < MAXLEVEL) THEN SCORE = SCORE + EVALUATE(-ID, BESTSCORE - TARGET + ID * (8 - ABS(4 - X) - ABS(4 - Y)))
  68.                 SCORE = SCORE + TARGET - ID * (8 - ABS(4 - X) - ABS(4 - Y))
  69.                 IF (ID < 0 AND SCORE > BESTSCORE) OR (ID > 0 AND SCORE < BESTSCORE) THEN
  70.                     BESTA(LEVEL) = A
  71.                     BESTB(LEVEL) = B
  72.                     BESTX(LEVEL) = X
  73.                     BESTY(LEVEL) = Y
  74.                     BESTSCORE = SCORE
  75.                     IF (ID < 0 AND BESTSCORE >= PRUNE) OR (ID > 0 AND BESTSCORE <= PRUNE) THEN
  76.                         BOARD(B, A) = MOVER
  77.                         BOARD(Y, X) = TARGET
  78.                         SCORE = OLDSCORE
  79.                         LEVEL = LEVEL - 1
  80.                         EVALUATE = BESTSCORE
  81.                         EXIT FUNCTION
  82.                     END IF
  83.                 END IF
  84.                 BOARD(B, A) = MOVER
  85.                 BOARD(Y, X) = TARGET
  86.                 SCORE = OLDSCORE
  87.             NEXT
  88.        1 NEXT
  89.     NEXT
  90.     LEVEL = LEVEL - 1
  91.     EVALUATE = BESTSCORE
  92.  
  93. FUNCTION INCHECK (X)
  94.     DIM XX(27), YY(27), NDX
  95.     FOR B = 0 TO 7
  96.         FOR A = 0 TO 7
  97.             IF BOARD(B, A) >= 0 THEN GOTO 6
  98.             CALL MOVELIST(A, B, XX(), YY(), NDX)
  99.             FOR I = 0 TO NDX STEP 1
  100.                 X = XX(I)
  101.                 Y = YY(I)
  102.                 IF BOARD(Y, X) = 5000 THEN
  103.                     PRINT "YOU ARE IN CHECK!"
  104.                     PRINT " "
  105.                     PRINT " "
  106.                     INCHECK = 1
  107.                     EXIT FUNCTION
  108.                 END IF
  109.             NEXT
  110.        6 NEXT
  111.     NEXT
  112.     INCHECK = 0
  113.  
  114. SUB IO (A, B, X, Y, RESULT)
  115.     DIM XX(0 TO 26), YY(0 TO 26)
  116.     CLS
  117.     IF A >= 0 THEN
  118.         IF RESULT < -2500 THEN
  119.             PRINT "I RESIGN"
  120.             SLEEP
  121.             SYSTEM
  122.         END IF
  123.         PIECE = BOARD(Y, X)
  124.         CALL MAKEMOVE(A, B, X, Y)
  125.         IF PIECE <> 0 THEN
  126.             PRINT "I TOOK YOUR ";
  127.             IF PIECE = 5000 THEN PRINT "KING"
  128.         END IF
  129.         NULL = INCHECK(0)
  130.     END IF
  131.     DO
  132.         CALL SHOWBD
  133.         VIEW PRINT 24 TO 24
  134.         LOCATE , 33: INPUT "YOUR MOVE: ", IN$
  135.         IF UCASE$(IN$) = "QUIT" THEN CLS: END
  136.         IF LEN(IN$) < 4 THEN GOTO 16
  137.         B = 8 - (ASC(MID$(IN$, 2, 1)) - 48)
  138.         A = ASC(UCASE$(MID$(IN$, 1, 1))) - 65
  139.         X = ASC(UCASE$(MID$(IN$, 3, 1))) - 65
  140.         Y = 8 - (ASC(MID$(IN$, 4, 1)) - 48)
  141.         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
  142.         IF BOARD(B, A) <= 0 THEN GOTO 16
  143.         IF Y = 2 AND B = 3 AND (X = A - 1 OR X = A + 1) THEN
  144.             IF BOARD(B, A) = 100 AND BOARD(Y, X) = 0 AND BOARD(Y + 1, X) = -100 THEN
  145.                 IF BESTB(1) = 1 AND BESTA(1) = X THEN
  146.                     MOVER = BOARD(B, A)
  147.                     TARGET = BOARD(Y, X)
  148.                     CALL MAKEMOVE(A, B, X, Y)
  149.                     BOARD(Y + 1, X) = 0
  150.                     ENPASSANT = -1
  151.                     GOTO 15
  152.                 END IF
  153.             END IF
  154.         END IF
  155.         CALL MOVELIST(A, B, XX(), YY(), NDX)
  156.         FOR K = 0 TO NDX STEP 1
  157.             IF X = XX(K) AND Y = YY(K) THEN
  158.                 MOVER = BOARD(B, A)
  159.                 TARGET = BOARD(Y, X)
  160.                 INTFLAG = -1
  161.                 CALL MAKEMOVE(A, B, X, Y)
  162.                 INTFLAG = 0
  163.                15 IF INCHECK(0) = 0 THEN EXIT SUB
  164.                 BOARD(B, A) = MOVER
  165.                 BOARD(Y, X) = TARGET
  166.                 GOTO 16
  167.             END IF
  168.         NEXT
  169.        16 CLS
  170.     LOOP
  171.  
  172. SUB KING (A, B, XX(), YY(), NDX)
  173.     ID = SGN(BOARD(B, A))
  174.     FOR DY = -1 TO 1
  175.         IF B + DY < 0 OR B + DY > 7 THEN GOTO 12
  176.         FOR DX = -1 TO 1
  177.             IF A + DX < 0 OR A + DX > 7 THEN GOTO 11
  178.             IF ID <> SGN(BOARD(B + DY, A + DX)) THEN
  179.                 NDX = NDX + 1
  180.                 XX(NDX) = A + DX
  181.                 YY(NDX) = B + DY
  182.             END IF
  183.        11 NEXT
  184.    12 NEXT
  185.  
  186. SUB MAKEMOVE (A, B, X, Y)
  187.     BOARD(Y, X) = BOARD(B, A)
  188.     BOARD(B, A) = 0
  189.  
  190. SUB MOVELIST (A, B, XX(), YY(), NDX)
  191.     PIECE = INT(ABS(BOARD(B, A)))
  192.     NDX = -1
  193.     IF PIECE = 500 THEN CALL ROOK(A, B, XX(), YY(), NDX) ELSE CALL KING(A, B, XX(), YY(), NDX)
  194.  
  195. SUB ROOK (A, B, XX(), YY(), NDX)
  196.     ID = SGN(BOARD(B, A))
  197.     FOR X = A - 1 TO 0 STEP -1
  198.         IF ID <> SGN(BOARD(B, X)) THEN
  199.             NDX = NDX + 1
  200.             XX(NDX) = X
  201.             YY(NDX) = B
  202.         END IF
  203.         IF (BOARD(B, X)) <> 0 THEN EXIT FOR
  204.     NEXT
  205.     FOR X = A + 1 TO 7 STEP 1
  206.         IF ID <> SGN(BOARD(B, X)) THEN
  207.             NDX = NDX + 1
  208.             XX(NDX) = X
  209.             YY(NDX) = B
  210.         END IF
  211.         IF (BOARD(B, X)) <> 0 THEN EXIT FOR
  212.     NEXT
  213.     FOR Y = B - 1 TO 0 STEP -1
  214.         IF ID <> SGN(BOARD(Y, A)) THEN
  215.             NDX = NDX + 1
  216.             XX(NDX) = A
  217.             YY(NDX) = Y
  218.         END IF
  219.         IF (BOARD(Y, A)) <> 0 THEN EXIT FOR
  220.     NEXT
  221.     FOR Y = B + 1 TO 7 STEP 1
  222.         IF ID <> SGN(BOARD(Y, A)) THEN
  223.             NDX = NDX + 1
  224.             XX(NDX) = A
  225.             YY(NDX) = Y
  226.         END IF
  227.         IF (BOARD(Y, A)) <> 0 THEN EXIT FOR
  228.     NEXT
  229.  
  230. SUB SHOWBD
  231.     VIEW PRINT
  232.     LOCATE 3, 30
  233.     COLOR 7, 0
  234.     PRINT "A  B  C  D  E  F  G  H"
  235.     FOR K = 0 TO 25
  236.         LOCATE 4, 28 + K
  237.         COLOR 6, 0
  238.         PRINT CHR$(220)
  239.     NEXT
  240.     FOR B = 0 TO 7
  241.         LOCATE 2 * B + 5, 26
  242.         COLOR 7, 0
  243.         PRINT CHR$(56 - B)
  244.         LOCATE 2 * B + 5, 28
  245.         COLOR 6, 0
  246.         PRINT CHR$(219)
  247.         LOCATE 2 * B + 6, 28
  248.         PRINT CHR$(219)
  249.         FOR A = 0 TO 7
  250.             IF ((A + B) MOD 2) <> 0 THEN
  251.                 COLOUR = 2
  252.             ELSE COLOUR = 15
  253.             END IF
  254.             CALL SQUARE(3 * A + 31, 2 * B + 5, COLOUR)
  255.         NEXT
  256.         LOCATE 2 * B + 5, 53
  257.         COLOR 6, 0
  258.         PRINT CHR$(219)
  259.         LOCATE 2 * B + 6, 53
  260.         PRINT CHR$(219)
  261.         LOCATE 2 * B + 6, 55
  262.         COLOR 7, 0
  263.         PRINT CHR$(56 - B)
  264.     NEXT
  265.     FOR K = 0 TO 25
  266.         LOCATE 21, 28 + K
  267.         COLOR 6, 0
  268.         PRINT CHR$(223)
  269.     NEXT
  270.     LOCATE 22, 30
  271.     COLOR 7, 0
  272.     PRINT "A  B  C  D  E  F  G  H"
  273.     FOR B = 0 TO 7
  274.         FOR A = 0 TO 7
  275.             CALL SHOWMAN(A, B, 0)
  276.         NEXT
  277.     NEXT
  278.     COLOR 7, 0
  279.  
  280. SUB SHOWMAN (A, B, FLAG)
  281.     IF BOARD(B, A) < 0 THEN BACK = 0
  282.     IF BOARD(B, A) > 0 THEN BACK = 7
  283.     FORE = 7 - BACK + FLAG
  284.     IF BOARD(B, A) = 0 THEN
  285.         IF ((A + B) MOD 2) <> 0 THEN BACK = 2 ELSE BACK = 15
  286.         FORE = BACK + -1 * (FLAG > 0)
  287.     END IF
  288.     N$ = " "
  289.     PIECE = INT(ABS(BOARD(B, A)))
  290.     IF PIECE = 0 THEN N$ = CHR$(219)
  291.     IF PIECE = 500 THEN N$ = "R"
  292.     IF PIECE = 5000 OR PIECE = 7500 THEN N$ = "K"
  293.     LOCATE 2 * B + 5 - (BOARD(B, A) > 0), 3 * A + 30
  294.     COLOR FORE, BACK
  295.     PRINT N$
  296.     LOCATE 1, 1
  297.     COLOR 7, 0
  298.  
  299. SUB SQUARE (A, B, C)
  300.     MT$ = CHR$(219)
  301.     MT$ = MT$ + MT$ + MT$
  302.     LOCATE B, A - 2
  303.     COLOR C, C
  304.     PRINT MT$
  305.     LOCATE B + 1, A - 2
  306.     PRINT MT$
  307.     COLOR 7, 0
« Last Edit: January 05, 2021, 08:50:11 pm by Adrian »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Chess project : King + Rook vs King endgame
« Reply #1 on: January 05, 2021, 01:36:09 pm »
Yes, this is the way to start real game program:

These 2 things seem imperative
#1 seek a win in next move, if that fails
#2 seek to spoil opponents win in next move

then you start playing for best positions or seeing moves ahead with recursive use of #1 and #2!

I don't think that! is in the sample Chess program that comes with QB64.