Socket.io国际象棋检查控制

huangapple go评论62阅读模式
英文:

Socket.io chess check control

问题

以下是给出的代码片段的翻译:

  1. onDrop(source, target): 当在棋盘上放置棋子时触发此函数。它执行与游戏逻辑相关的各种操作,如确定当前玩家的轮次,验证移动,执行移动,发出事件以更新游戏状态,检查是否将军以及更新用户界面。

  2. removeGreySquares(): 调用此函数以移除棋盘上可能用于指示玩家有效移动的灰色高亮显示。

  3. engine.getSide(): 此函数返回当前玩家的一方(颜色)。

  4. engine.promotedToString(promotedPiece): 此函数将升变的棋子代码转换为其字符串表示形式。它用于表示兵升变移动。

  5. engine.moveFromString(move): 此函数接受象棋符号表示法中的移动字符串,并返回如果是有效移动则返回数字移动,否则返回0。

  6. engine.generateLegalMoves(): 此函数生成棋盘上当前位置的所有合法移动。

  7. engine.makeMove(validMove): 此函数根据传递的有效移动在棋盘上执行移动。

  8. engine.printBoard(): 此函数打印棋盘的当前状态。

  9. engine.generateFen(): 此函数生成表示棋盘上当前位置的Forsyth-Edwards符号(FEN)字符串。

  10. socket.emit('makeMove', { source, target, fen }): 此行使用WebSocket(socket.io)发出'makeMove'事件,向服务器发送源方格、目标方格和FEN字符串。

  11. playSound(soundFile): 此函数播放位于'Sounds'目录中的声音文件。

  12. socket.on('checkControl', (data) => { ... }): 此事件处理程序从服务器接收'checkControl'事件,当游戏中发生将军条件时会触发它。它触发redSquare函数,并根据将军信息执行进一步的操作。

  13. sendCheck(message, checkCoord): 此函数发出'check'事件到服务器,发送消息和被检查的方格的坐标。

  14. engine.inCheck(): 此函数基于当前玩家的颜色[白色:0,黑色:1]返回true或false。

这些函数一起处理在线国际象棋游戏中的游戏逻辑、用户界面更新和与服务器的通信。

关于前端代码中的sendCheck函数在游戏中的问题,如果在浏览器的控制台中手动执行该函数时,信号能够正确地传达到后端,并且后端通过io.emit响应另一位用户,完成了将军控制的过程。然而,当使用onDrop函数进行互动游戏时,这个序列并没有发生。事实上,在onDrop函数中没有信号传达到后端。可能的原因是什么?下面是与sockets相关的后端代码。

socket.on('check', (data) => {
    io.to(user.room).emit('checkControl', { message: data.message, checkCoord: data.checkCoord })
    console.log(data.message, data.checkCoord)
})

请注意,我已根据您的要求仅提供代码的翻译和相关解释,没有额外的回答。

英文:

The given code snippet is a JavaScript function that handles the dropping of a chess piece in an online chess game. Here is a brief explanation of the functions present in the code:

  1. onDrop(source, target): This function is triggered when a chess piece is dropped on the board. It performs various actions related to the game logic, such as determining the current player's turn, validating the move, making the move, emitting events to update the game state, checking for checks, and updating the user interface.

  2. removeGreySquares(): This function is called to remove any gray highlighting on the chessboard, which might have been used to indicate valid moves for the player.

  3. engine.getSide(): This function returns the side (color) of the current player.

  4. engine.promotedToString(promotedPiece): This function converts a promoted piece code to its string representation. It is used to represent a pawn promotion move.

  5. engine.moveFromString(move): This function takes a move string in algebraic notation and returns a numeric move if it is a valid move, or 0 if it is an invalid move.

  6. engine.generateLegalMoves(): This function generates all legal moves for the current position in the chess engine.

  7. engine.makeMove(validMove): This function makes a move on the chessboard based on the valid move passed as an argument.

  8. engine.printBoard(): This function prints the current state of the chessboard.

  9. engine.generateFen(): This function generates the Forsyth–Edwards Notation (FEN) string representing the current position on the chessboard.

  10. socket.emit('makeMove', { source, target, fen }): This line emits a 'makeMove' event using the WebSocket (socket.io) to send the source square, target square, and the FEN string to the server.

  11. playSound(soundFile): This function plays a sound file located in the 'Sounds' directory.

  12. socket.on('checkControl', (data) => { ... }): This event handler receives the 'checkControl' event from the server, which is emitted when a check condition occurs in the game. It triggers the redSquare function and performs further actions based on the check information.

  13. sendCheck(message, checkCoord): This function emits a 'check' event to the server, sending a message and the coordinates of the checked square.

  14. engine.inCheck():This function returns true or false based on the color [white:0,black:1] of the current player.

