[英]What causes this event handler to keep running?, and why does it halt when I try to add a condition?
I'm making a chess opening trainer.我正在做一个国际象棋开场教练。 I have a working game using cm-chessboard based on an example, and I'm using an API to get the computer's moves.我有一个基于示例的使用cm-chessboard的工作游戏,并且我正在使用 API 来获取计算机的移动。 I have condensed my code and removed this API so it's easier to read.我已经压缩了我的代码并删除了这个 API,所以它更容易阅读。 In this version, the computer makes random moves from all valid chess moves.在这个版本中,计算机从所有有效的国际象棋移动中随机移动。
The idea is, the API gets the best move, and then the player tries to input that move by moving a piece.这个想法是,API 获得最佳移动,然后玩家尝试通过移动棋子来输入该移动。 If the player is correct, the computer moves for their next go, but if the player incorrectly guesses the best move, they are told 'Incorrect.'如果玩家是正确的,计算机会为他们的下一个 go 移动,但如果玩家猜错了最佳移动,他们会被告知“不正确”。 and are able to try again.并且能够再试一次。
However, my code works fine when they are correct, but breaks when they are incorrect.但是,我的代码在正确时可以正常工作,但在错误时会中断。
Here's what I have done:这是我所做的:
<!-- Condensed Version -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Chess Opening Trainer</title>
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0"/>
<link rel="stylesheet" href="https://alftheelf.github.io/Chess-Trainer/cm-chessboard/styles/cm-chessboard.css"/>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500&display=swap" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/chess.js/0.10.2/chess.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div class="board" id="board" style="width: 800px; max-width: 800px;"></div>
<script type="text/javascript">
function getBestMove(fen){
//This function has been simplified
var bestMove = "e5"
return bestMove
}
</script>
<script type="module">
var DATA;
var side = 'black' //select which side to play as
import {INPUT_EVENT_TYPE, COLOR, Chessboard, MARKER_TYPE} from "https://alftheelf.github.io/Chess-Trainer/cm-chessboard/src/cm-chessboard/Chessboard.js"
import {BORDER_TYPE} from "https://alftheelf.github.io/Chess-Trainer/cm-chessboard/src/cm-chessboard/Chessboard.js"
const chess = new Chess() //Creates a new Chess() object. Add a FEN string as an argument to start from a paticular FEN.
function inputHandler(event) {
console.log("event", event)
event.chessboard.removeMarkers(undefined, MARKER_TYPE.dot)
//Before move. Clicking about, and showing dot for possible moves and such.
if (event.type === INPUT_EVENT_TYPE.moveStart) {
const moves = chess.moves({square: event.square, verbose: true});
for (const move of moves) {
event.chessboard.addMarker(move.to, MARKER_TYPE.dot)
}
return moves.length > 0
//Here is once a move has been attempted
} else if (event.type === INPUT_EVENT_TYPE.moveDone) {
const move = {from: event.squareFrom, to: event.squareTo} //gets which move was attempted from event
const result = chess.move(move) //gets result of move
var correctAnswer = getBestMove(chess.fen());
if (result.san == correctAnswer){console.log('correct!')}else{console.log('Incorrect!')}
//Makes moves for the player
if (result && result.san == correctAnswer) {
event.chessboard.disableMoveInput()
event.chessboard.setPosition(chess.fen())
//Makes moves for the computer
const possibleMoves = chess.moves({verbose: true})
if (possibleMoves.length > 0) {
const randomIndex = Math.floor(Math.random() * possibleMoves.length)
const randomMove = possibleMoves[randomIndex]
setTimeout(() => { // smoother with 500ms delay
chess.move({from: randomMove.from, to: randomMove.to})
if(side === 'white') {
event.chessboard.enableMoveInput(inputHandler, COLOR.white)
}
else {
event.chessboard.enableMoveInput(inputHandler, COLOR.black)
}
event.chessboard.setPosition(chess.fen())
}, 500)
}
} else { //If result returns null, then we will loop back to the begining of the function to have another go.
console.warn("invalid move", move)
}
return result
}
}
if (side == 'white'){
const board = new Chessboard(document.getElementById("board"), {
position: chess.fen(),
sprite: {url: "https://alftheelf.github.io/Chess-Trainer/cm-chessboard/assets/images/chessboard-sprite-staunty.svg"},
style: {moveMarker: MARKER_TYPE.square, hoverMarker: undefined},
orientation: COLOR.white
})
board.enableMoveInput(inputHandler, COLOR.white)
}
else{
const board = new Chessboard(document.getElementById("board"), {
position: chess.fen(),
sprite: {url: "https://alftheelf.github.io/Chess-Trainer/cm-chessboard/assets/images/chessboard-sprite-staunty.svg"},
style: {moveMarker: MARKER_TYPE.square, hoverMarker: undefined},
orientation: COLOR.black
})
const possibleMoves = chess.moves({verbose: true})
if (possibleMoves.length > 0) {
const randomIndex = Math.floor(Math.random() * possibleMoves.length)
const randomMove = possibleMoves[randomIndex]
setTimeout(() => { // smoother with 500ms delay
chess.move({from: randomMove.from, to: randomMove.to});
board.enableMoveInput(inputHandler, COLOR.black)
board.setPosition(chess.fen())
}, 500)
}
}
</script>
</body>
</html>
I've made a simple function, getBestMove(fen)
to replace what the API would do to get the next best move.我做了一个简单的 function, getBestMove(fen)
来代替 API 会做的事情,以获得下一个最佳移动。 In this case I want the first move to be "pawn e5", after that, all moves will be incorrect, but it should allow me to keep trying to find the correct move instead of halting.在这种情况下,我希望第一个动作是“pawn e5”,之后所有的动作都是不正确的,但它应该允许我继续尝试找到正确的动作而不是停下来。
I'm not sure I'm understanding how this event loop repeats.我不确定我是否理解这个事件循环是如何重复的。 At first I thought the function was being called with the line event.chessboard.enableMoveInput(inputHandler, COLOR.black)
but after a while I realised that it still loops even if result == null
and so I'm very confused.起初我以为 function 是用event.chessboard.enableMoveInput(inputHandler, COLOR.black)
行调用的,但过了一会儿我意识到即使result == null
它仍然循环,所以我很困惑。
I have live versions on Github you can check out to see it working (or not working):我在 Github 上有实时版本,您可以查看它是否工作(或不工作):
getBestMove()
(working): https://alftheelf.github.io/Chess-Trainer/original.html没有getBestMove()
原始版本(工作): https://alftheelf.github.io/Chess-Trainer/original.ZFC35FDC70D5FC69D2698Z83A822C7A53EI've tried this so many ways for the last couple of days.在过去的几天里,我尝试了很多方法。 I think I'm missing something because this is the most advanced Javascript project I've ever done (I'm learning so much though).我想我遗漏了一些东西,因为这是我做过的最先进的 Javascript 项目(不过我学到了很多东西)。
I've tried debugging with a browser, but it's very confusing and I couldn't work anything out that way.我曾尝试使用浏览器进行调试,但它非常令人困惑,我无法以这种方式解决任何问题。
What do I need to do to get this working?我需要做什么才能使它正常工作? What exactly is it in the original version that calls the function again so the player can play another move, but doesn't allow this in the edited version?在原始版本中究竟是什么再次调用 function 以便玩家可以下一个动作,但在编辑版本中不允许这样做? I don't get it.我不明白。
I played around a bit and I was able to use this to get it to work.我玩了一会儿,我可以用它来让它工作。 This is around line 90 of your code.这大约是代码的第 90 行。 It uses your code to check if the move is not the correct one and resets it back until you do the correct move它使用您的代码检查移动是否不正确并将其重置,直到您执行正确的移动
else { //If result returns null, then we will loop back to the
//begining of the function to have another go.
chess.undo();
event.chessboard.setPosition(chess.fen());
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.