У меня есть слушатель событий в шахматной игре, которую я создаю, и в ней есть несколько правил о том, когда менять определенные свойства или переменные. Проблема в том, что код редактирует свойство hasClicked в true для части в массиве Board, когда это не должно быть. Чтобы быть более точным c, кажется, что редактировать свойство, даже когда логическая переменная "hasClicked" имеет значение false (эта переменная не является свойством). Я попытался проверить любые косвенные способы, которыми код мог редактировать фактическую плату внутри определений функций, но единственный способ, которым это редактирует значения платы, - через параметры, в которые должна быть передана плата.
Функции update и returnCastledBoard предназначены для возврата обновленной доски со свойством hasClicked.
Если вам нужны дополнительные переменные и функции, показанные в коде, не стесняйтесь спрашивать.
Вот код:
let hasClicked = false;
let canMove = false;
let isHighlightPossibleMoves = false;
let canAdvancePiece = false;
let highlightPos = undefined;
let pieceMoves = undefined;
let advancePosition = undefined;
let isCastling = false;
document.addEventListener('click', function(event){
if(!hasClicked){
if(event.clientX < boardWidth && event.clientY < boardHeight && board[Math.floor(event.clientY / 60)][Math.floor(event.clientX / 60)] != "vacant"){
if(isItemInArray(humanPlayer, board[Math.floor(event.clientY / 60)][Math.floor(event.clientX / 60)])){
canMove = true;
isHighlightPossibleMoves = true;
hasClicked = true;
highlightPos = {x: Math.floor(event.clientX / 60), y: Math.floor(event.clientY / 60)};
pieceMoves = getValidMoves({x: Math.floor(event.clientX / 60), y: Math.floor(event.clientY / 60)}, board);
} else {
hasClicked = true;
highlightPos = {x: Math.floor(event.clientX / 60), y: Math.floor(event.clientY / 60)};
canMove = false;
}
}
} else {
if(canMove){
advancePosition = {x: Math.floor(event.clientX / 60), y: Math.floor(event.clientY / 60)};
for(pieceMove = 0; pieceMove < pieceMoves.move.length; pieceMove++){
if(advancePosition.x == pieceMoves.move[pieceMove].to.x && advancePosition.y == pieceMoves.move[pieceMove].to.y){
board = pieceMoves.move[pieceMove].node;
// this board is the actual game board where the the property hasclicked on an item in a board is being incorrectly set
break;
}
}
}
hasClicked = false;
canMove = false;
highlightPos = undefined;
pieceMoves = undefined;
advancePosition = undefined;
}
});
function pawnMoves(piecePosition, board){
let moves = [];
let pieceType = getPieceType(piecePosition, board);
if(piecePosition.y - 1 >= 0 && piecePosition.x - 1 >= 0){
var isEnemyInTopLeft = !isItemInArray(pieceType, board[piecePosition.y - 1][piecePosition.x - 1]) && board[piecePosition.y - 1][piecePosition.x - 1] != "vacant";
}
if(piecePosition.y - 1 >= 0 && piecePosition.x + 1 < 8){
var isEnemyInTopRight = !isItemInArray(pieceType, board[piecePosition.y - 1][piecePosition.x + 1]) && board[piecePosition.y - 1][piecePosition.x + 1] != "vacant";
}
if(piecePosition.y + 1 < 8 && piecePosition.x - 1 >= 0){
var isEnemyInBottomLeft = !isItemInArray(pieceType, board[piecePosition.y + 1][piecePosition.x - 1]) && board[piecePosition.y + 1][piecePosition.x - 1] != "vacant";
}
if(piecePosition.y + 1 < 8 && piecePosition.x + 1 < 8){
var isEnemyInBottomRight = !isItemInArray(pieceType, board[piecePosition.y + 1][piecePosition.x + 1]) && board[piecePosition.y + 1][piecePosition.x + 1] != "vacant";
}
let boardPosition = board[piecePosition.y][piecePosition.x];
let isPieceInBackOfBoard = piecePosition.y == 6;
let isPieceInTopOfBoard = piecePosition.y == 1;
humanPlayer == whitePieces ? pawnInBottom = whitePawns : pawnInBottom = blackPawns;
if(isItemInArray(pawnInBottom, boardPosition)){
if(isPieceInBackOfBoard){
if(board[piecePosition.y - 1][piecePosition.x] == "vacant"){
moves.push({node: update(board, piecePosition, {x: piecePosition.x, y: piecePosition.y - 1}), to: {x: piecePosition.x, y: piecePosition.y - 1}});
}
if(board[piecePosition.y - 2][piecePosition.x] == "vacant" && board[piecePosition.y - 1][piecePosition.x] == "vacant"){
moves.push({node: update(board, piecePosition, {x: piecePosition.x, y: piecePosition.y - 2}), to: {x: piecePosition.x, y: piecePosition.y - 2}});
}
} else if(piecePosition.y - 1 >= 0){
if(board[piecePosition.y - 1][piecePosition.x] == "vacant"){
moves.push({node: update(board, piecePosition, {x: piecePosition.x, y: piecePosition.y - 1}), to: {x: piecePosition.x, y: piecePosition.y - 1}});
}
}
if(isEnemyInTopLeft){
moves.push({node: update(board, piecePosition, {x: piecePosition.x - 1, y: piecePosition.y - 1}), to: {x: piecePosition.x - 1, y: piecePosition.y - 1}});
}
if(isEnemyInTopRight){
moves.push({node: update(board, piecePosition, {x: piecePosition.x + 1, y: piecePosition.y - 1}), to: {x: piecePosition.x + 1, y: piecePosition.y - 1}});
}
} else {
if(isPieceInTopOfBoard){
if(board[piecePosition.y + 1][piecePosition.x] == "vacant"){
moves.push({node: update(board, piecePosition, {x: piecePosition.x, y: piecePosition.y + 1}), to: {x: piecePosition.x, y: piecePosition.y + 1}});
}
if(board[piecePosition.y + 2][piecePosition.x] == "vacant" && board[piecePosition.y + 1][piecePosition.x] == "vacant"){
moves.push({node: update(board, piecePosition, {x: piecePosition.x, y: piecePosition.y + 2}), to: {x: piecePosition.x, y: piecePosition.y + 2}});
}
} else if(piecePosition.y + 1 < 8){
if(board[piecePosition.y + 1][piecePosition.x] == "vacant"){
moves.push({node: update(board, piecePosition, {x: piecePosition.x, y: piecePosition.y + 1}), to: {x: piecePosition.x, y: piecePosition.y + 1}});
}
}
if(isEnemyInBottomLeft){
moves.push({node: update(board, piecePosition, {x: piecePosition.x - 1, y: piecePosition.y + 1}), to: {x: piecePosition.x - 1, y: piecePosition.y + 1}});
}
if(isEnemyInBottomRight){
moves.push({node: update(board, piecePosition, {x: piecePosition.x + 1, y: piecePosition.y + 1}), to: {x: piecePosition.x + 1, y: piecePosition.y + 1}})
}
}
return moves;
}
function returnCastledBoard(kingPos, to, board){
let king = board[kingPos.y][kingPos.x];
if(to.x > kingPos.x){
castlingCastle = board[to.y][7];
boardDeepClone = copyBoardArray(board);
boardDeepClone[kingPos.y][kingPos.x] = "vacant";
boardDeepClone[kingPos.y][kingPos.x + 2] = king;
boardDeepClone[kingPos.y][kingPos.x + 2].hasClicked = true;
boardDeepClone[kingPos.y][7] = "vacant";
boardDeepClone[kingPos.y][kingPos.x + 1] = castlingCastle;
} else {
castlingCastle = board[to.y][0];
boardDeepClone = copyBoardArray(board);
boardDeepClone[kingPos.y][kingPos.x] = "vacant";
boardDeepClone[kingPos.y][kingPos.x - 2] = king;
boardDeepClone[kingPos.y][kingPos.x - 2].hasClicked = true;
boardDeepClone[kingPos.y][0] = "vacant";
boardDeepClone[kingPos.y][kingPos.x - 1] = castlingCastle;
}
return boardDeepClone;
}
function castleMoves(piecePosition, board){
let moves = [];
let pieceType = getPieceType(piecePosition, board);
for(i = piecePosition.x + 1; i < 8; i++){
if(board[piecePosition.y][i] != "vacant" && isItemInArray(pieceType, board[piecePosition.y][i])){
break;
}
if(board[piecePosition.y][i] != "vacant" && !isItemInArray(pieceType, board[piecePosition.y][i])){
moves.push({node: update(board, piecePosition, {x: i, y: piecePosition.y}), to: {x: i, y: piecePosition.y}});
break;
}
moves.push({node: update(board, piecePosition, {x: i, y: piecePosition.y}), to: {x: i, y: piecePosition.y}});
}
for(i = piecePosition.x - 1; i >= 0; i--){
if(board[piecePosition.y][i] != "vacant" && isItemInArray(pieceType, board[piecePosition.y][i])){
break;
}
if(board[piecePosition.y][i] != "vacant" && !isItemInArray(pieceType, board[piecePosition.y][i])){
moves.push({node: update(board, piecePosition, {x: i, y: piecePosition.y}), to: {x: i, y: piecePosition.y}});
break;
}
moves.push({node: update(board, piecePosition, {x: i, y: piecePosition.y}), to: {x: i, y: piecePosition.y}});
}
for(i = piecePosition.y + 1; i < 8; i++){
if(board[i][piecePosition.x] != "vacant" && isItemInArray(pieceType, board[i][piecePosition.x])){
break;
}
if(board[i][piecePosition.x] != "vacant" && !isItemInArray(pieceType, board[i][piecePosition.x])){
moves.push({node: update(board, piecePosition, {x: piecePosition.x, y: i}), to: {x: piecePosition.x, y: i}});
break;
}
moves.push({node: update(board, piecePosition, {x: piecePosition.x, y: i}), to: {x: piecePosition.x, y: i}});
}
for(i = piecePosition.y - 1; i >= 0; i--){
if(board[i][piecePosition.x] != "vacant" && isItemInArray(pieceType, board[i][piecePosition.x])){
break;
}
if(board[i][piecePosition.x] != "vacant" && !isItemInArray(pieceType, board[i][piecePosition.x])){
moves.push({node: update(board, piecePosition, {x: piecePosition.x, y: i}), to: {x: piecePosition.x, y: i}});
break;
}
moves.push({node: update(board, piecePosition, {x: piecePosition.x, y: i}), to: {x: piecePosition.x, y: i}});
}
return moves;
}
function castlingMoves(pieceType, board){
let castlingMoves = [];
pieceType == blackPieces ? king = blackKing : king = whiteKing;
let kingPos = getPiecePosition(king, board);
let isPieceBlocking;
let playerInCheck;
if(board[kingPos.y][kingPos.x].hasClicked === undefined){
if(board[kingPos.y][0].hasClicked === undefined){
for(xPos = kingPos.x - 1; xPos >= 1; xPos--){
if(board[kingPos.y][xPos] == "vacant"){
isPieceBlocking = false;
} else if(board[kingPos.y][xPos] != "vacant"){
isPieceBlocking = true;
break;
}
}
if(!isPieceBlocking){
for(xPos = kingPos.x; xPos >= kingPos.x - 2; xPos--){
bCopy = copyBoardArray(board);
bCopy = update(board, kingPos, {x: xPos, y: kingPos.y});
if(isPlayerInCheck(pieceType, board)){
playerInCheck = true;
break;
} else {
playerInCheck = false;
}
}
}
if(!isPieceBlocking && !playerInCheck){
castlingMoves.push({node: returnCastledBoard(kingPos, {x: kingPos.x - 2, y: kingPos.y}, board), to: {x: kingPos.x - 2, y: kingPos.y}});
}
}
if(board[kingPos.y][7].hasClicked === undefined){
for(xPos = kingPos.x + 1; xPos <= 7; xPos++){
if(board[kingPos.y][xPos] == "vacant"){
isPieceBlocking = false;
} else if(board[kingPos.y][xPos] != "vacant"){
isPieceBlocking = true;
break;
}
}
if(!isPieceBlocking){
for(xPos = kingPos.x; xPos <= kingPos.x + 2; xPos++){
bCopy = copyBoardArray(board);
bCopy = update(board, kingPos, {x: xPos, y: kingPos.y});
if(isPlayerInCheck(pieceType, board)){
playerInCheck = true;
break;
} else {
playerInCheck = false;
}
}
}
if(!isPieceBlocking && !playerInCheck){
castlingMoves.push({node: returnCastledBoard(kingPos, {x: kingPos.x + 2, y: kingPos.y}, board), to: {x: kingPos.x + 2, y: kingPos.y}});
}
}
}
return castlingMoves;
}
function bishopMoves(piecePosition, board){
let moves = [];
let pieceType = getPieceType(piecePosition, board);
x = piecePosition.x + 1;
y = piecePosition.y + 1;
while(x < 8 && y < 8){
if(board[y][x] != "vacant" && isItemInArray(pieceType, board[y][x])){
break;
}
if(board[y][x] != "vacant" && !isItemInArray(pieceType, board[y][x])){
moves.push({node: update(board, piecePosition, {x: x, y: y}), to: {x: x, y: y}});
break;
}
moves.push({node: update(board, piecePosition, {x: x, y: y}), to: {x: x, y: y}});
x += 1;
y += 1;
}
x = piecePosition.x - 1;
y = piecePosition.y - 1;
while(x >= 0 && y >= 0){
if(board[y][x] != "vacant" && isItemInArray(pieceType, board[y][x])){
break;
}
if(board[y][x] != "vacant" && !isItemInArray(pieceType, board[y][x])){
moves.push({node: update(board, piecePosition, {x: x, y: y}), to: {x: x, y: y}});
break;
}
moves.push({node: update(board, piecePosition, {x: x, y: y}), to: {x: x, y: y}});
x -= 1;
y -= 1;
}
x = piecePosition.x - 1;
y = piecePosition.y + 1;
while(x >= 0 && y < 8){
if(board[y][x] != "vacant" && isItemInArray(pieceType, board[y][x])){
break;
}
if(board[y][x] != "vacant" && !isItemInArray(pieceType, board[y][x])){
moves.push({node: update(board, piecePosition, {x: x, y: y}), to: {x: x, y: y}});
break;
}
moves.push({node: update(board, piecePosition, {x: x, y: y}), to: {x: x, y: y}});
x -= 1;
y += 1;
}
x = piecePosition.x + 1;
y = piecePosition.y - 1;
while(x < 8 && y >= 0){
if(board[y][x] != "vacant" && isItemInArray(pieceType, board[y][x])){
break;
}
if(board[y][x] != "vacant" && !isItemInArray(pieceType, board[y][x])){
moves.push({node: update(board, piecePosition, {x: x, y: y}), to: {x: x, y: y}});
break;
}
moves.push({node: update(board, piecePosition, {x: x, y: y}), to: {x: x, y: y}});
x += 1;
y -= 1;
}
return moves;
}
function horseMoves(piecePosition, board){
let moves = [];
let pieceType = getPieceType(piecePosition, board);
if(piecePosition.x + 1 < 8 && piecePosition.y + 2 < 8){
if(board[piecePosition.y + 2][piecePosition.x + 1] == "vacant" || !isItemInArray(pieceType, board[piecePosition.y + 2][piecePosition.x + 1])){
moves.push({node: update(board, piecePosition, {x: piecePosition.x + 1, y: piecePosition.y + 2}), to: {x: piecePosition.x + 1, y: piecePosition.y + 2}});
}
}
if(piecePosition.x - 1 >= 0 && piecePosition.y + 2 < 8){
if(board[piecePosition.y + 2][piecePosition.x - 1] == "vacant" || !isItemInArray(pieceType, board[piecePosition.y + 2][piecePosition.x - 1])){
moves.push({node: update(board, piecePosition, {x: piecePosition.x - 1, y: piecePosition.y + 2}), to: {x: piecePosition.x - 1, y: piecePosition.y + 2}});
}
}
if(piecePosition.x + 1 < 8 && piecePosition.y - 2 >= 0){
if(board[piecePosition.y - 2][piecePosition.x + 1] == "vacant" || !isItemInArray(pieceType, board[piecePosition.y - 2][piecePosition.x + 1])){
moves.push({node: update(board, piecePosition, {x: piecePosition.x + 1, y: piecePosition.y - 2}), to: {x: piecePosition.x + 1, y: piecePosition.y - 2}});
}
}
if(piecePosition.x - 1 >= 0 && piecePosition.y - 2 >= 0){
if(board[piecePosition.y - 2][piecePosition.x - 1] == "vacant" || !isItemInArray(pieceType, board[piecePosition.y - 2][piecePosition.x - 1])){
moves.push({node: update(board, piecePosition, {x: piecePosition.x - 1, y: piecePosition.y - 2}), to: {x: piecePosition.x - 1, y: piecePosition.y - 2}});
}
}
if(piecePosition.x + 2 < 8 && piecePosition.y + 1 < 8){
if(board[piecePosition.y + 1][piecePosition.x + 2] == "vacant" || !isItemInArray(pieceType, board[piecePosition.y + 1][piecePosition.x + 2])){
moves.push({node: update(board, piecePosition, {x: piecePosition.x + 2, y: piecePosition.y + 1}), to: {x: piecePosition.x + 2, y: piecePosition.y + 1}});
}
}
if(piecePosition.x - 2 >= 0 && piecePosition.y + 1 < 8){
if(board[piecePosition.y + 1][piecePosition.x - 2] == "vacant" || !isItemInArray(pieceType, board[piecePosition.y + 1][piecePosition.x - 2])){
moves.push({node: update(board, piecePosition, {x: piecePosition.x - 2, y: piecePosition.y + 1}), to: {x: piecePosition.x - 2, y: piecePosition.y + 1}});
}
}
if(piecePosition.x + 2 < 8 && piecePosition.y - 1 >= 0){
if(board[piecePosition.y - 1][piecePosition.x + 2] == "vacant" || !isItemInArray(pieceType, board[piecePosition.y - 1][piecePosition.x + 2])){
moves.push({node: update(board, piecePosition, {x: piecePosition.x + 2, y: piecePosition.y - 1}), to: {x: piecePosition.x + 2, y: piecePosition.y - 1}});
}
}
if(piecePosition.x - 2 >= 0 && piecePosition.y - 1 >= 0){
if(board[piecePosition.y - 1][piecePosition.x - 2] == "vacant" || !isItemInArray(pieceType, board[piecePosition.y - 1][piecePosition.x - 2])){
moves.push({node: update(board, piecePosition, {x: piecePosition.x - 2, y: piecePosition.y - 1}), to: {x: piecePosition.x - 2, y: piecePosition.y - 1}});
}
}
return moves;
}
function kingMoves(piecePosition, board){
moves = [];
let pieceType = getPieceType(piecePosition, board);
if(piecePosition.x + 1 < 8){
if(board[piecePosition.y][piecePosition.x + 1] == "vacant" || !isItemInArray(pieceType, board[piecePosition.y][piecePosition.x + 1])){
moves.push({node: update(board, piecePosition, {x: piecePosition.x + 1, y: piecePosition.y}), to: {x: piecePosition.x + 1, y: piecePosition.y}});
}
}
if(piecePosition.x - 1 >= 0){
if(board[piecePosition.y][piecePosition.x - 1] == "vacant" || !isItemInArray(pieceType, board[piecePosition.y][piecePosition.x - 1])){
moves.push({node: update(board, piecePosition, {x: piecePosition.x - 1, y: piecePosition.y}), to: {x: piecePosition.x - 1, y: piecePosition.y}});
}
}
if(piecePosition.y + 1 < 8){
if(board[piecePosition.y + 1][piecePosition.x] == "vacant" || !isItemInArray(pieceType, board[piecePosition.y + 1][piecePosition.x])){
moves.push({node: update(board, piecePosition, {x: piecePosition.x, y: piecePosition.y + 1}), to: {x: piecePosition.x, y: piecePosition.y + 1}});
}
}
if(piecePosition.y - 1 >= 0){
if(board[piecePosition.y - 1][piecePosition.x] == "vacant" || !isItemInArray(pieceType, board[piecePosition.y - 1][piecePosition.x])){
moves.push({node: update(board, piecePosition, {x: piecePosition.x, y: piecePosition.y - 1}), to: {x: piecePosition.x, y: piecePosition.y - 1}});
}
}
if(piecePosition.y - 1 >= 0 && piecePosition.x - 1 >= 0){
if(board[piecePosition.y - 1][piecePosition.x - 1] == "vacant" || !isItemInArray(pieceType, board[piecePosition.y - 1][piecePosition.x - 1])){
moves.push({node: update(board, piecePosition, {x: piecePosition.x - 1, y: piecePosition.y - 1}), to: {x: piecePosition.x - 1, y: piecePosition.y - 1}});
}
}
if(piecePosition.y + 1 < 8 && piecePosition.x + 1 < 8){
if(board[piecePosition.y + 1][piecePosition.x + 1] == "vacant" || !isItemInArray(pieceType, board[piecePosition.y + 1][piecePosition.x + 1])){
moves.push({node: update(board, piecePosition, {x: piecePosition.x + 1, y: piecePosition.y + 1}), to: {x: piecePosition.x + 1, y: piecePosition.y + 1}});
}
}
if(piecePosition.y + 1 < 8 && piecePosition.x - 1 >= 0){
if(board[piecePosition.y + 1][piecePosition.x - 1] == "vacant" || !isItemInArray(pieceType, board[piecePosition.y + 1][piecePosition.x - 1])){
moves.push({node: update(board, piecePosition, {x: piecePosition.x - 1, y: piecePosition.y + 1}), to: {x: piecePosition.x - 1, y: piecePosition.y + 1}});
}
}
if(piecePosition.y - 1 >= 0 && piecePosition.x + 1 < 8){
if(board[piecePosition.y - 1][piecePosition.x + 1] == "vacant" || !isItemInArray(pieceType, board[piecePosition.y - 1][piecePosition.x + 1])){
moves.push({node: update(board, piecePosition, {x: piecePosition.x + 1, y: piecePosition.y - 1}), to: {x: piecePosition.x + 1, y: piecePosition.y - 1}});
}
}
return moves;
}
function queenMoves(piecePosition, board){
let castleMovesForQueen = castleMoves(piecePosition, board);
let bishopMovesForQueen = bishopMoves(piecePosition, board);
let moves = castleMovesForQueen.concat(bishopMovesForQueen);
return moves;
}
function getUncheckedMoves(piecePosition, board){
let boardPosition = board[piecePosition.y][piecePosition.x];
if(isItemInArray(pawns, boardPosition)){
unCheckedMoves = pawnMoves(piecePosition, board);
} else if(isItemInArray(castles, boardPosition)){
unCheckedMoves = castleMoves(piecePosition, board);
} else if(boardPosition == whiteBishop || boardPosition == blackBishop){
unCheckedMoves = bishopMoves(piecePosition, board);
} else if(boardPosition == whiteQueen || boardPosition == blackQueen){
unCheckedMoves = queenMoves(piecePosition, board);
} else if(boardPosition == whiteKing || boardPosition == blackKing){
unCheckedMoves = kingMoves(piecePosition, board);
} else {
unCheckedMoves = horseMoves(piecePosition, board);
}
return {from: piecePosition, move: unCheckedMoves};
}
function getValidMoves(piecePosition, board){
let unfilteredMoveSet = getUncheckedMoves(piecePosition, board);
let boardPos = board[piecePosition.y][piecePosition.x]
let pieceType = getPieceType(piecePosition, board);
for(index = unfilteredMoveSet.move.length - 1; index >= 0; index--){
if(isPlayerInCheck(pieceType, unfilteredMoveSet.move[index].node)){
unfilteredMoveSet.move.splice(index, 1);
}
}
if(castlingMoves(pieceType, board).length && (boardPos == whiteKing || boardPos == blackKing)){
unfilteredMoveSet.move.push(castlingMoves(pieceType, board));
}
return unfilteredMoveSet;
}