简体   繁体   English

是什么导致此事件处理程序继续运行?为什么当我尝试添加条件时它会停止?

[英]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 上有实时版本,您可以查看它是否工作(或不工作):

I'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.

相关问题 为什么当我将@action 装饰器添加到反应事件处理程序 function 时组件不重新渲染 - Why does the component is not re-rendering when i add @action decorator to an react event handler function 为什么在尝试清理事件处理程序时,该事件处理程序代码会中断? - Why does this event handling code for ender break when I try to clean it up some? 为什么当我尝试将事件变量作为参数提供给 function 时,JS 会划掉事件变量? - Why does JS cross out the event variable when I try to give it to an function as an argument? 为什么该事件处理程序不在范围内时可以访问类属性? - Why does this event handler have access to the class properties when it is not in scope? 当条件为假时,为什么这个 for 循环会不断增加? - Why does this for loop keep incrementing when the condition is false? 为什么当我使用 keydown 事件时我的游戏角色不断加速? - Why does my game character keep accelerating when I use the keydown event? 为什么当我尝试将 jQuery 中继器的添加按钮放在 tr td 上时它不起作用? - Why does jQuery repeater's add button not working when I try to placed it on tr td? 一旦在 JavaScript 中满足条件,我将如何使事件处理程序函数中的被调用函数无法运行? - How would I void a called function within an event Handler function from running once a condition is met in JavaScript? 当我向事件处理函数添加参数时,“此”发生变化 - “this” changes when I add parameters to event handler function 当我为它分配一个超时处理程序时,为什么 resize 事件会不断触发? - Why is the resize event constantly firing when I assign it a handler with a timeout?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM