fb:porticula NoPaste
Chess HUOC_V06b_portFB
Uploader: | grindstone |
Datum/Zeit: | 10.01.2021 20:31:24 |
'HUOC: Huo Chess by Spiros I. Kakos (huo) - DRAFT VERSION (NOT FULLY TESTED, STILL IN PROGRESS)
'Version 0.2: Thinking in 3 half-moves depth
'Version 0.3: Thinking in 3 half-moves depth with MinMax algorithm
'Version 0.4: Thinking up to 5 half-moves depth
'Version 0.5: Improved score function
'Version 0.6: Added opening functionality
'Based on the Huo Chess implementation in C++ and C#
'Check "Huo Chess" in C# at Harmonia Philosophica for code in C# and relative tutorials
'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 [FIXED: 2020-08-06 - Not included in computer thought!]
'2. Castling [FIXED only for human player: 2020-08-04 - Not included in computer thought!]
'3. Pawn promotion [FIXED only for queen promotion: 2020-08-04 - Not included in computer thought!]
'4. Check [FIXED: 2020-08-05 - Not included in computer thought!]
'5. Mate [FIXED: 2020-08-05 - Not included in computer thought!]
'6. Inform user he has entered an invalid move [FIXED: 2020-08-06]
#Include "vbcompat.bi"
DECLARE SUB movValidation (aline AS INTEGER, fline AS INTEGER, arcol AS INTEGER, telcol AS INTEGER)
DECLARE SUB drawBoard ()
DECLARE SUB ElegxosNomimotitas(ENSkakiera() AS STRING, _
checkForDanger AS INTEGER, _
startColumn AS INTEGER, _
startRank AS INTEGER, _
finishColumn AS INTEGER, _
finishRank AS INTEGER, _
MovingPieceEN AS STRING)
Declare SUB initialPosition
Declare SUB PlayerMove
Declare SUB computerMove
Declare SUB checkBlackCheck(chessboard() As String)
Declare SUB checkWhiteCheck(chessboard() As String)
Declare SUB Castling
Declare SUB PawnPromotion
Declare SUB countScore
Declare SUB MinMax
Declare SUB HumanMove1(HM1Skakiera() AS STRING)
Declare SUB ComputerMove2(CM2Skakiera() AS STRING)
Declare SUB HumanMove3 (HM3Skakiera() AS STRING)
Declare SUB ComputerMove4 (CM4Skakiera() AS STRING)
'DEFINT A-Z
'OPTION BASE 1 'Make tables dimensions start from 1
DIM SHARED As string chessboard(1 To 8, 1 To 8)
COMMON SHARED As string playerColor
COMMON SHARED As Integer startingRank, startingColumn
COMMON SHARED As Integer finishingRank, finishingColumn
COMMON SHARED As string startingRankText, startingColumnText
COMMON SHARED As string finishingRankText, finishingColumnText
COMMON SHARED As string Move
COMMON SHARED As string MovingPiece
COMMON SHARED As string ProsorinoKommati
COMMON SHARED As Integer Nomimotita
COMMON SHARED As Integer debugMode
COMMON SHARED As Integer positionScore
COMMON SHARED As Integer bestStartingRank, bestStartingColumn
COMMON SHARED As Integer bestFinishingRank, bestFinishingColumn
COMMON SHARED As Integer bestPositionScore
COMMON SHARED As string whoPlays
COMMON SHARED As string computerLogs, humanLogs
COMMON SHARED As Integer MoveNumber
'Castling
COMMON SHARED As Integer whiteCastling
COMMON SHARED As Integer whiteBigCastling
COMMON SHARED As Integer whiteSmallCastling
COMMON SHARED As Integer blackCastling
COMMON SHARED As Integer blackBigCastling
COMMON SHARED As Integer blackSmallCastling
'Check variables
COMMON SHARED As Integer whiteCheck
COMMON SHARED As Integer blackCheck
'En passant
COMMON SHARED As Integer enPassantColumn
COMMON SHARED As Integer enPassantRank
COMMON SHARED As Integer enPassantHappened
'COMMON SHARED enPassantTest
'MinMax
'Important note: All dimensions in the tables are +1 compared to the Huo Chess in C#! (tables start from 1 here)
COMMON SHARED As Integer foundMove
DIM SHARED As Integer NodesAnalysis0(1 To 1000000, 1 To 6)
DIM SHARED As Integer NodesAnalysis1(1 To 1000000, 1 To 2)
DIM SHARED As Integer NodesAnalysis2(1 To 1000000, 1 To 2)
DIM SHARED NodesAnalysis3(1 To 10000000, 1 To 2) AS LONG
DIM SHARED NodesAnalysis4(1 To 10000000, 1 To 2) AS LONG
COMMON SHARED NodeLevel_0_count AS LONG
COMMON SHARED NodeLevel_1_count AS LONG
COMMON SHARED NodeLevel_2_count AS LONG
COMMON SHARED NodeLevel_3_count AS LONG
COMMON SHARED NodeLevel_4_count AS LONG
COMMON SHARED parentNodeAnalyzed AS LONG
DIM SHARED As Integer bestNodes0(1 To 10000000)
DIM SHARED As Integer bestNodes1(1 To 10000000)
DIM SHARED As Integer bestNodes2(1 To 10000000)
DIM SHARED As Integer bestNodes3(1 To 10000000)
DIM SHARED As Integer bestNodes4(1 To 10000000)
COMMON SHARED As Integer bestNode2, bestNode1, bestNode0
COMMON SHARED counter0 AS LONG
COMMON SHARED counter1 AS LONG
COMMON SHARED counter2 AS LONG
COMMON SHARED counter3 AS LONG
COMMON SHARED counter4 AS LONG
COMMON SHARED As String huologs, logLine, humanLog, positionFile, newLine, openingFile
COMMON SHARED As Integer thinkingDepth
COMMON SHARED As Integer iMove, FileNum, foundOpening, verifyPosition, i, j, ii, jj, finishColumn
COMMON SHARED As Integer finishRank
'Set debugMode = 1 if you want debugging messages to appear, else set to 0
debugMode = 0
PRINT "Huo Chess - HUOC v0.6 by Spiros Kakos (2020)"
PRINT ""
PRINT "The best open source chess in BASIC for educational purposes"
PRINT "Check HUO CHESS in C# at Harmonia Philosophica as well!"
PRINT ""
PRINT "How to play: Enter move coordinates without spaces (e.g. c2c4) and press Enter"
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 or 5: ", thinkingDepth
IF thinkingDepth <> 1 AND thinkingDepth <> 3 AND thinkingDepth <> 5 THEN GOTO SetThinkingDepth
PRINT ""
computerLogs:
INPUT "Activate debug messages for computer? (y/n) ", computerLogs: IF computerLogs <> "y" AND computerLogs <> "n" THEN GOTO computerLogs
humanLogs:
INPUT "Activate debug messages for the human? (y/n) ", humanLog: IF humanLog <> "y" AND humanLog <> "n" THEN GOTO humanLogs
CLS
initialPosition
drawBoard
'Initialize variables
MoveNumber = 0
'Check variables
whiteCheck = 0
blackCheck = 0
'Castling
whiteCastling = 0
blackCastling = 0
whiteBigCastling = 0
whiteSmallCastling = 0
blackBigCastling = 0
blackSmallCastling = 0
'En Passant
'enPassantTest = 0
enPassantHappened = 0
'Set thinking depth
'thinkingDepth = 3
LOCATE 12, 1: PRINT "Huo Chess - HUOC"
IF playerColor = "w" THEN
whoPlays = "Human"
PlayerMove
END IF
IF playerColor = "b" THEN
whoPlays = "HY"
LOCATE 13, 1: PRINT "Thinking..."
computerMove
END IF
SUB PlayerMove
'Initialize variables
'Check
whiteCheck = 0
blackCheck = 0
'En Passant
enPassantHappened = 0
'Check the Check
IF playerColor = "b" Then checkBlackCheck(chessboard())
IF playerColor = "w" THEN checkWhiteCheck(chessboard())
'PRINT "PlayerMove: blackCheck = " + STR(blackCheck): INPUT aa
IF whiteCheck = 1 OR blackCheck = 1 THEN LOCATE 12, 1: PRINT "Check! ": LOCATE 13, 1: PRINT "Press Enter": DO: LOOP UNTIL INKEY <> "": LOCATE 12, 1: PRINT " ": LOCATE 13, 1: PRINT " "
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)
ProsorinoKommati = chessboard(finishingColumn, finishingRank)
IF (debugMode = 1) THEN
PRINT "[Move: " + STR(startingColumn) + STR(startingRank) + " -> " + STR(finishingColumn) + Str(finishingRank) + " ]"
END IF
'Check legality of the move entered
'ElegxosNomimotitas(chessboard(), 0, startingColumn, startingRank, finishingColumn, finishingRank, MovingPiece)
ElegxosNomimotitas(chessboard(), 0, startingColumn, startingRank, finishingColumn, finishingRank, MovingPiece)
' ------------------ Check the Check! START ------------------
'Temporarily do the move
chessboard(finishingColumn, finishingRank) = chessboard(startingColumn, startingRank)
chessboard(startingColumn, startingRank) = ""
'Check the check
IF playerColor = "b" AND Nomimotita = 1 THEN
whoPlays = "HY"
checkBlackCheck(chessboard())
'Restore Nomimotita! (because it is 'broken' in the checkCheck function
Nomimotita = 1
IF blackCheck = 1 THEN Nomimotita = 0
whoPlays = "Human"
END IF
IF playerColor = "w" AND Nomimotita = 1 THEN
whoPlays = "HY"
checkWhiteCheck(chessboard())
'Restore Nomimotita! (because it is 'broken' in the checkCheck function
Nomimotita = 1
IF whiteCheck = 1 THEN Nomimotita = 0
whoPlays = "Human"
END IF
'Undo the move
chessboard(startingColumn, startingRank) = MovingPiece
chessboard(finishingColumn, finishingRank) = ProsorinoKommati
' ------------------ Check the Check! END ------------------
'Castling
IF (playerColor = "w" AND whiteCastling = 0) OR (playerColor = "b" AND blackCastling = 0) THEN Castling
IF playerColor = "w" AND whiteCastling = 1 THEN Nomimotita = 1
IF playerColor = "b" AND blackCastling = 1 THEN Nomimotita = 1
'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) = ""
'Castling
IF playerColor = "w" AND whiteBigCastling = 1 THEN chessboard(4, 1) = "wrook": chessboard(1, 1) = ""
IF playerColor = "w" AND whiteSmallCastling = 1 THEN chessboard(6, 1) = "wrook": chessboard(8, 1) = ""
IF playerColor = "b" AND blackBigCastling = 1 THEN chessboard(4, 8) = "brook": chessboard(1, 8) = ""
IF playerColor = "b" AND blackSmallCastling = 1 THEN chessboard(6, 8) = "brook": chessboard(8, 8) = ""
'Check for pawn promotion
PawnPromotion
'En passant happened?
IF enPassantHappened = 1 THEN
IF enPassantRank = 3 THEN chessboard(finishingColumn, 4) = ""
IF enPassantRank = 6 THEN chessboard(finishingColumn, 5) = ""
END IF
'En passant possible?
enPassantColumn = 0
enPassantRank = 0
IF startingColumn = finishingColumn AND startingRank = 2 AND finishingRank = 4 AND MovingPiece = "wpawn" THEN
enPassantColumn = finishingColumn
enPassantRank = 3
ELSEIF startingColumn = finishingColumn AND startingRank = 7 AND finishingRank = 5 AND MovingPiece = "bpawn" THEN
enPassantColumn = finishingColumn
enPassantRank = 6
END IF
CLS
drawBoard
'Increase move number of the game
IF playerColor = "w" THEN MoveNumber = MoveNumber + 1
'Time for the computer to think now...
LOCATE 12, 1: PRINT "Huo Chess - HUOC"
LOCATE 13, 1: PRINT "Thinking..."
whoPlays = "HY"
computerMove
ELSE
LOCATE 12, 1: PRINT "Invalid move - Please try again"
LOCATE 13, 1: PRINT "Press any key to continue"
DO: LOOP UNTIL InKey <> ""
LOCATE 12, 1: PRINT " "
LOCATE 13, 1: PRINT " "
LOCATE 12, 1: PRINT "Huo Chess - HUOC"
PlayerMove
END IF
END SUB
SUB computerMove
'Initialize variables
iMove = 1
bestPositionScore = 0
bestStartingRank = 0
bestStartingColumn = 0
bestFinishingRank = 0
bestFinishingColumn = 0
IF playerColor = "w" THEN bestPositionScore = 999
IF playerColor = "b" THEN bestPositionScore = -999
'MinMax
foundMove = 0
NodeLevel_0_count = 1
NodeLevel_1_count = 1
NodeLevel_2_count = 1
NodeLevel_3_count = 1
NodeLevel_4_count = 1
'Check
whiteCheck = 0
blackCheck = 0
'En Passant
enPassantHappened = 0
'Check the Check
IF playerColor = "b" THEN checkWhiteCheck(chessboard())
IF playerColor = "w" THEN checkBlackCheck(chessboard())
'PRINT "PlayerMove: blackCheck = " + STR(blackCheck): INPUT aa
IF whiteCheck = 1 OR blackCheck = 1 THEN LOCATE 12, 1: PRINT "Check! ": LOCATE 13, 1: PRINT "Press Enter": DO: LOOP UNTIL InKey <> "": LOCATE 12, 1: PRINT " ": LOCATE 13, 1: PRINT " "
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)
' ------------------- OPENING (start) -------------------
'Search for the position
FileNum = 0
positionFile = ""
foundOpening = 0
newLine = ""
DO
FileNum = FileNum + 1
openingFile = "Opening" + LTRIM(Str(FileNum)) + ".txt"
IF FILEEXISTS(openingFile) THEN
verifyPosition = 1
CLOSE #4
OPEN openingFile FOR INPUT AS #4
FOR i = 1 TO 8
FOR j = 1 TO 8
LINE INPUT #4, newLine
IF CHR(34) + chessboard(i, j) + CHR(34) <> newLine THEN verifyPosition = 0
NEXT j
NEXT i
'If position is found, store the file and read the suggested move!
IF verifyPosition = 1 THEN
positionFile = openingFile
foundOpening = 1
'Read Suggested Move line
LINE INPUT #4, newLine
'Read the coordinates of the suggested move
LINE INPUT #4, newLine
bestStartingColumn = VAL(newLine)
LINE INPUT #4, newLine
bestStartingRank = VAL(newLine)
LINE INPUT #4, newLine
bestFinishingColumn = VAL(newLine)
LINE INPUT #4, newLine
bestFinishingRank = VAL(newLine)
END IF
ELSE
positionFile = "Not found"
END IF
LOOP WHILE positionFile = ""
IF foundOpening = 1 THEN
'PRINT "Found position in file: " + positionFile
'PRINT "Suggested move: " + STR(openingStartColumn) + STR(openingStartRank) + " -> " + STR(openingFinishColumn) + STR(openingFinishRank)
'INPUT H
GOTO bestMoveSection
END IF
' ------------------- OPENING (end) -------------------
'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
ElegxosNomimotitas(chessboard(), 0, startingColumn, startingRank, finishingColumn, finishingRank, MovingPiece)
' ------------------ Check the Check! START ------------------
'Temporarily do the move
chessboard(finishingColumn, finishingRank) = chessboard(startingColumn, startingRank)
chessboard(startingColumn, startingRank) = ""
'Trela = 0
'IF Nomimotita = 1 THEN PRINT "Check A: whiteCheck = " + STR(whiteCheck) + " , Nomimotita = " + STR(Nomimotita): Trela = 1: INPUT A
'Check the check
IF playerColor = "b" AND Nomimotita = 1 THEN
whoPlays = "Human"
checkWhiteCheck(chessboard())
'Restore Nomimotita! (because it is 'broken' in the checkCheck function
Nomimotita = 1
IF whiteCheck = 1 THEN Nomimotita = 0
'IF Trela = 1 THEN PRINT "Check B: whiteCheck = " + STR(whiteCheck) + " , Nomimotita = " + STR(Nomimotita): INPUT A
whoPlays = "HY"
END IF
IF playerColor = "w" AND Nomimotita = 1 THEN
whoPlays = "Human"
checkBlackCheck(chessboard())
'Restore Nomimotita! (because it is 'broken' in the checkCheck function
Nomimotita = 1
IF blackCheck = 1 THEN Nomimotita = 0
whoPlays = "HY"
END IF
'Undo the move
chessboard(startingColumn, startingRank) = MovingPiece
chessboard(finishingColumn, finishingRank) = ProsorinoKommati
' ------------------ Check the Check! END ------------------
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
'-------------- MinMax --------------
'Important note: All dimensions in the tables are +1 compared to the Huo Chess in C#! (tables start from 1 here)
NodesAnalysis0(NodeLevel_0_count, 3) = startingColumn
NodesAnalysis0(NodeLevel_0_count, 4) = finishingColumn
NodesAnalysis0(NodeLevel_0_count, 5) = startingRank
NodesAnalysis0(NodeLevel_0_count, 6) = finishingRank
'If first move found, then store it (This is useless)
IF foundMove = 0 THEN
'NodesAnalysis0(NodeLevel_0_count, 3) = startingColumn
'NodesAnalysis0(NodeLevel_0_count, 4) = finishingColumn
'NodesAnalysis0(NodeLevel_0_count, 5) = startingRank
'NodesAnalysis0(NodeLevel_0_count, 6) = finishingRank
'PRINT "startingColumn = " + STR(startingColumn)
'PRINT "finishingColumn = " + STR(finishingColumn)
'PRINT "startingRank = " + STR(startingRank)
'PRINT "finishingRank = " + STR(finishingRank)
'INPUT A
foundMove = 1
END IF
'Do the move
chessboard(finishingColumn, finishingRank) = chessboard(startingColumn, startingRank)
chessboard(startingColumn, startingRank) = ""
'Count the score of the move
countScore
'-------------- MinMax --------------
'Store scores
NodesAnalysis0(NodeLevel_0_count, 1) = positionScore
' Store parents
NodesAnalysis0(NodeLevel_0_count, 2) = 0
IF iMove = 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 iMove < thinkingDepth THEN
iMove = iMove + 1
HumanMove1(chessboard())
END IF
'Undo the move
chessboard(startingColumn, startingRank) = MovingPiece
chessboard(finishingColumn, finishingRank) = ProsorinoKommati
'-------------- MinMax --------------
'Increase node count
NodeLevel_0_count = NodeLevel_0_count + 1
END IF
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
'-------------- MinMax --------------
MinMax
'No move found? Then resign! Else, make the move!
IF bestFinishingColumn = 0 THEN
LOCATE 12, 1: PRINT "I resign! "
ELSE
'En passant test
'IF enPassantTest = 0 THEN
' bestStartingColumn = 5: bestStartingRank = 2
' bestFinishingColumn = 5: bestFinishingRank = 4
' enPassantTest = 1
'END IF
bestMoveSection:
'Do the best move found
chessboard(bestFinishingColumn, bestFinishingRank) = chessboard(bestStartingColumn, bestStartingRank)
chessboard(bestStartingColumn, bestStartingRank) = ""
'Check for pawn promotion
PawnPromotion
'En passant happened?
IF (finishColumn = enPassantColumn) AND (finishRank = enPassantRank) THEN enPassantHappened = 1 ELSE enPassantHappened = 0
'En passant happened?
IF enPassantHappened = 1 THEN
IF enPassantRank = 3 THEN chessboard(finishingColumn, 4) = ""
IF enPassantRank = 6 THEN chessboard(finishingColumn, 5) = ""
END IF
'En passant possible?
enPassantColumn = 0
enPassantRank = 0
IF bestStartingColumn = bestFinishingColumn AND bestStartingRank = 2 AND bestFinishingRank = 4 AND chessboard(bestFinishingColumn, bestFinishingRank) = "wpawn" THEN
enPassantColumn = bestFinishingColumn
enPassantRank = 3
ELSEIF bestStartingColumn = bestFinishingColumn AND bestStartingRank = 7 AND bestFinishingRank = 5 AND chessboard(bestFinishingColumn, bestFinishingRank) = "bpawn" THEN
enPassantColumn = bestFinishingColumn
enPassantRank = 6
END IF
CLS
drawBoard
'Increase move number of the game
IF playerColor = "b" THEN MoveNumber = MoveNumber + 1
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"
PlayerMove
END IF
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"
'---------- CASTLING TEST ----------
'chessboard(1, 1) = "wrook": chessboard(1, 2) = "wpawn"
'chessboard(3, 3) = "wknight": chessboard(2, 2) = "wpawn"
'chessboard(6, 4) = "wbishop": chessboard(3, 2) = "wpawn"
'chessboard(4, 2) = "wqueen": chessboard(4, 3) = "wpawn"
'chessboard(5, 1) = "wking": chessboard(5, 5) = "wpawn"
'chessboard(3, 4) = "wbishop": chessboard(6, 2) = "wpawn"
'chessboard(6, 3) = "wknight": chessboard(7, 2) = "wpawn"
'chessboard(8, 1) = "wrook": chessboard(8, 2) = "wpawn"
'chessboard(1, 7) = "bpawn": chessboard(1, 8) = "brook"
'chessboard(2, 6) = "bpawn": chessboard(3, 6) = "bknight"
'chessboard(3, 7) = "bpawn": chessboard(1, 4) = "bbishop"
'chessboard(4, 5) = "bpawn": chessboard(4, 7) = "bqueen"
'chessboard(5, 6) = "bpawn": chessboard(5, 8) = "bking"
'chessboard(6, 7) = "bpawn": chessboard(5, 7) = "bbishop"
'chessboard(7, 7) = "bpawn": chessboard(8, 6) = "bknight"
'chessboard(8, 7) = "bpawn": chessboard(8, 8) = "brook"
'---------- CHECK TEST ----------
'chessboard(1, 1) = "wrook": chessboard(1, 2) = "wpawn"
'chessboard(2, 5) = "wknight": chessboard(2, 2) = "wpawn"
'chessboard(6, 4) = "wbishop": chessboard(3, 2) = "wpawn"
'chessboard(4, 2) = "wqueen": chessboard(4, 3) = "wpawn"
'chessboard(5, 1) = "wking": chessboard(5, 5) = "wpawn"
'chessboard(3, 4) = "wbishop": chessboard(6, 2) = "wpawn"
'chessboard(6, 3) = "wknight": chessboard(7, 2) = "wpawn"
'chessboard(8, 1) = "wrook": chessboard(8, 2) = "wpawn"
'chessboard(1, 7) = "bpawn": chessboard(1, 8) = "brook"
'chessboard(2, 6) = "bpawn": chessboard(3, 6) = "bknight"
'chessboard(3, 7) = "bpawn": chessboard(1, 4) = "bbishop"
'chessboard(4, 5) = "bpawn": chessboard(4, 7) = "bqueen"
'chessboard(5, 6) = "bpawn": chessboard(5, 8) = "bking"
'chessboard(6, 7) = "bpawn": chessboard(5, 7) = "bbishop"
'chessboard(7, 7) = "bpawn": chessboard(8, 4) = "bknight"
'chessboard(8, 7) = "bpawn": chessboard(8, 8) = "brook"
'---------- EN PASSANT TEST ----------
'chessboard(1, 1) = "wrook": chessboard(1, 2) = "wpawn"
'chessboard(2, 1) = "wknight": chessboard(2, 2) = "wpawn"
'chessboard(3, 1) = "wbishop": chessboard(3, 4) = "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, 5) = "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, 4) = "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, 5) = "bpawn": chessboard(8, 8) = "brook"
END SUB
' -------------------------------------------------------------------------------------------------------
SUB drawBoard
Dim As String sqcolor = "" 'Square color
Dim As String piece = "" 'Piece to be printed
Dim As Integer pfcolor = 0 'Piece front color
Dim As Integer pbcolor = 1 'Piece back color
Dim As String MT = Chr(219)
Dim As String 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 As String ProsorinoKommatiEN, a
DIM NomimotitaEN As Integer
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 MovingPieceEN = "wbishop" AND startColumn = 2 AND startRank = 4 AND finishColumn = 5 AND finishRank = 7 THEN
' PRINT "Checkpoint 1 - Nomimotita = " + STR(NomimotitaEN)
' INPUT C
'END IF
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 MovingPieceEN = "wbishop" AND startColumn = 2 AND startRank = 4 AND finishColumn = 5 AND finishRank = 7 THEN
' PRINT "Checkpoint 2 - Nomimotita = " + STR(NomimotitaEN)
' INPUT C
'END IF
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
'IF MovingPieceEN = "wbishop" AND startColumn = 2 AND startRank = 4 AND finishColumn = 5 AND finishRank = 7 THEN
' PRINT "Checkpoint 3 - Nomimotita = " + STR(NomimotitaEN)
' INPUT C
'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
'IF MovingPieceEN = "wbishop" AND startColumn = 2 AND startRank = 4 AND finishColumn = 5 AND finishRank = 7 THEN
' PRINT "Checkpoint 3.0 - Nomimotita = " + STR(NomimotitaEN) + " (i = " + STR(I) + ")"
' INPUT C
'END IF
END IF
NEXT I
END IF
'IF MovingPieceEN = "wbishop" AND startColumn = 2 AND startRank = 4 AND finishColumn = 5 AND finishRank = 7 THEN
' PRINT "Checkpoint 3.1 - Nomimotita = " + STR(NomimotitaEN)
' INPUT C
'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 MovingPieceEN = "wbishop" AND startColumn = 2 AND startRank = 4 AND finishColumn = 5 AND finishRank = 7 THEN
' PRINT "Checkpoint 4 - Nomimotita = " + STR(NomimotitaEN)
' INPUT C
'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 MovingPieceEN = "wbishop" AND startColumn = 2 AND startRank = 4 AND finishColumn = 5 AND finishRank = 7 THEN
' PRINT "Checkpoint 5 - Nomimotita = " + STR(NomimotitaEN)
' INPUT C
'END IF
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
'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
'En Passant
IF finishColumn = enPassantColumn AND finishRank = enPassantRank 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
'En Passant
IF finishColumn = enPassantColumn AND finishRank = enPassantRank 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
'En Passant
IF finishColumn = enPassantColumn AND finishRank = enPassantRank 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
'En Passant
IF finishColumn = enPassantColumn AND finishRank = enPassantRank 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)
'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 = " + Str(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
'v0.5: Multipled all scores by 10-factor (e.g. score of a bishop is now 30 instead of 3), so that I can include additional checks for the position score.
' Without doing that I could not add the quality checks I added, e.g. the IF chessboard(4, 4) = "wpawn" THEN positionScore = positionScore + 0.1.
' Now the additional score checks can be added with integers, e.g. IF chessboard(4, 4) = "wpawn" THEN positionScore = positionScore + 1 for the above example.
' If I wanted to do what using decimals, then all positionScore, bestPositionScore, NodesAnalysis0... NodesAnalysis4 variables and arrays should de defined as DOUBLE, but then we would have memory problems...
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
IF chessboard(I, J) = "wpawn" THEN positionScore = positionScore + 10
IF chessboard(I, J) = "wrook" THEN positionScore = positionScore + 50
IF chessboard(I, J) = "wknight" THEN positionScore = positionScore + 30
IF chessboard(I, J) = "wbishop" THEN positionScore = positionScore + 30
IF chessboard(I, J) = "wqueen" THEN positionScore = positionScore + 90
IF chessboard(I, J) = "wking" THEN positionScore = positionScore + 150
IF chessboard(I, J) = "bpawn" THEN positionScore = positionScore - 10
IF chessboard(I, J) = "brook" THEN positionScore = positionScore - 50
IF chessboard(I, J) = "bknight" THEN positionScore = positionScore - 30
IF chessboard(I, J) = "bbishop" THEN positionScore = positionScore - 30
IF chessboard(I, J) = "bqueen" THEN positionScore = positionScore - 90
IF chessboard(I, J) = "bking" THEN positionScore = positionScore - 150
NEXT J
NEXT I
'Check position quality
'Take the center
IF chessboard(4, 4) = "wpawn" THEN positionScore = positionScore + 1
IF chessboard(5, 4) = "wpawn" THEN positionScore = positionScore + 1
IF chessboard(4, 5) = "bpawn" THEN positionScore = positionScore - 1
IF chessboard(5, 5) = "bpawn" THEN positionScore = positionScore - 1
'In the opening, avoid stupid moves
'White
IF MoveNumber < 10 THEN
'Do not move the rook
IF chessboard(1, 1) = "" THEN positionScore = positionScore - 1
IF chessboard(8, 1) = "" THEN positionScore = positionScore - 1
'Do not move the knights at the edges
IF chessboard(1, 3) = "wknight" THEN positionScore = positionScore - 1
IF chessboard(8, 3) = "wknight" THEN positionScore = positionScore - 1
'Do not move the queen
IF chessboard(4, 1) = "" THEN positionScore = positionScore - 1
'Do not move the king
IF chessboard(5, 1) = "" THEN positionScore = positionScore - 1
'Don't do stupid moves with pawns
IF chessboard(1, 4) = "wpawn" THEN positionScore = positionScore - 1
IF chessboard(8, 4) = "wpawn" THEN positionScore = positionScore - 1
END IF
'Black
IF MoveNumber < 10 THEN
'Do not move the rook
IF chessboard(1, 8) = "" THEN positionScore = positionScore + 1
IF chessboard(8, 8) = "" THEN positionScore = positionScore + 1
'Do not move the knights at the edges
IF chessboard(1, 6) = "bknight" THEN positionScore = positionScore + 1
IF chessboard(8, 6) = "bknight" THEN positionScore = positionScore + 1
'Do not move the queen
IF chessboard(4, 8) = "" THEN positionScore = positionScore + 1
'Do not move the king
IF chessboard(5, 8) = "" THEN positionScore = positionScore + 1
'Don't do stupid moves with pawns
IF chessboard(1, 5) = "bpawn" THEN positionScore = positionScore + 1
IF chessboard(8, 5) = "bpawn" THEN positionScore = positionScore + 1
END IF
IF (debugMode = 1) THEN PRINT "Position Score = " + Str(positionScore)
END SUB
SUB HumanMove1 (HM1Skakiera() AS STRING)
Dim As Integer startingColumnHM1, startingRankHM1, finishingColumnHM1, finishingRankHM1
Dim As String MovingPieceHM1, ProsorinoKommatiHM1
'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
whoPlays = "Human"
ElegxosNomimotitas(HM1Skakiera(), 0, startingColumnHM1, startingRankHM1, finishingColumnHM1, finishingRankHM1, MovingPieceHM1)
whoPlays = "HY"
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) = ""
'Count the score of the move
countScore
'-------------- MinMax --------------
'Store scores
NodesAnalysis1(NodeLevel_1_count, 1) = positionScore
' Store parents
NodesAnalysis1(NodeLevel_1_count, 2) = NodeLevel_0_count
IF iMove < thinkingDepth THEN
iMove = iMove + 1
ComputerMove2(HM1Skakiera())
END IF
'Undo the move
HM1Skakiera(startingColumnHM1, startingRankHM1) = MovingPieceHM1
HM1Skakiera(finishingColumnHM1, finishingRankHM1) = ProsorinoKommatiHM1
'-------------- MinMax --------------
'Increase node count
NodeLevel_1_count = NodeLevel_1_count + 1
END IF
NEXT jj
NEXT ii
END IF
NEXT J
NEXT I
'Reduce the move
iMove = iMove - 1
END SUB
SUB ComputerMove2 (CM2Skakiera() AS STRING)
DIM bestMove2score AS INTEGER
Dim As Integer startingColumnCM2, startingRankCM2, finishingColumnCM2, finishingRankCM2
Dim As String MovingPieceCM2, ProsorinoKommatiCM2
bestMove2score = 0
'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
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
countScore
'PRINT "NodeLevel_2_count = " + STR(NodeLevel_2_count)
'-------------- MinMax --------------
'Store scores
NodesAnalysis2(NodeLevel_2_count, 1) = positionScore
' Store parents
NodesAnalysis2(NodeLevel_2_count, 2) = NodeLevel_1_count
'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
'Call next level
'IF Move < thinkingDepth AND ProsorinoKommatiCM2 <> "" THEN
'IF Move < thinkingDepth THEN
IF iMove < thinkingDepth AND ((playerColor = "b" AND positionScore > bestMove2score) OR (playerColor = "w" AND positionScore < bestMove2score)) THEN
iMove = iMove + 1
bestMove2score = positionScore
HumanMove3(CM2Skakiera())
END IF
'Undo the move
CM2Skakiera(startingColumnCM2, startingRankCM2) = MovingPieceCM2
CM2Skakiera(finishingColumnCM2, finishingRankCM2) = ProsorinoKommatiCM2
'-------------- MinMax --------------
'Increase node count
NodeLevel_2_count = NodeLevel_2_count + 1
END IF
NEXT jj
NEXT ii
END IF
NEXT J
NEXT I
'Reduce the move
iMove = iMove - 1
END SUB
'-------------- MinMax --------------
SUB MinMax ()
' -------------------------------------------------------------------------------
' DO THE BEST MOVE FOUND
' Analyze only if possibility to eat back is not true!!!
' MessageBox.Show("Entered Best Move found area!")
' v0.990: Added the possibility_to_eat
' v0.991: Removed possibility to eat! Why not think everything?
' v0.991: Added the opening book check
' if ((possibility_to_eat_back = false) AND (possibility_to_eat = false))
' -------------------------------------------------------------------------------
' [MiniMax algorithm - skakos]
' MessageBox.Show("Entered checkpoint 1")
' Find node 1 move with the best score via the MiniMax algorithm.
' v0.980: Remove unsued counters.
' v0.990: Move 4 changes
' v0.991: Added counter4 again (needed if Thinking_Depth = 4)
Dim As Integer bestNode4, bestNode3, temp_score
counter0 = 1
counter1 = 1
counter2 = 1
counter3 = 1
counter4 = 1
' -------------------------------------------------------------------
' NodesAnalysis
' -------------------------------------------------------------------
' Nodes structure...
' [ccc, xxx, 1]: Score of node No. ccc at level xxx
' [ccc, xxx, 2]: Parent of node No. ccc at level xxx-1
' -------------------------------------------------------------------
' ------- LOG: Nodes before (start) -------
'Log not available in this edition - Check the graphics edition!
' ------- LOG: Nodes before (end) -------
IF thinkingDepth = 5 THEN
parentNodeAnalyzed = -999
' Move 4 level (Computer) -- The analysis starts from here if Thinking_Depth = 4.
' Note: Start from 1!
'PRINT "NodeLevel_4_count = " + STR(NodeLevel_4_count)
'PRINT "NodesAnalysis4(counter4, 1) = " + STR(NodesAnalysis4(counter4, 1))
'PRINT "NodesAnalysis4(counter4, 2) = " + STR(NodesAnalysis4(counter4, 2))
'PRINT "NodesAnalysis3(NodesAnalysis4(counter4, 2), 1) = " + STR(NodesAnalysis3(NodesAnalysis4(counter4, 2), 1))
FOR counter4 = 1 TO (NodeLevel_4_count - 1)
IF (NodesAnalysis4(counter4, 2) <> parentNodeAnalyzed) THEN
parentNodeAnalyzed = NodesAnalysis4(counter4, 2)
'PRINT "counter4 = " + STR(counter4)
IF NodesAnalysis4(counter4, 2) = 0 THEN NodesAnalysis4(counter4, 2) = 1
NodesAnalysis3(NodesAnalysis4(counter4, 2), 1) = NodesAnalysis4(counter4, 1)
bestNode4 = counter4
bestNodes4(parentNodeAnalyzed) = counter4
END IF
' v0.991: Original: >=
' v0.991: This should depend on the colour of the computer!!!
' v0.991: Tried to fix the problem in MinMax. Node1 elements for the SAME parent of Node2 must be filled accordingly.
' We do not need to take into account the Node2 elements which are empty, thus having a score of 0 but no
' assigned move! (this is why the Best Variant text is empty in the first moves)
IF playerColor = "w" THEN
IF (NodesAnalysis4(counter4, 1) <= NodesAnalysis3(NodesAnalysis4(counter4, 2), 1)) THEN
IF NodesAnalysis4(counter4, 2) = 0 THEN NodesAnalysis4(counter4, 2) = 1
NodesAnalysis3(NodesAnalysis4(counter4, 2), 1) = NodesAnalysis4(counter4, 1)
bestNode4 = counter4
bestNodes4(parentNodeAnalyzed) = counter4
END IF
ELSEIF (playerColor = "b") THEN
IF (NodesAnalysis4(counter4, 1) >= NodesAnalysis3(NodesAnalysis4(counter4, 2), 1)) THEN
IF NodesAnalysis4(counter4, 2) = 0 THEN NodesAnalysis4(counter4, 2) = 1
NodesAnalysis3(NodesAnalysis4(counter4, 2), 1) = NodesAnalysis4(counter4, 1)
bestNode4 = counter4
bestNodes4(parentNodeAnalyzed) = counter4
END IF
END IF
NEXT counter4
' Now the Node1 level is filled with the score data
' this is line 1 in the shape at http:'upload.wikimedia.org/wikipedia/commons/thumb/6/6f/Minimax.svg/300px-Minimax.svg.png
' Move 3 level (Human)
parentNodeAnalyzed = -999
' Note: Start from 1!
FOR counter3 = 1 TO (NodeLevel_3_count - 1)
IF (NodesAnalysis3(counter3, 2) <> parentNodeAnalyzed) THEN
parentNodeAnalyzed = NodesAnalysis3(counter3, 2)
IF NodesAnalysis3(counter3, 2) = 0 THEN NodesAnalysis3(counter3, 2) = 1
NodesAnalysis2(NodesAnalysis3(counter3, 2), 1) = NodesAnalysis3(counter3, 1)
bestNode3 = counter3
bestNodes3(parentNodeAnalyzed) = counter3
END IF
' v0.991: Choose different based on colour!
IF (playerColor = "w") THEN
IF NodesAnalysis3(counter3, 1) >= NodesAnalysis2(NodesAnalysis3(counter3, 2), 1) THEN
IF NodesAnalysis3(counter3, 2) = 0 THEN NodesAnalysis3(counter3, 2) = 1
NodesAnalysis2(NodesAnalysis3(counter3, 2), 1) = NodesAnalysis3(counter3, 1)
bestNode3 = counter3
bestNodes3(parentNodeAnalyzed) = counter3
END IF
ELSEIF (playerColor = "b") THEN
IF NodesAnalysis3(counter3, 1) <= NodesAnalysis2(NodesAnalysis3(counter3, 2), 1) THEN
IF NodesAnalysis3(counter3, 2) = 0 THEN NodesAnalysis3(counter3, 2) = 1
NodesAnalysis2(NodesAnalysis3(counter3, 2), 1) = NodesAnalysis3(counter3, 1)
bestNode3 = counter3
bestNodes3(parentNodeAnalyzed) = counter3
END IF
END IF
NEXT counter3
END IF
parentNodeAnalyzed = -999
' Move 2 level (Computer) -- The analysis starts from here if Thinking_Depth = 2.
' Note: Start from 1!
FOR counter2 = 1 TO (NodeLevel_2_count - 1)
IF debugMode = 1 THEN
PRINT "counter2 = " + Str(counter2)
PRINT "NodesAnalysis2(counter2, 2) = " + Str(NodesAnalysis2(counter2, 2))
PRINT "NodesAnalysis1(NodesAnalysis2(counter2, 2), 1) = " + Str(NodesAnalysis1(NodesAnalysis2(counter2, 2), 1))
END IF
IF (NodesAnalysis2(counter2, 2) <> parentNodeAnalyzed) THEN
parentNodeAnalyzed = NodesAnalysis2(counter2, 2)
NodesAnalysis1(NodesAnalysis2(counter2, 2), 1) = NodesAnalysis2(counter2, 1)
bestNode2 = counter2
IF debugMode = 1 THEN
PRINT "parentNodeAnalyzed = " + Str(parentNodeAnalyzed)
PRINT "parentNodeAnalyzed = " + Str(parentNodeAnalyzed)
END IF
bestNodes2(parentNodeAnalyzed) = counter2
END IF
' v0.991: Original: >=
' v0.991: This should depend on the colour of the computer!!!
' v0.991: Tried to fix the problem in MinMax. Node1 elements for the SAME parent of Node2 must be filled accordingly.
' We do not need to take into account the Node2 elements which are empty, thus having a score of 0 but no
' assigned move! (this is why the Best Variant text is empty in the first moves)
IF playerColor = "w" THEN
IF (NodesAnalysis2(counter2, 1) <= NodesAnalysis1(NodesAnalysis2(counter2, 2), 1)) THEN
NodesAnalysis1(NodesAnalysis2(counter2, 2), 1) = NodesAnalysis2(counter2, 1)
bestNode2 = counter2
bestNodes2(parentNodeAnalyzed) = counter2
END IF
ELSEIF (playerColor = "b") THEN
IF (NodesAnalysis2(counter2, 1) >= NodesAnalysis1(NodesAnalysis2(counter2, 2), 1)) THEN
NodesAnalysis1(NodesAnalysis2(counter2, 2), 1) = NodesAnalysis2(counter2, 1)
bestNode2 = counter2
bestNodes2(parentNodeAnalyzed) = counter2
END IF
END IF
NEXT counter2
' Now the Node1 level is filled with the score data
' this is line 1 in the shape at http:'upload.wikimedia.org/wikipedia/commons/thumb/6/6f/Minimax.svg/300px-Minimax.svg.png
' Move 1 level (Human)
parentNodeAnalyzed = -999
' Note: Start from 1!
FOR counter1 = 1 TO (NodeLevel_1_count - 1)
IF (NodesAnalysis1(counter1, 2) <> parentNodeAnalyzed) THEN
parentNodeAnalyzed = NodesAnalysis1(counter1, 2)
NodesAnalysis0(NodesAnalysis1(counter1, 2), 1) = NodesAnalysis1(counter1, 1)
bestNode1 = counter1
bestNodes1(parentNodeAnalyzed) = counter1
END IF
' v0.991: Choose different based on colour!
IF (playerColor = "w") THEN
IF NodesAnalysis1(counter1, 1) >= NodesAnalysis0(NodesAnalysis1(counter1, 2), 1) THEN
NodesAnalysis0(NodesAnalysis1(counter1, 2), 1) = NodesAnalysis1(counter1, 1)
bestNode1 = counter1
bestNodes1(parentNodeAnalyzed) = counter1
END IF
ELSEIF (playerColor = "b") THEN
IF NodesAnalysis1(counter1, 1) <= NodesAnalysis0(NodesAnalysis1(counter1, 2), 1) THEN
NodesAnalysis0(NodesAnalysis1(counter1, 2), 1) = NodesAnalysis1(counter1, 1)
bestNode1 = counter1
bestNodes1(parentNodeAnalyzed) = counter1
END IF
END IF
NEXT counter1
' Choose the biggest score at the Node0 level
' Check example at http:'en.wikipedia.org/wiki/Minimax#Example_2
' This is line 0 at the shape at http:'upload.wikimedia.org/wikipedia/commons/thumb/6/6f/Minimax.svg/300px-Minimax.svg.png
' Move 0 level (Computer)
' Initialize the score with the first score and move found
' Note: Start from 1!
temp_score = NodesAnalysis0(1, 1)
' v0.992: Start from 0 also here!
bestStartingColumn = NodesAnalysis0(1, 3)
bestStartingRank = NodesAnalysis0(1, 5)
bestFinishingColumn = NodesAnalysis0(1, 4)
bestFinishingRank = NodesAnalysis0(1, 6)
' v0.992
bestNode0 = 0
'PRINT "Best move : " + STR(bestStartingColumn) + STR(bestStartingRank) + " -> " + STR(bestFinishingColumn) + STR(bestFinishingRank)
'PRINT "Best score : " + STR(temp_score)
'INPUT A
'Note: Start from 1!
FOR counter0 = 1 TO (NodeLevel_0_count - 1)
' v0.991: Choose different based on colour!
IF (playerColor = "b") THEN
IF (NodesAnalysis0(counter0, 1) > temp_score) THEN
temp_score = NodesAnalysis0(counter0, 1)
bestStartingColumn = NodesAnalysis0(counter0, 3)
bestStartingRank = NodesAnalysis0(counter0, 5)
bestFinishingColumn = NodesAnalysis0(counter0, 4)
bestFinishingRank = NodesAnalysis0(counter0, 6)
' v0.992
bestNode0 = counter0
END IF
ELSEIF (playerColor = "w") THEN
IF NodesAnalysis0(counter0, 1) < temp_score THEN
temp_score = NodesAnalysis0(counter0, 1)
bestStartingColumn = NodesAnalysis0(counter0, 3)
bestStartingRank = NodesAnalysis0(counter0, 5)
bestFinishingColumn = NodesAnalysis0(counter0, 4)
bestFinishingRank = NodesAnalysis0(counter0, 6)
' v0.992
bestNode0 = counter0
END IF
END IF
NEXT counter0
' ------- LOG: Nodes after (start) -------
'Log not available in this edition - Check the graphics edition!
' ------- LOG: Nodes after (end) -------
END SUB
SUB HumanMove3 (HM3Skakiera() AS STRING)
DIM bestMove3score AS INTEGER
Dim As Integer startingColumnHM3, startingRankHM3, finishingColumnHM3, finishingRankHM3
Dim As String MovingPieceHM3, ProsorinoKommatiHM3
bestMove3score = 0
'Scan the chessboard...
FOR I = 1 TO 8
FOR J = 1 TO 8
'If you find a piece of the human...
IF ((MID(HM3Skakiera(I, J), 1, 1) = "w" AND playerColor = "w") OR (MID(HM3Skakiera(I, J), 1, 1) = "b" AND playerColor = "b")) THEN
IF debugMode = 1 THEN PRINT "Inside Human level 3 move - Checkpoint A"
'Scan all possible destination squares...
FOR ii = 1 TO 8
FOR jj = 1 TO 8
startingColumnHM3 = I
startingRankHM3 = J
finishingColumnHM3 = ii
finishingRankHM3 = jj
MovingPieceHM3 = HM3Skakiera(I, J)
ProsorinoKommatiHM3 = HM3Skakiera(ii, jj)
'Check legality of the move entered
whoPlays = "Human"
ElegxosNomimotitas(HM3Skakiera(), 0, startingColumnHM3, startingRankHM3, finishingColumnHM3, finishingRankHM3, MovingPieceHM3)
whoPlays = "HY"
IF debugMode = 1 THEN
PRINT ""
PRINT "NEW MOVE ANALYZED: " + STR(startingColumnHM3) + STR(startingRankHM3) + " -> " + STR(finishingColumnHM3) + Str(finishingRankHM3)
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
HM3Skakiera(finishingColumnHM3, finishingRankHM3) = HM3Skakiera(startingColumnHM3, startingRankHM3)
HM3Skakiera(startingColumnHM3, startingRankHM3) = ""
'Count the score of the move
countScore
'PRINT "NodeLevel_3_count = " + STR(NodeLevel_3_count)
'-------------- MinMax --------------
'Store scores
NodesAnalysis3(NodeLevel_3_count, 1) = positionScore
' Store parents
NodesAnalysis3(NodeLevel_3_count, 2) = NodeLevel_2_count
'Call the next level only if the variant entails capturing a piece
'IF Move < thinkingDepth AND ProsorinoKommatiHM3 <> "" THEN
IF iMove < thinkingDepth AND ((playerColor = "b" AND positionScore <= bestMove3score) OR (playerColor = "w" AND positionScore >= bestMove3score)) THEN
iMove = iMove + 1
bestMove3score = positionScore
ComputerMove4(HM3Skakiera())
END IF
'Undo the move
HM3Skakiera(startingColumnHM3, startingRankHM3) = MovingPieceHM3
HM3Skakiera(finishingColumnHM3, finishingRankHM3) = ProsorinoKommatiHM3
'-------------- MinMax --------------
'Increase node count
NodeLevel_3_count = NodeLevel_3_count + 1
END IF
NEXT jj
NEXT ii
END IF
NEXT J
NEXT I
'Reduce the move
iMove = iMove - 1
END SUB
SUB ComputerMove4 (CM4Skakiera() AS STRING)
Dim As Integer startingColumnCM4, startingRankCM4, finishingColumnCM4, finishingRankCM4
Dim As String MovingPieceCM4, ProsorinoKommatiCM4
'Scan the chessboard...
FOR I = 1 TO 8
FOR J = 1 TO 8
'If you find a piece of the computer...
IF ((MID(CM4Skakiera(I, J), 1, 1) = "w" AND playerColor = "b") OR (MID(CM4Skakiera(I, J), 1, 1) = "b" AND playerColor = "w")) THEN
IF debugMode = 1 THEN PRINT "Inside Computer level 4 move - Checkpoint A"
'Scan all possible destination squares...
FOR ii = 1 TO 8
FOR jj = 1 TO 8
startingColumnCM4 = I
startingRankCM4 = J
finishingColumnCM4 = ii
finishingRankCM4 = jj
MovingPieceCM4 = CM4Skakiera(I, J)
ProsorinoKommatiCM4 = CM4Skakiera(ii, jj)
'Check legality of the move entered
ElegxosNomimotitas(CM4Skakiera(), 0, startingColumnCM4, startingRankCM4, finishingColumnCM4, finishingRankCM4, MovingPieceCM4)
IF debugMode = 1 THEN
PRINT ""
PRINT "NEW MOVE ANALYZED: " + STR(startingColumnCM4) + STR(startingRankCM4) + " -> " + STR(finishingColumnCM4) + Str(finishingRankCM4)
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
CM4Skakiera(finishingColumnCM4, finishingRankCM4) = CM4Skakiera(startingColumnCM4, startingRankCM4)
CM4Skakiera(startingColumnCM4, startingRankCM4) = ""
'Count the score of the move
countScore
'-------------- MinMax --------------
'Store scores
NodesAnalysis4(NodeLevel_4_count, 1) = positionScore
' Store parents
NodesAnalysis4(NodeLevel_4_count, 2) = NodeLevel_3_count
'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
'Undo the move
CM4Skakiera(startingColumnCM4, startingRankCM4) = MovingPieceCM4
CM4Skakiera(finishingColumnCM4, finishingRankCM4) = ProsorinoKommatiCM4
'-------------- MinMax --------------
'Increase node count
NodeLevel_4_count = NodeLevel_4_count + 1
END IF
NEXT jj
NEXT ii
END IF
NEXT J
NEXT I
'Reduce the move
iMove = iMove - 1
END SUB
SUB PawnPromotion ()
FOR KK As Integer = 1 TO 8
IF chessboard(KK, 1) = "bpawn" THEN chessboard(KK, 1) = "bqueen"
NEXT KK
FOR YY As Integer = 1 TO 8
IF chessboard(YY, 8) = "wpawn" THEN chessboard(YY, 8) = "wqueen"
NEXT YY
END SUB
SUB Castling ()
'White castling
IF startingRank = 1 AND finishingRank = 1 AND startingColumn = 5 AND finishingColumn = 3 AND MovingPiece = "wking" AND playerColor = "w" THEN
IF chessboard(4, 1) = "" AND chessboard(3, 1) = "" AND chessboard(2, 1) = "" AND chessboard(1, 1) = "wrook" AND whiteCastling = 0 THEN
Nomimotita = 1
whiteCastling = 1
whiteBigCastling = 1
END IF
ELSEIF startingRank = 1 AND finishingRank = 1 AND startingColumn = 5 AND finishingColumn = 7 AND MovingPiece = "wking" AND playerColor = "w" THEN
IF chessboard(6, 1) = "" AND chessboard(7, 1) = "" AND chessboard(8, 1) = "wrook" AND whiteCastling = 0 THEN
Nomimotita = 1
whiteCastling = 1
whiteSmallCastling = 1
END IF
END IF
'Black castling
IF startingRank = 8 AND finishingRank = 8 AND startingColumn = 5 AND finishingColumn = 3 AND MovingPiece = "bking" AND playerColor = "b" THEN
IF chessboard(4, 8) = "" AND chessboard(3, 8) = "" AND chessboard(2, 8) = "" AND chessboard(1, 8) = "brook" AND blackCastling = 0 THEN
Nomimotita = 1
blackCastling = 1
blackBigCastling = 1
END IF
ELSEIF startingRank = 8 AND finishingRank = 8 AND startingColumn = 5 AND finishingColumn = 7 AND MovingPiece = "bking" AND playerColor = "b" THEN
IF chessboard(6, 8) = "" AND chessboard(7, 8) = "" AND chessboard(8, 8) = "brook" AND blackCastling = 0 THEN
Nomimotita = 1
blackCastling = 1
blackSmallCastling = 1
END IF
END IF
END SUB
SUB checkWhiteCheck (CWCSkakiera() AS STRING)
Dim As Integer startingColumnCWC, startingRankCWC, finishingColumnCWC, finishingRankCWC
Dim As String MovingPieceCWC, ProsorinoKommatiCWC
whiteCheck = 0
'PRINT "Check check START: Nomimotita = " + STR(Nomimotita)
'Scan the chessboard...
FOR I1 As Integer = 1 TO 8
FOR J1 As Integer = 1 TO 8
'If you find a black piece...
IF MID(CWCSkakiera(I1, J1), 1, 1) = "b" THEN
'Scan all possible destination squares...
FOR ii1 As Integer = 1 TO 8
FOR jj1 As Integer = 1 TO 8
startingColumnCWC = I1
startingRankCWC = J1
finishingColumnCWC = ii1
finishingRankCWC = jj1
MovingPieceCWC = CWCSkakiera(I1, J1)
ProsorinoKommatiCWC = CWCSkakiera(ii1, jj1)
'Check legality of the move entered if the target is the White King!
IF ProsorinoKommatiCWC = "wking" THEN
ElegxosNomimotitas(CWCSkakiera(), 0, startingColumnCWC, startingRankCWC, finishingColumnCWC, finishingRankCWC, MovingPieceCWC)
'If move is legal, then do the move and present it in the chessbooard
IF Nomimotita = 1 THEN whiteCheck = 1
'IF Nomimotita = 1 THEN PRINT "Found legal check move: " + STR(startingColumnCWC) + STR(startingRankCWC) + " -> " + STR(finishingColumnCWC) + STR(finishingRankCWC): INPUT h
END IF
NEXT jj1
NEXT ii1
END IF
NEXT J1
NEXT I1
END SUB
SUB checkBlackCheck (CBCSkakiera() AS STRING)
Dim As Integer startingColumnCBC, startingRankCBC, finishingColumnCBC, finishingRankCBC
Dim As String MovingPieceCBC, ProsorinoKommatiCBC
blackCheck = 0
'Scan the chessboard...
FOR I2 As Integer = 1 TO 8
FOR J2 As Integer = 1 TO 8
'If you find a black piece...
IF MID(CBCSkakiera(I2, J2), 1, 1) = "w" THEN
'Scan all possible destination squares...
FOR ii2 As Integer = 1 TO 8
FOR jj2 As Integer = 1 TO 8
startingColumnCBC = I2
startingRankCBC = J2
finishingColumnCBC = ii2
finishingRankCBC = jj2
MovingPieceCBC = CBCSkakiera(I2, J2)
ProsorinoKommatiCBC = CBCSkakiera(ii2, jj2)
'Check legality of the move entered if the target is the Black King!
IF ProsorinoKommatiCBC = "bking" THEN
'IF startingColumnCBC = 3 AND startingRankCBC = 7 AND finishingColumnCBC = 5 AND finishingRankCBC = 8 THEN
' PRINT "MovingPieceCBC = " + MovingPieceCBC
' PRINT "ProsorinoKommatiCBC = " + ProsorinoKommatiCBC
' INPUT aa
'END IF
ElegxosNomimotitas(CBCSkakiera(), 0, startingColumnCBC, startingRankCBC, finishingColumnCBC, finishingRankCBC, MovingPieceCBC)
'If move is legal, then do the move and present it in the chessbooard
IF Nomimotita = 1 THEN blackCheck = 1
'IF startingColumnCBC = 3 AND startingRankCBC = 7 AND finishingColumnCBC = 5 AND finishingRankCBC = 8 THEN
' PRINT "Nomimotita = " + STR(Nomimotita)
' PRINT "blackCheck = " + STR(blackCheck)
' INPUT aa
'END IF
END IF
NEXT jj2
NEXT ii2
END IF
NEXT J2
NEXT I2
END SUB