'HUOC: Huo Chess by Spiros I. Kakos (huo) - DRAFT VERSION (NOT FULLY TESTED, STILL IN PROGRESS) 'Version 0.2: Thinking in 3 moves depth 'Based on the Huo Chess implementation in C++ and C# 'Check "Huo Chess" in C# at Harmonia Philosophica for fully functional code 'Check https://harmoniaphilosophica.com/2019/02/13/huo-chess-c-micro-chess-updated/ 'Other QBasic Internet resources 'https://www.qb64.org/wiki/Arrays#Working_with_the_Array_Elements 'https://www.qb64.org/wiki/CALL 'https://www.qb64.org/wiki/SUB 'https://www.qb64.org/wiki/IF...THEN 'What is not supported... '1. En passant '2. Castling DECLARE SUB movValidation (aline AS INTEGER, fline AS INTEGER, arcol AS INTEGER, telcol AS INTEGER) DECLARE SUB drawBoard () DECLARE SUB ElegxosNomimotitas(ENSkakiera() AS STRING, startColumn AS INTEGER, startRank AS INTEGER, finishColumn AS INTEGER, finishRank AS INTEGER, MovingPieceEN AS STRING) DEFINT A-Z OPTION BASE 1 'Make tables dimensions start from 1 DIM SHARED chessboard$(8, 8) COMMON SHARED playerColor$ COMMON SHARED startingRank, startingColumn COMMON SHARED finishingRank, finishingColumn COMMON SHARED startingRankText$, startingColumnText$ COMMON SHARED finishingRankText$, finishingColumnText$ COMMON SHARED Move$ COMMON SHARED MovingPiece$ COMMON SHARED ProsorinoKommati$ COMMON SHARED Nomimotita COMMON SHARED debugMode COMMON SHARED positionScore COMMON SHARED bestStartingRank, bestStartingColumn COMMON SHARED bestFinishingRank, bestFinishingColumn COMMON SHARED bestPositionScore COMMON SHARED whoPlays$ COMMON SHARED computerLogs$, humanLogs$ COMMON SHARED thinkingDepth COMMON SHARED Move 'Set debugMode = 1 if you want debugging messages to appear, else set to 0 debugMode = 0 PRINT "Huo Chess - HUOC by Spiros Kakos (2020) - ALPHA VERSION" PRINT "The best educational purposes open source chess in BASIC" PRINT "" PRINT "Version 0.3: Thinking in 3 moves depth" PRINT "" PRINT "NOT FULLY FUNCTIONAL!" PRINT "NOT FULLY TESTED!" PRINT "FOR EDUCATIONAL PURPOSES ONLY!" PRINT "DEVELOPERS VERSION - TEST POSITION LOADED!" PRINT "" PRINT "Check HUO CHESS in C# for a fully functional open source chess program!" PRINT "" SetPlayerColor: 'Set the colour of the player INPUT "Set your color. Please select 'w' or 'b': ", playerColor$ IF playerColor$ <> "w" AND playerColor$ <> "b" THEN GOTO SetPlayerColor SetThinkingDepth: 'Set the thinking depth PRINT "": INPUT "Set thinking depth. Please select 1 or 3: ", thinkingDepth IF thinkingDepth <> 1 AND thinkingDepth <> 3 THEN GOTO SetThinkingDepth PRINT "" computerLogs: INPUT "Activate logs for computer? (y/n) ", computerLogs$: IF computerLogs$ <> "y" AND computerLogs$ <> "n" THEN GOTO computerLogs humanLogs: INPUT "Activate log for the human? (y/n) ", humanLogs$: IF humanLogs$ <> "y" AND humanLogs$ <> "n" THEN GOTO humanLogs CLS CALL initialPosition CALL drawBoard 'Set thinking depth 'thinkingDepth = 3 LOCATE 12, 1: PRINT "Huo Chess - HUOC" IF playerColor$ = "w" THEN whoPlays$ = "Human" CALL PlayerMove END IF IF playerColor$ = "b" THEN whoPlays$ = "HY" CALL computerMove END IF SUB PlayerMove LOCATE 13, 1: INPUT "Enter your move: ", Move$ startingColumnText$ = MID$(Move$, 1, 1) startingRankText$ = MID$(Move$, 2, 1) finishingColumnText$ = MID$(Move$, 3, 1) finishingRankText$ = MID$(Move$, 4, 1) IF humanLogs$ = "y" THEN debugMode = 1 ELSE debugMode = 0 SELECT CASE startingRankText$ CASE "1" startingRank = 1 CASE "2" startingRank = 2 CASE "3" startingRank = 3 CASE "4" startingRank = 4 CASE "5" startingRank = 5 CASE "6" startingRank = 6 CASE "7" startingRank = 7 CASE "8" startingRank = 8 END SELECT SELECT CASE finishingRankText$ CASE "1" finishingRank = 1 CASE "2" finishingRank = 2 CASE "3" finishingRank = 3 CASE "4" finishingRank = 4 CASE "5" finishingRank = 5 CASE "6" finishingRank = 6 CASE "7" finishingRank = 7 CASE "8" finishingRank = 8 END SELECT SELECT CASE startingColumnText$ CASE "A", "a" startingColumn = 1 CASE "B", "b" startingColumn = 2 CASE "C", "c" startingColumn = 3 CASE "D", "d" startingColumn = 4 CASE "E", "e" startingColumn = 5 CASE "F", "f" startingColumn = 6 CASE "G", "g" startingColumn = 7 CASE "H", "h" startingColumn = 8 END SELECT SELECT CASE finishingColumnText$ CASE "A", "a" finishingColumn = 1 CASE "B", "b" finishingColumn = 2 CASE "C", "c" finishingColumn = 3 CASE "D", "d" finishingColumn = 4 CASE "E", "e" finishingColumn = 5 CASE "F", "f" finishingColumn = 6 CASE "G", "g" finishingColumn = 7 CASE "H", "h" finishingColumn = 8 END SELECT MovingPiece$ = chessboard$(startingColumn, startingRank) IF (debugMode = 1) THEN PRINT "[Move: " + STR$(startingColumn) + STR$(startingRank) + " -> " + STR$(finishingColumn) + STR$(finishingRank) + " ]" END IF 'Check legality of the move entered CALL ElegxosNomimotitas(chessboard$(), 0, startingColumn, startingRank, finishingColumn, finishingRank, MovingPiece$) 'If move is legal, then do the move and present it in the chessbooard IF Nomimotita = 1 THEN IF debugMode = 1 THEN PRINT "Now we will redraw the chessboard" END IF 'Do the move chessboard$(finishingColumn, finishingRank) = chessboard$(startingColumn, startingRank) chessboard$(startingColumn, startingRank) = "" CLS CALL drawBoard END IF 'Time for the computer to think now... whoPlays$ = "HY" CALL computerMove END SUB SUB computerMove 'Initialize variables Move = 1 bestPositionScore = 0 bestStartingRank = 0 bestStartingColumn = 0 bestFinishingRank = 0 bestFinishingColumn = 0 IF playerColor$ = "w" THEN bestPositionScore = 999 IF playerColor$ = "b" THEN bestPositionScore = -999 IF computerLogs$ = "y" THEN debugMode = 1 ELSE debugMode = 0 IF debugMode = 1 THEN PRINT "chessboard$(1,1) = " + chessboard$(1, 1) IF debugMode = 1 THEN PRINT "MID$(chessboard$(1, 1), 1, 1) = " + MID$(chessboard$(1, 1), 1, 1) 'Scan the chessboard... FOR I = 1 TO 8 FOR J = 1 TO 8 'If you find a piece of the computer... IF ((MID$(chessboard$(I, J), 1, 1) = "w" AND playerColor$ = "b") OR (MID$(chessboard$(I, J), 1, 1) = "b" AND playerColor$ = "w")) THEN IF debugMode = 1 THEN PRINT "Inside Computer Mode - Checkpoint A" 'Scan all possible destination squares... FOR ii = 1 TO 8 FOR jj = 1 TO 8 startingColumn = I startingRank = J finishingColumn = ii finishingRank = jj MovingPiece$ = chessboard$(I, J) ProsorinoKommati$ = chessboard$(ii, jj) 'Check legality of the move entered CALL ElegxosNomimotitas(chessboard$(), 0, startingColumn, startingRank, finishingColumn, finishingRank, MovingPiece$) IF debugMode = 1 THEN PRINT "" PRINT "NEW MOVE ANALYZED: " + STR$(startingColumn) + STR$(startingRank) + " -> " + STR$(finishingColumn) + STR$(finishingRank) PRINT "Legality of the move analyzed: " + STR$(Nomimotita) END IF 'If move is legal, then do the move and present it in the chessbooard IF Nomimotita = 1 THEN 'Do the move chessboard$(finishingColumn, finishingRank) = chessboard$(startingColumn, startingRank) chessboard$(startingColumn, startingRank) = "" 'Count the score of the move CALL countScore IF Move = thinkingDepth THEN 'If the score is better than the existing best score, then this is the best move now (and the best score) IF ((playerColor$ = "b" AND positionScore >= bestPositionScore) OR (playerColor$ = "w" AND positionScore <= bestPositionScore)) THEN bestStartingRank = startingRank bestStartingColumn = startingColumn bestFinishingRank = finishingRank bestFinishingColumn = finishingColumn bestPositionScore = positionScore END IF END IF IF Move < thinkingDepth THEN CALL HumanMove1(chessboard$()) END IF 'Undo the move chessboard$(startingColumn, startingRank) = MovingPiece$ chessboard$(finishingColumn, finishingRank) = ProsorinoKommati$ NEXT jj NEXT ii END IF NEXT J NEXT I IF debugMode = 1 THEN PRINT "bestStartingRank = " + STR$(bestStartingRank) PRINT "bestStartingColumn = " + STR$(bestStartingColumn) PRINT "bestFinishingRank = " + STR$(bestFinishingRank) PRINT "bestFinishingColumn = " + STR$(bestFinishingColumn) END IF 'Do the best move found chessboard$(bestFinishingColumn, bestFinishingRank) = chessboard$(bestStartingColumn, bestStartingRank) chessboard$(bestStartingColumn, bestStartingRank) = "" CLS CALL drawBoard SELECT CASE bestStartingColumn CASE 1 startingColumnText$ = "a" CASE 2 startingColumnText$ = "b" CASE 3 startingColumnText$ = "c" CASE 4 startingColumnText$ = "d" CASE 5 startingColumnText$ = "e" CASE 6 startingColumnText$ = "f" CASE 7 startingColumnText$ = "g" CASE 8 startingColumnText$ = "h" END SELECT SELECT CASE bestFinishingColumn CASE 1 finishingColumnText$ = "a" CASE 2 finishingColumnText$ = "b" CASE 3 finishingColumnText$ = "c" CASE 4 finishingColumnText$ = "d" CASE 5 finishingColumnText$ = "e" CASE 6 finishingColumnText$ = "f" CASE 7 finishingColumnText$ = "g" CASE 8 finishingColumnText$ = "h" END SELECT LOCATE 12, 1: PRINT "My move: " + startingColumnText$ + STR$(bestStartingRank) + " -> " + finishingColumnText$ + STR$(bestFinishingRank) 'Time for the human to play now... whoPlays$ = "Human" CALL PlayerMove END SUB '----------------------------------------------------------------------------------------------------- SUB initialPosition chessboard$(1, 1) = "wrook": chessboard$(1, 2) = "wpawn" chessboard$(2, 1) = "wknight": chessboard$(2, 2) = "wpawn" chessboard$(3, 1) = "wbishop": chessboard$(3, 2) = "wpawn" chessboard$(4, 1) = "wqueen": chessboard$(4, 2) = "wpawn" chessboard$(5, 1) = "wking": chessboard$(5, 2) = "wpawn" chessboard$(6, 1) = "wbishop": chessboard$(6, 2) = "wpawn" chessboard$(7, 1) = "wknight": chessboard$(7, 2) = "wpawn" chessboard$(8, 1) = "wrook": chessboard$(8, 2) = "wpawn" chessboard$(1, 7) = "bpawn": chessboard$(1, 8) = "brook" chessboard$(2, 7) = "bpawn": chessboard$(2, 8) = "bknight" chessboard$(3, 7) = "bpawn": chessboard$(3, 8) = "bbishop" chessboard$(4, 7) = "bpawn": chessboard$(4, 8) = "bqueen" chessboard$(5, 7) = "bpawn": chessboard$(5, 8) = "bking" chessboard$(6, 7) = "bpawn": chessboard$(6, 8) = "bbishop" chessboard$(7, 7) = "bpawn": chessboard$(7, 8) = "bknight" chessboard$(8, 7) = "bpawn": chessboard$(8, 8) = "brook" 'Test 'FOR q = 1 TO 8 ' FOR w = 1 TO 8 ' chessboard$(q, w) = "" ' NEXT w 'NEXT q 'chessboard$(4, 4) = "wbishop" 'chessboard$(5, 5) = "bbishop" 'chessboard$(1, 1) = "wrook" 'chessboard$(1, 8) = "brook" 'chessboard$(2, 2) = "wpawn" '---------- TEST ---------- chessboard$(1, 1) = "wrook": chessboard$(1, 2) = "wpawn" chessboard$(2, 1) = "wknight": chessboard$(2, 2) = "bpawn" chessboard$(3, 1) = "": chessboard$(3, 2) = "wpawn" chessboard$(4, 1) = "": chessboard$(4, 2) = "wpawn" chessboard$(5, 1) = "wking": chessboard$(5, 2) = "" chessboard$(6, 1) = "": chessboard$(6, 2) = "wpawn" chessboard$(7, 1) = "wknight": chessboard$(7, 2) = "wpawn" chessboard$(8, 1) = "wrook": chessboard$(8, 2) = "" chessboard$(1, 7) = "": chessboard$(1, 8) = "brook" chessboard$(2, 7) = "wbishop": chessboard$(2, 8) = "bknight" chessboard$(3, 7) = "bpawn": chessboard$(3, 8) = "" chessboard$(4, 7) = "bpawn": chessboard$(4, 8) = "bqueen" chessboard$(5, 7) = "bpawn": chessboard$(5, 8) = "bking" chessboard$(6, 7) = "bpawn": chessboard$(6, 8) = "bbishop" chessboard$(7, 7) = "bpawn": chessboard$(7, 8) = "bknight" chessboard$(8, 7) = "bpawn": chessboard$(8, 8) = "brook" chessboard$(4, 4) = "wpawn" chessboard$(2, 4) = "wbishop" chessboard$(6, 4) = "wqueen" chessboard$(7, 6) = "bbishop" END SUB ' ------------------------------------------------------------------------------------------------------- SUB drawBoard sqcolor$ = "" 'Square color piece$ = "" 'Piece to be printed pfcolor = 0 'Piece front color pbcolor = 1 'Piece back color MT$ = CHR$(219) SQ$ = MT$ + MT$ + MT$ 'CLS 0 SCREEN 0 'COLOR 6 'LINE (0, 0)-(30, 30), 0, BF LOCATE 1, 1 PRINT "HUO Chess (HUOC) by Spiros (h uo) Kakos - Alpha version" FOR i = 1 TO 8 FOR j = 1 TO 8 IF (i + j) MOD 2 = 0 THEN sqcolor$ = "b" ELSEIF (i + j) MOD 2 <> 0 THEN sqcolor$ = "w" END IF 'Columns are the first number inside the parenthesis and 'because we start drawing the board from upside-up, we 'must apply this (9 - i) to draw the board correctly 'Print the square LOCATE 2 + (9 - i), 1 + (j - 1) * 3 IF sqcolor$ = "w" THEN COLOR 7, 0 ELSEIF sqcolor$ = "b" THEN COLOR 0, 7 END IF PRINT SQ$ 'Determine the color of the piece to print IF LEFT$(chessboard$(j, i), 1) = "w" AND sqcolor$ = "w" THEN pfcolor = 15 pbcolor = 7 ELSEIF LEFT$(chessboard$(j, i), 1) = "w" AND sqcolor$ = "b" THEN pfcolor = 15 pbcolor = 0 ELSEIF LEFT$(chessboard$(j, i), 1) = "b" AND sqcolor$ = "w" THEN pfcolor = 5 pbcolor = 7 ELSEIF LEFT$(chessboard$(j, i), 1) = "b" AND sqcolor$ = "b" THEN pfcolor = 5 pbcolor = 0 END IF SELECT CASE chessboard$(j, i) CASE "wking" piece$ = "K" CASE "wqueen" piece$ = "Q" CASE "wrook" piece$ = "R" CASE "wbishop" piece$ = "B" CASE "wknight" piece$ = "N" CASE "wpawn" piece$ = "o" CASE "bking" piece$ = "K" CASE "bqueen" piece$ = "Q" CASE "brook" piece$ = "R" CASE "bbishop" piece$ = "B" CASE "bknight" piece$ = "N" CASE "bpawn" piece$ = "o" CASE "" piece$ = "" END SELECT 'Print the piece LOCATE 2 + (9 - i), 2 + (j - 1) * 3 COLOR pfcolor, pbcolor PRINT piece$ NEXT j NEXT i 'Restore color of screen and text COLOR 7, 0 'Restore cursor LOCATE 13, 1 END SUB ' ------------------------------------------------------------------------------------------------------- SUB ElegxosNomimotitas (ENSkakiera() AS STRING, checkForDanger AS INTEGER, startColumn AS INTEGER, startRank AS INTEGER, finishColumn AS INTEGER, finishRank AS INTEGER, MovingPieceEN AS STRING) 'Some GREEK: Skakiera in Greek means "chessboard". NomimotitaEN in Greek means "legality". 'This SUB checks the legality of the moves enetered by the player or thought by the computer DIM ProsorinoKommatiEN AS STRING DIM NomimotitaEN NomimotitaEN = 1 'Set legality (= Nomimotita in Greek) to TRUE. If a problem is found then it will be set to FALSE. IF (debugMode = 1) THEN PRINT "" PRINT "--------------- DEBUG MESSAGE ---------------" PRINT "ElegxosNomimotitas CALLED" PRINT "" PRINT "Start column: " + STR$(startColumn) PRINT "Start rank : " + STR$(startRank) PRINT "End column : " + STR$(finishColumn) PRINT "End rank : " + STR$(finishRank) PRINT "" PRINT "Moving piece: " + MovingPieceEN$ PRINT "ENSkakiera(1,1) = " + ENSkakiera(1, 1) PRINT "ENSkakiera(1,2) = " + ENSkakiera(1, 2) PRINT "" PRINT "playerColor$ = " + playerColor$ PRINT "---------------------------------------------" PRINT "" INPUT a$ END IF 'If player moves a different colour piece then move is illegal IF whoPlays$ = "Human" THEN IF MID$(playerColor$, 1, 1) <> MID$(ENSkakiera$(startColumn, startRank), 1, 1) THEN NomimotitaEN = 0 END IF IF whoPlays$ = "HY" THEN IF MID$(playerColor$, 1, 1) = MID$(ENSkakiera$(startColumn, startRank), 1, 1) THEN NomimotitaEN = 0 END IF ' ------------------------------------ ROOK ------------------------------------ IF (MovingPieceEN$ = "wrook" OR MovingPieceEN$ = "brook") THEN IF debugMode = 1 THEN PRINT "Nomimotita = " + STR$(NomimotitaEN) 'Check correctness of move (Rook only moves in lines) IF ((startColumn <> finishColumn) AND (startRank <> finishRank)) THEN NomimotitaEN = 0 IF debugMode = 1 AND NomimotitaEN = 0 THEN PRINT "Checkpoint ROOK-0" 'Check if the Rook moves beyond the limits of the chessboard IF ((finishColumn < 1) OR (finishRank < 1)) THEN NomimotitaEN = 0 IF ((finishColumn > 8) OR (finishRank > 8)) THEN NomimotitaEN = 0 IF debugMode = 1 AND NomimotitaEN = 0 THEN PRINT "Checkpoint ROOK-1" 'Check if another piece is between the current and the target square 'Horizontal movement IF (startColumn > finishColumn) AND (startRank = finishRank) THEN FOR J = startColumn TO finishColumn STEP -1 IF (J <> startColumn) AND (J <> finishColumn) AND ENSkakiera(J, startRank) <> "" THEN NomimotitaEN = 0 NEXT J END IF IF (startColumn < finishColumn) AND (startRank = finishRank) THEN FOR J = startColumn TO finishColumn IF (J <> startColumn) AND (J <> finishColumn) AND ENSkakiera(J, startRank) <> "" THEN NomimotitaEN = 0 NEXT J END IF IF debugMode = 1 AND NomimotitaEN = 0 THEN PRINT "Checkpoint ROOK-2" 'Vertical movement IF (startColumn = finishColumn) AND (startRank > finishRank) THEN FOR J = startRank TO finishRank STEP -1 IF (J <> startRank) AND (J <> finishRank) AND ENSkakiera(startColumn, J) <> "" THEN NomimotitaEN = 0 NEXT J END IF IF (startColumn = finishColumn) AND (startRank < finishRank) THEN FOR J = startRank TO finishRank IF (J <> startRank) AND (J <> finishRank) AND ENSkakiera(startColumn, J) <> "" THEN NomimotitaEN = 0 NEXT J END IF IF debugMode = 1 AND NomimotitaEN = 0 THEN PRINT "Checkpoint ROOK-3" 'If the start square is the same as the destination... IF startColumn = finishColumn AND startRank = finishRank THEN NomimotitaEN = 0 IF debugMode = 1 AND NomimotitaEN = 0 THEN PRINT "Checkpoint ROOK-4" 'Check if a piece of the same colour is at the destination square IF MID$(ENSkakiera$(finishColumn, finishRank), 1, 1) = MID$(ENSkakiera$(startColumn, startRank), 1, 1) THEN NomimotitaEN = 0 IF debugMode = 1 AND NomimotitaEN = 0 THEN PRINT "Checkpoint ROOK-5": 'INPUT a$ END IF ' ------------------------------------ BISHOP ------------------------------------ IF (MovingPieceEN$ = "wbishop" OR MovingPieceEN$ = "bbishop") THEN 'Check correctness of move (Bishop only moves in diagonals) IF ((startRank = finishRank) OR (startColumn = finishColumn)) THEN NomimotitaEN = 0 IF (ABS(startColumn - finishColumn) <> ABS(startRank - finishRank)) THEN NomimotitaEN = 0 IF debugMode = 1 AND NomimotitaEN = 0 THEN PRINT "Bishop - Checkpoint A" 'Check if the piece moves beyond the limits of the chessboard IF ((finishColumn < 1) OR (finishRank < 1)) THEN NomimotitaEN = 0 IF ((finishColumn > 8) OR (finishRank > 8)) THEN NomimotitaEN = 0 IF debugMode = 1 AND NomimotitaEN = 0 THEN PRINT "Bishop - Checkpoint B" 'Check if another piece is between the current and the target square 'Move down-left IF (finishColumn < startColumn) AND (finishRank < startRank) THEN FOR I = 1 TO 7 IF (startColumn - I) > 0 AND (startRank - I) > 0 THEN IF (startColumn - I) <> finishColumn AND (startRank - I) <> finishRank AND ENSkakiera(startColumn - I, startRank - I) <> "" THEN NomimotitaEN = 0 END IF NEXT I END IF 'Move up-left IF (finishColumn < startColumn) AND (finishRank > startRank) THEN FOR I = 1 TO 7 IF (startColumn - I) > 0 AND (startRank + I) < 9 THEN IF (startColumn - I) <> finishColumn AND (startRank + I) <> finishRank AND ENSkakiera(startColumn - I, startRank + I) <> "" THEN NomimotitaEN = 0 END IF NEXT I END IF 'Move up-right IF (finishColumn > startColumn) AND (finishRank > startRank) THEN FOR I = 1 TO 7 IF (startColumn + I) < 9 AND (startRank + I) < 9 THEN IF (startColumn + I) <> finishColumn AND (startRank + I) <> finishRank AND ENSkakiera(startColumn + I, startRank + I) <> "" THEN NomimotitaEN = 0 END IF NEXT I END IF 'Move down-right IF (finishColumn > startColumn) AND (finishRank < startRank) THEN FOR I = 1 TO 7 IF (startColumn + I) < 9 AND (startRank - I) > 0 THEN IF (startColumn + I) <> finishColumn AND (startRank - I) <> finishRank AND ENSkakiera(startColumn + I, startRank - I) <> "" THEN NomimotitaEN = 0 END IF NEXT I END IF IF debugMode = 1 AND NomimotitaEN = 0 THEN PRINT "Bishop - Checkpoint C" 'If the start square is the same as the destination... IF startColumn = finishColumn AND startRank = finishRank THEN NomimotitaEN = 0 IF debugMode = 1 AND NomimotitaEN = 0 THEN PRINT "Bishop - Checkpoint D" 'Check if a piece of the same colour is at the destination square IF MID$(ENSkakiera$(finishColumn, finishRank), 1, 1) = MID$(ENSkakiera$(startColumn, startRank), 1, 1) THEN NomimotitaEN = 0 IF debugMode = 1 AND NomimotitaEN = 0 THEN PRINT "Bishop - Checkpoint E": 'INPUT a$ END IF ' ------------------------------------ QUEEN ------------------------------------ IF (MovingPieceEN$ = "wqueen" OR MovingPieceEN$ = "bqueen") THEN 'Check correctness of move (Queen moves in diagonals and in lines) 'Different check depending on whether the queen moves in lines or not. 'Checks are a combination of the above checks for Rook and Bishop. IF (startRank <> finishRank) AND (startColumn <> finishColumn) THEN IF (ABS(startColumn - finishColumn) <> ABS(startRank - finishRank)) THEN NomimotitaEN = 0 END IF IF debugMode = 1 THEN PRINT "Queen - Entered check legality SUB": INPUT a$ IF debugMode = 1 AND NomimotitaEN = 0 THEN PRINT "Queen - Checkpoint Null" 'Check if the piece moves beyond the limits of the chessboard IF ((finishColumn < 1) OR (finishRank < 1)) THEN NomimotitaEN = 0 IF ((finishColumn > 8) OR (finishRank > 8)) THEN NomimotitaEN = 0 'Check if another piece is between the current and the target square 'Diagonal movement 'Move down-left IF (finishColumn < startColumn) AND (finishRank < startRank) THEN FOR I = 1 TO 7 IF (startColumn - I) > 0 AND (startRank - I) > 0 THEN IF (startColumn - I) <> finishColumn AND (startRank - I) <> finishRank AND ENSkakiera(startColumn - I, startRank - I) <> "" THEN NomimotitaEN = 0 END IF NEXT I END IF 'Move up-left IF (finishColumn < startColumn) AND (finishRank > startRank) THEN FOR I = 1 TO 7 IF (startColumn - I) > 0 AND (startRank + I) < 9 THEN IF (startColumn - I) <> finishColumn AND (startRank + I) <> finishRank AND ENSkakiera(startColumn - I, startRank + I) <> "" THEN NomimotitaEN = 0 END IF NEXT I END IF 'Move up-right IF (finishColumn > startColumn) AND (finishRank > startRank) THEN FOR I = 1 TO 7 IF (startColumn + I) < 9 AND (startRank + I) < 9 THEN IF (startColumn + I) <> finishColumn AND (startRank + I) <> finishRank AND ENSkakiera(startColumn + I, startRank + I) <> "" THEN NomimotitaEN = 0 END IF NEXT I END IF 'Move down-right IF (finishColumn > startColumn) AND (finishRank < startRank) THEN FOR I = 1 TO 7 IF (startColumn + I) < 9 AND (startRank - I) > 0 THEN IF (startColumn + I) <> finishColumn AND (startRank - I) <> finishRank AND ENSkakiera(startColumn + I, startRank - I) <> "" THEN NomimotitaEN = 0 END IF NEXT I END IF IF debugMode = 1 AND NomimotitaEN = 0 THEN PRINT "Queen - Checkpoint 0" 'Horizontal movement IF (startColumn > finishColumn) AND (startRank = finishRank) THEN FOR J = startColumn TO finishColumn STEP -1 IF (J <> startColumn) AND (J <> finishColumn) AND ENSkakiera(J, startRank) <> "" THEN NomimotitaEN = 0 NEXT J END IF IF (startColumn < finishColumn) AND (startRank = finishRank) THEN FOR J = startColumn TO finishColumn IF (J <> startColumn) AND (J <> finishColumn) AND ENSkakiera(J, startRank) <> "" THEN NomimotitaEN = 0 NEXT J END IF IF debugMode = 1 AND NomimotitaEN = 0 THEN PRINT "Queen - Checkpoint 1" IF debugMode = 1 THEN PRINT "startColumn = " + STR$(startColumn) + " - finishColumn = " + STR$(finishColumn) 'Vertical movement IF (startColumn = finishColumn) AND (startRank > finishRank) THEN FOR J = startRank TO finishRank STEP -1 IF (J <> startRank) AND (J <> finishRank) AND ENSkakiera(startColumn, J) <> "" THEN NomimotitaEN = 0 NEXT J END IF IF (startColumn = finishColumn) AND (startRank < finishRank) THEN FOR J = startRank TO finishRank IF (J <> startRank) AND (J <> finishRank) AND ENSkakiera(startColumn, J) <> "" THEN NomimotitaEN = 0 NEXT J END IF IF debugMode = 1 AND NomimotitaEN = 0 THEN PRINT "Queen - Checkpoint 2" 'If the start square is the same as the destination... IF startColumn = finishColumn AND startRank = finishRank THEN NomimotitaEN = 0 'Check if a piece of the same colour is at the destination square IF MID$(ENSkakiera$(finishColumn, finishRank), 1, 1) = MID$(ENSkakiera$(startColumn, startRank), 1, 1) THEN NomimotitaEN = 0 IF debugMode = 1 AND NomimotitaEN = 0 THEN PRINT "Queen - Checkpoint 3": INPUT a$ END IF ' ------------------------------------ KING ------------------------------------ IF (MovingPieceEN$ = "wking" OR MovingPieceEN$ = "bking") THEN 'Check correctness of move (King moves in diagonals and in lines, but only for one square) 'Different check depending on whether the queen moves in lines or not. 'Checks are the same as the checks for the Queen, with the addition of a check that King only moves one square. IF (startRank <> finishRank) AND (startColumn <> finishColumn) THEN IF (ABS(startColumn - finishColumn) <> ABS(startRank - finishRank)) THEN NomimotitaEN = 0 END IF 'Castling not supported 'Check if the King moves more than one square IF ABS(startColumn - finishColumn) > 1 OR ABS(startRank - finishRank) > 1 THEN NomimotitaEN = 0 'Check if the piece moves beyond the limits of the chessboard IF ((finishColumn < 1) OR (finishRank < 1)) THEN NomimotitaEN = 0 IF ((finishColumn > 8) OR (finishRank > 8)) THEN NomimotitaEN = 0 'If the start square is the same as the destination... IF startColumn = finishColumn AND startRank = finishRank THEN NomimotitaEN = 0 'Check if a piece of the same colour is at the destination square IF MID$(ENSkakiera$(finishColumn, finishRank), 1, 1) = MID$(ENSkakiera$(startColumn, startRank), 1, 1) THEN NomimotitaEN = 0 END IF ' ------------------------------------ KNIGHT ------------------------------------ IF (MovingPieceEN$ = "wknight" OR MovingPieceEN$ = "bknight") THEN NomimotitaEN = 0 IF (finishColumn = startColumn + 2) AND (finishRank = startRank + 1) THEN NomimotitaEN = 1 IF (finishColumn = startColumn + 2) AND (finishRank = startRank - 1) THEN NomimotitaEN = 1 IF (finishColumn = startColumn + 1) AND (finishRank = startRank + 2) THEN NomimotitaEN = 1 IF (finishColumn = startColumn + 1) AND (finishRank = startRank - 2) THEN NomimotitaEN = 1 IF (finishColumn = startColumn - 1) AND (finishRank = startRank + 2) THEN NomimotitaEN = 1 IF (finishColumn = startColumn - 1) AND (finishRank = startRank - 2) THEN NomimotitaEN = 1 IF (finishColumn = startColumn - 2) AND (finishRank = startRank + 1) THEN NomimotitaEN = 1 IF (finishColumn = startColumn - 2) AND (finishRank = startRank - 1) THEN NomimotitaEN = 1 'Check if the piece moves beyond the limits of the chessboard IF ((finishColumn < 1) OR (finishRank < 1)) THEN NomimotitaEN = 0 IF ((finishColumn > 8) OR (finishRank > 8)) THEN NomimotitaEN = 0 'Check if a piece of the same colour is at the destination square IF MID$(ENSkakiera$(finishColumn, finishRank), 1, 1) = MID$(ENSkakiera$(startColumn, startRank), 1, 1) THEN NomimotitaEN = 0 'If the start square is the same as the destination... IF startColumn = finishColumn AND startRank = finishRank THEN NomimotitaEN = 0 END IF ' ------------------------------------ PAWN ------------------------------------ IF (MovingPieceEN$ = "wpawn" OR MovingPieceEN$ = "bpawn") THEN NomimotitaEN = 0 IF MovingPieceEN$ = "wpawn" THEN IF (finishColumn = startColumn) AND (finishRank = startRank + 1) THEN NomimotitaEN = 1 IF (finishColumn = startColumn - 1) AND (finishRank = startRank + 1) THEN IF MID$(ENSkakiera$(finishColumn, finishRank), 1, 1) = "b" THEN NomimotitaEN = 1 END IF IF (finishColumn = startColumn + 1) AND (finishRank = startRank + 1) THEN IF MID$(ENSkakiera$(finishColumn, finishRank), 1, 1) = "b" THEN NomimotitaEN = 1 END IF END IF IF debugMode = 1 THEN PRINT "Pawn - Checkpoint Null: Nomimotita = " + STR$(NomimotitaEN) IF MovingPieceEN$ = "bpawn" THEN IF (finishColumn = startColumn) AND (finishRank = startRank - 1) THEN NomimotitaEN = 1 IF (finishColumn = startColumn - 1) AND (finishRank = startRank - 1) THEN IF MID$(ENSkakiera$(finishColumn, finishRank), 1, 1) = "w" THEN NomimotitaEN = 1 END IF IF (finishColumn = startColumn + 1) AND (finishRank = startRank - 1) THEN IF MID$(ENSkakiera$(finishColumn, finishRank), 1, 1) = "w" THEN NomimotitaEN = 1 END IF END IF 'Moving two squares IF MovingPieceEN$ = "wpawn" AND startRank = 2 AND finishRank = 4 AND startColumn = finishColumn AND ENSkakiera$(startColumn, 3) = "" AND ENSkakiera$(startColumn, 4) = "" THEN NomimotitaEN = 1 IF MovingPieceEN$ = "bpawn" AND startRank = 7 AND finishRank = 5 AND startColumn = finishColumn AND ENSkakiera$(startColumn, 6) = "" AND ENSkakiera$(startColumn, 5) = "" THEN NomimotitaEN = 1 IF debugMode = 1 THEN PRINT "Pawn - Checkpoint 1: Nomimotita = " + STR$(NomimotitaEN) 'En passant not supported 'Promotion not supported 'Check if the piece moves beyond the limits of the chessboard IF ((finishColumn < 1) OR (finishRank < 1)) THEN NomimotitaEN = 0 IF ((finishColumn > 8) OR (finishRank > 8)) THEN NomimotitaEN = 0 'Check if a piece of the same colour is at the destination square IF MID$(ENSkakiera$(finishColumn, finishRank), 1, 1) = MID$(ENSkakiera$(startColumn, startRank), 1, 1) THEN NomimotitaEN = 0 IF debugMode = 1 THEN PRINT "Pawn - Checkpoint 2: Nomimotita = " + STR$(NomimotitaEN) 'Check if a piece of any colour is at the destination square IF (finishColumn <> startColumn) THEN IF MovingPieceEN$ = "wpawn" AND MID$(ENSkakiera$(finishColumn, finishRank), 1, 1) = "w" THEN NomimotitaEN = 0 IF MovingPieceEN$ = "bpawn" AND MID$(ENSkakiera$(finishColumn, finishRank), 1, 1) = "b" THEN NomimotitaEN = 0 END IF IF (finishColumn = startColumn) THEN IF MID$(ENSkakiera$(finishColumn, finishRank), 1, 1) <> "" THEN NomimotitaEN = 0 END IF IF debugMode = 1 THEN PRINT "Pawn - Checkpoint 3: Nomimotita = " + NomimotitaEN$: INPUT a$ 'If the start square is the same as the destination... IF startColumn = finishColumn AND startRank = finishRank THEN NomimotitaEN = 0 END IF IF (debugMode = 1) THEN PRINT "" PRINT "--------------- DEBUG MESSAGE ---------------" PRINT "startColumn = " + STR$(startColumn) PRINT "startRank = " + STR$(startRank) PRINT "finishColumn = " + STR$(finishColumn) PRINT "finishRank = " + STR$(finishRank) PRINT "ENSkakiera$(startColumn, startRank) = " + ENSkakiera$(startColumn, startRank) PRINT "ENSkakiera$(finishColumn, finishRank) = " + ENSkakiera$(finishColumn, finishRank) PRINT "" PRINT "NomimotitaEN = " + STR$(NomimotitaEN) PRINT "--------------- DEBUG MESSAGE ---------------" PRINT "" INPUT a$ END IF Nomimotita = NomimotitaEN END SUB SUB countScore positionScore = 0 FOR I = 1 TO 8 FOR J = 1 TO 8 IF chessboard$(I, J) = "wpawn" THEN positionScore = positionScore + 1 IF chessboard$(I, J) = "wrook" THEN positionScore = positionScore + 5 IF chessboard$(I, J) = "wknight" THEN positionScore = positionScore + 3 IF chessboard$(I, J) = "wbishop" THEN positionScore = positionScore + 3 IF chessboard$(I, J) = "wqueen" THEN positionScore = positionScore + 9 IF chessboard$(I, J) = "wking" THEN positionScore = positionScore + 100 IF chessboard$(I, J) = "bpawn" THEN positionScore = positionScore - 1 IF chessboard$(I, J) = "brook" THEN positionScore = positionScore - 5 IF chessboard$(I, J) = "bknight" THEN positionScore = positionScore - 3 IF chessboard$(I, J) = "bbishop" THEN positionScore = positionScore - 3 IF chessboard$(I, J) = "bqueen" THEN positionScore = positionScore - 9 IF chessboard$(I, J) = "bking" THEN positionScore = positionScore - 100 NEXT J NEXT I IF (debugMode = 1) THEN PRINT "Position Score = " + STR$(positionScore): INPUT A$ END SUB SUB HumanMove1 (HM1Skakiera() AS STRING) 'Scan the chessboard... FOR I = 1 TO 8 FOR J = 1 TO 8 'If you find a piece of the human... IF ((MID$(HM1Skakiera$(I, J), 1, 1) = "w" AND playerColor$ = "w") OR (MID$(HM1Skakiera$(I, J), 1, 1) = "b" AND playerColor$ = "b")) THEN IF debugMode = 1 THEN PRINT "Inside Human level 1 move - Checkpoint A" 'Scan all possible destination squares... FOR ii = 1 TO 8 FOR jj = 1 TO 8 startingColumnHM1 = I startingRankHM1 = J finishingColumnHM1 = ii finishingRankHM1 = jj MovingPieceHM1$ = HM1Skakiera$(I, J) ProsorinoKommatiHM1$ = HM1Skakiera$(ii, jj) 'Check legality of the move entered CALL ElegxosNomimotitas(HM1Skakiera$(), 0, startingColumnHM1, startingRankHM1, finishingColumnHM1, finishingRankHM1, MovingPieceHM1$) IF debugMode = 1 THEN PRINT "" PRINT "NEW MOVE ANALYZED: " + STR$(startingColumnHM1) + STR$(startingRankHM1) + " -> " + STR$(finishingColumnHM1) + STR$(finishingRankHM1) PRINT "Legality of the move analyzed: " + STR$(Nomimotita) END IF 'If move is legal, then do the move and present it in the chessbooard IF Nomimotita = 1 THEN 'Do the move HM1Skakiera$(finishingColumnHM1, finishingRankHM1) = HM1Skakiera$(startingColumnHM1, startingRankHM1) HM1Skakiera$(startingColumnHM1, startingRankHM1) = "" CALL ComputerMove2(HM1Skakiera$()) END IF 'Undo the move HM1Skakiera$(startingColumnHM1, startingRankHM1) = MovingPieceHM1$ HM1Skakiera$(finishingColumnHM1, finishingRankHM1) = ProsorinoKommatiHM1$ NEXT jj NEXT ii END IF NEXT J NEXT I END SUB SUB ComputerMove2 (CM2Skakiera() AS STRING) 'Scan the chessboard... FOR I = 1 TO 8 FOR J = 1 TO 8 'If you find a piece of the computer... IF ((MID$(CM2Skakiera$(I, J), 1, 1) = "w" AND playerColor$ = "b") OR (MID$(CM2Skakiera$(I, J), 1, 1) = "b" AND playerColor$ = "w")) THEN IF debugMode = 1 THEN PRINT "Inside Computer level 2 move - Checkpoint A" 'Scan all possible destination squares... FOR ii = 1 TO 8 FOR jj = 1 TO 8 startingColumnCM2 = I startingRankCM2 = J finishingColumnCM2 = ii finishingRankCM2 = jj MovingPieceCM2$ = CM2Skakiera$(I, J) ProsorinoKommatiCM2$ = CM2Skakiera$(ii, jj) 'Check legality of the move entered CALL ElegxosNomimotitas(CM2Skakiera$(), 0, startingColumnCM2, startingRankCM2, finishingColumnCM2, finishingRankCM2, MovingPieceCM2$) IF debugMode = 1 THEN PRINT "" PRINT "NEW MOVE ANALYZED: " + STR$(startingColumnCM2) + STR$(startingRankCM2) + " -> " + STR$(finishingColumnCM2) + STR$(finishingRankCM2) PRINT "Legality of the move analyzed: " + STR$(Nomimotita) END IF 'If move is legal, then do the move and present it in the chessbooard IF Nomimotita = 1 THEN 'Do the move CM2Skakiera$(finishingColumnCM2, finishingRankCM2) = CM2Skakiera$(startingColumnCM2, startingRankCM2) CM2Skakiera$(startingColumnCM2, startingRankCM2) = "" 'Count the score of the move CALL countScore 'If the score is better than the existing best score, then this is the best move now (and the best score) IF ((playerColor$ = "b" AND positionScore >= bestPositionScore) OR (playerColor$ = "w" AND positionScore <= bestPositionScore)) THEN bestStartingRank = startingRank bestStartingColumn = startingColumn bestFinishingRank = finishingRank bestFinishingColumn = finishingColumn bestPositionScore = positionScore END IF END IF 'Undo the move CM2Skakiera$(startingColumnCM2, startingRankCM2) = MovingPieceCM2$ CM2Skakiera$(finishingColumnCM2, finishingRankCM2) = ProsorinoKommatiCM2$ NEXT jj NEXT ii END IF NEXT J NEXT I END SUB