As I added more features to my chess game, such as an endgame screen. I eventually ended up having a lot of duplicate code, and complex logic with lots of nested if statements in loops. The usual advice is to add more functions, but I cannot think of ways to reorganise this code such that each part has a highly specific role so that it can be turned into a function. I also could try to split this over multiple event listeners, but that may become too complicated.
If any extra pieces of code, or clarification about the question is needed, feel free to ask.
Here is the code:
let movedCastlesAndKings = {
hasWKMoved: false,
hasWKSCMoved: false,
hasWQSCMoved: false,
hasBKMoved: false,
hasBKSCMoved: false,
hasBQSCMoved: false
};
let castlingPerms = {
WKSC: false,
WQSC: false,
BKSC: false,
BQSC: false
};
let boardHistory = [];
let lastDoubledPawnMove, enpassantSquare;
let humanPlayer = "w";
let humanPieces = WP;
let AIPlayer = "b";
let AIPieces = BP;
let currentPlayer = humanPlayer;
let currentPieces = humanPieces;
let movesForThisPiece, clickPosition, currentPlayerKingPosition, isCurrentPlayerInCheck, promotedPawnPosition;
let isCheckMate, hashIndex, isHighlightSquare, isHighlightPossibleMoves, hasClickedBefore, oppositePlayer, elementToEdit;
let legalMoves = generateLegalMoves(enpassantSquare, castlingPerms, initKingPosition, board, "w");
let lastMoveFromAndToSQ = {
from: undefined,
to: undefined
}
let threatningPieces = [];
function updateGameLoop(event) {
clickPosition = getBoardCellFromClick(event);
if (!hasClickedBefore) {
if (clickPosition.x < 8 && clickPosition.y < 8) {
boardItem = board[clickPosition.y][clickPosition.x];
if (boardItem != " ") isHighlightSquare = true;
if (currentPieces.includes(board[clickPosition.y][clickPosition.x])) {
moves = generateMovesForThisPiece(legalMoves, clickPosition);
isHighlightPossibleMoves = true;
}
hasClickedBefore = true;
}
} else {
if (isHighlightPossibleMoves) {
let moveItem, toSQ;
for (move = 0; move < moves.length; move++) {
moveItem = moves[move];
toSQ = moveItem.to;
if (toSQ.x == clickPosition.x && toSQ.y == clickPosition.y) {
board = moveItem.node;
switchSides();
currentPlayer == "w" ? oppositePlayer = "b" : oppositePlayer = "w";
promotedPawnPosition = findPromotedPawns(board, oppositePlayer);
if (promotedPawnPosition) {
if (oppositePlayer == "w" ) {
document.getElementById("whitePromotionSelection").style.display = "inline";
} else {
document.getElementById("blackPromotionSelection").style.display = "inline";
}
window.promotePawns = function (piece) {
board[promotedPawnPosition.y][promotedPawnPosition.x] = piece;) {
document.getElementById("whitePromotionSelection").style.display = "none";
} else {
document.getElementById("blackPromotionSelection").style.display = "none";
}
currentPlayerKingPosition = findKing(board, currentPlayer);
movedCastlesAndKings = updateMovedCastlesAndKings(movedCastlesAndKings, board);
enpassantSquare = getEnpassantSquare(moveItem.doublePawnMove, board, currentPlayer);
castlingPerms = castlingPermissions(movedCastlesAndKings, board);
hashIndex = makeHashTableIndex(castlingPerms, enpassantSquare, board, currentPlayer);
legalMoves = generateLegalMoves(enpassantSquare, castlingPerms, currentPlayerKingPosition, board, currentPlayer);
lastMoveFromAndToSQ.from = moveItem.from;
lastMoveFromAndToSQ.to = toSQ;
threatningPieces = getThreatningPieces(board, currentPlayer);
isCurrentPlayerInCheck = isSquareUnderAttack(currentPlayerKingPosition, board, currentPlayer);
isCheckMate = isCheckmate(legalMoves.length, isCurrentPlayerInCheck);
if (isCheckMate && currentPlayer == humanPlayer) {
document.getElementById("gameover").style.display = "inline";
document.removeEventListener('click', updateGameLoop);
}
promotedPawnPosition = undefined;
}
} else {
currentPlayerKingPosition = findKing(board, currentPlayer);
movedCastlesAndKings = updateMovedCastlesAndKings(movedCastlesAndKings, board);
enpassantSquare = getEnpassantSquare(moveItem.doublePawnMove, board, currentPlayer);
castlingPerms = castlingPermissions(movedCastlesAndKings, board);
hashIndex = makeHashTableIndex(castlingPerms, enpassantSquare, board, currentPlayer);
legalMoves = generateLegalMoves(enpassantSquare, castlingPerms, currentPlayerKingPosition, board, currentPlayer);
lastMoveFromAndToSQ.from = moveItem.from;
lastMoveFromAndToSQ.to = toSQ;
threatningPieces = getThreatningPieces(board, currentPlayer);
isCurrentPlayerInCheck = isSquareUnderAttack(currentPlayerKingPosition, board, currentPlayer);
isCheckMate = isCheckmate(legalMoves.length, isCurrentPlayerInCheck);
if (isCheckMate && currentPlayer == humanPlayer) {
document.getElementById("gameover").style.display = "inline";
document.removeEventListener('click', updateGameLoop);
}
}
break;
}
}
}
isHighlightPossibleMoves = false;
isHighlightSquare = false;
hasClickedBefore = false;
}
}
````
board[promotedPawnPosition.y][promotedPawnPosition.x] = piece;) {
looks like a typo, there's no(
to end with)
, did you miss a character or a line? \$\endgroup\$