[英]How can I get inside my event handler without manually clicking the screen to stimulate an event?
我正在使用cm-chessboard创建一个国际象棋开场教练游戏。 我将控制一侧,最终我会让计算机移动特定的开口。
cm-chessboard 有一个示例页面,我从这个最接近我最终想法的示例开始。 目前,计算机从一组可能的移动中随机移动。
github 的例子只在白方播放。 我已经调整了代码以允许黑色播放。 然而,当游戏开始并且我在玩黑棋时,我必须点击一个黑棋来激发一个导致白棋迈出第一步的事件,然后我们从那里继续游戏。 这是因为白色总是先行。
这是我的代码:
<!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
function 时,function 等待事件才能开始。 当我扮演白棋并inputHandler_white
时,这很好,因为无论如何我都必须迈出第一步。 当我玩黑棋时,我希望计算机自动下棋,而不必单击随机的黑棋子来启动它。
有谁知道我该怎么做? 有没有办法以某种方式强制它进入 function 而无需使用鼠标手动创建事件?
此代码段对玩家进行移动,因此您应该在玩家为黑色时最初(在棋盘初始化之后)运行此代码段。
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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.