// on dropping piece
function onDrop(source, target) {
  console.log(informationArea);
  let currentPlayerColor;
  if (socket.id=== informationArea.roomOwnerSocketId&&localStorage.getItem('sessionId')===informationArea.roomOwnerSessionId) {
    currentPlayerColor = informationArea.roomOwnerColor;
  }
  else if(socket.id=== informationArea.roomFirstOpponent&&localStorage.getItem('sessionId')===informationArea.roomOpponentSessionId) {
    currentPlayerColor = informationArea.roomOpponentColor;
  }
  if(!currentPlayerColor){
    return;
  }
  let isPlayerTurn = (engine.getSide() === (currentPlayerColor === "white" ? 0 : 1));

  if (!isPlayerTurn) {
    return;
  }
  removeGreySquares();

  let promotedPiece = (engine.getSide() ? (5 + 6) : 5) // queen promotion only for now
  let move = source + target + engine.promotedToString(promotedPiece);
  let validMove = engine.moveFromString(move);

  console.log('user move', promotedPiece);

  // invalid move
  if (validMove == 0) return 'snapback';

  let legalMoves = engine.generateLegalMoves();
  let isLegal = 0;

  for (let count = 0; count < legalMoves.length; count++) {
    if (validMove == legalMoves[count].move) isLegal = 1;
  }

  // illegal move
  if (isLegal == 0) {return 'snapback'}
  
 
  //updateStatus();
  
  // make user move
  engine.makeMove(validMove);
  engine.printBoard();
  playSound('move.wav');
  let fen=engine.generateFen()
  socket.emit('makeMove', { source, target, fen});
  // make engine move
  var moves = board.move({
    verbose: true
  })
  
  let checkControl = localStorage.getItem('playerColor') === "white" ? 0 : 1;
  if(engine.inCheck(checkControl)){
    for (var key in moves) {
      console.log(moves[key])
      if (moves.hasOwnProperty(key)) {
        if (moves[key] === "wK"&& checkControl===0) {
          // "wK" taşının konumu key'de bulunuyor
          console.log("wK taşı bulundu! Konum: " + key);
          redSquare(key);
          sendCheck('whitecheck',key)
        }
        else if(moves[key] === "bK"&& checkControl===1){
          console.log("bK taşı bulundu! Konum: " + key);
          redSquare(key);
          sendCheck('blackcheck',key);
          
       
        }
      }
    }
    
  }

  console.log(engine.generateFen());
  $fen.html(engine.generateFen());

  // TODO: update game status
  // isGameOver();
}
function sendCheck(message,checkCoord){
  socket.emit('check',{message:message,checkCoord:checkCoord});
}

function playSound(soundFile) {
  var audio = new Audio('./Sounds/' + soundFile);
  audio.play();
}

socket.on('checkControl',(data)=>{
  console.log(data.message)
    redSquare(data.checkCoord);
})

These functions together handle the game logic, user interface updates, and communication with the server in an online chess game.
I have a problem related to the sendCheck function in the frontend code I shared with you above. When I manually execute this function in the browser's console, the signal reaches the backend correctly, and the backend responds to the other user with an io.emit, completing the checkControl process. As a result, the background of the piece in the specified coordinates turns red. However, this sequence doesn't happen when playing the game interactively using the onDrop function. In fact, no signal reaches the backend during the onDrop function. What could be the reason for this? I'm also sharing the backend code that is related on that sockets in below.

socket.on('check',(data)=>{
            io.to(user.room).emit('checkControl', { message: data.message, checkCoord: data.checkCoord })
            console.log(data.message,data.checkCoord)
          })

答案1

得分: 0

我理解了问题,并感谢您帮助 @RokoC.Buljan。我现在不是检查对手的国王是否被将军,而是在检查我的棋盘。这就是算法不正确的原因。以下是我如何解决这个问题的方式:

我意识到通过颠倒逻辑,我可以检查对手的棋盘是否受到威胁。所以,我进行了以下更改:

从:

let checkControl = localStorage.getItem('playerColor') === "white" ? 0 : 1;

到:

let checkControl = localStorage.getItem('playerColor') === "white" ? 1 : 0;

通过进行这个改变,期望的触发事件发生了,并且信号传达到了后端。

英文:

I understood the problem and appreciated it for helping @RokoC.Buljan . Instead of checking whether the opponent's king is in check, I am currently checking my own board. This is why the algorithm is incorrect. Here's how I solved the problem:

I realized that by reversing the logic, I can check if the opponent's board is being threatened or not. So, I made the following change:

From:

let checkControl = localStorage.getItem('playerColor') === "white" ? 0 : 1;

To:

let checkControl = localStorage.getItem('playerColor') === "white" ? 1 : 0;

By making this change, the expected trigger occurs, and the signal reaches the backend.

huangapple
  • 本文由 发表于 2023年5月28日 04:13:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76348856.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定