如何在不手动单击屏幕以激发事件的情况下进入事件处理程序



我正在使用cm棋盘创建一个国际象棋开局训练游戏。我会控制一边,最终我会让电脑移动特定的开口。

cm棋盘有一个示例页面,我从这个最接近我最终想法的示例开始。此时,计算机从一组可能的移动中随机移动。

github的例子只在white的一边播放过。我已经调整了代码,允许黑人玩。然而,当游戏开始时,我正在玩黑色游戏,我必须点击一个黑色棋子来刺激一个事件,该事件会导致白色做出第一步动作,然后我们继续玩。这是因为白色总是排在第一位。

这是我的代码:

<!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="/cm-chessboard/styles/cm-chessboard.css"/> 
<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>
<div id="output"></div>
<script type="module">

var side = 'black'
if (side == 'white'){var colour = 'w'}else{var colour = 'b'}

import {INPUT_EVENT_TYPE, COLOR, Chessboard, MARKER_TYPE} from "/cm-chessboard/src/cm-chessboard/Chessboard.js"
import {BORDER_TYPE} from "/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 FEN.
var oneTimeBool = true;
function inputHandler(event) {
console.log("event", event)
event.chessboard.removeMarkers(undefined, MARKER_TYPE.dot)
//Do this only once
if (oneTimeBool == true && side == 'black'){
event.chessboard.disableMoveInput()
event.chessboard.setPosition(chess.fen())
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})
event.chessboard.enableMoveInput(inputHandler, colour)
event.chessboard.setPosition(chess.fen())
}, 500)
}
oneTimeBool = false;
}
//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

if (result) { //if result is anyting then we processed
event.chessboard.disableMoveInput()
event.chessboard.setPosition(chess.fen())
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})
event.chessboard.enableMoveInput(inputHandler, colour)
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 with new dots.
console.warn("invalid move", move)
}
return result
}
}
const board = new Chessboard(document.getElementById("board"), {
position: chess.fen(),
sprite: {url: "/cm-chessboard/assets/images/chessboard-sprite-staunty.svg"},
style: {moveMarker: MARKER_TYPE.square, hoverMarker: undefined},
orientation: colour
})
board.enableMoveInput(inputHandler, colour)

</script>
</body>
</html>

我知道,情况很糟糕。我相信还有更优雅的方法可以做到这一点。

我的问题是,当board.enableMoveInput(inputHandler_black, COLOR.black)调用inputhandler_black函数时,该函数会等待事件开始。当我打成白色并且inputHandler_white被调用时,这很好,因为无论如何我都必须做出第一步。当我玩黑色游戏时,我希望计算机自动播放该动作,而无需单击随机的黑色棋子即可启动。

有人知道我该怎么做吗?有没有一种方法可以在不使用鼠标手动创建事件的情况下以某种方式强制它进入函数?

此代码段针对玩家进行移动,因此当玩家为黑色时,您应该首先运行此代码段(在棋盘初始化后(。

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)
}

这是整个代码:

<!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="/cm-chessboard/styles/cm-chessboard.css"/> 
<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>
<div id="output"></div>
<script type="module">
import {INPUT_EVENT_TYPE, COLOR, Chessboard, MARKER_TYPE} from "/cm-chessboard/src/cm-chessboard/Chessboard.js"
import {BORDER_TYPE} from "/cm-chessboard/src/cm-chessboard/Chessboard.js"
const side = 'black' //select which side to play as
const chess = new Chess() //Creates a new Chess() object. Add a FEN string as an argument to start from a 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

if (result) { //if result is anyting then we processed
event.chessboard.disableMoveInput()
event.chessboard.setPosition(chess.fen())
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 with new dots.
console.warn("invalid move", move)
}
return result
}
}

if (side == 'white'){
const board = new Chessboard(document.getElementById("board"), {
position: chess.fen(),
sprite: {url: "/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: "/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)
}
console.log(board)
}
</script>
</body>
</html>

相关内容

最新更新