我想在我的网站上为我的学生制作一个国际象棋拼图。 我用鳕鱼干.js来玩引擎。 如何更改板上的起始位置? 我尝试更改所有 FEN 字符串,但没有工作。 在哪里寻找功能或其他东西? 有人可以帮助我吗?
与Stockfish的javascript端口进行交互(在撰写本文时(仍然像与使用/支持UCI(通用国际象棋接口(的国际象棋引擎进行通信一样。
UCIposition
命令就足够了:
var fenString = "rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq - 0 2"
// start UCI
stockfish.postMessage("uci");
// start new game
stockfish.postMessage("ucinewgame");
// set new game position
stockfish.postMessage("position fen " + fenString);
// start search
stockfish.postMessage("go depth 10");
已编辑:更新了 postMessage(( 函数的大小写。
我正在做同样的事情并弄清楚了——这绝不是显而易见的,在鳕鱼干的例子中有很多小旅行和陷阱。我在网上找到了几个问题,我想我会给他们一些答案。
所以 - 这个答案假设使用这里找到的示例代码:https://github.com/nmrugg/stockfish.js/tree/Stockfish11/example。
需要进行两个主要修改 - 第一个在index.html
文件中,第二个在enginegame.js
中。
首先,我们将定义一个帮助程序函数,该函数将使其易于处理称为 url "search">
:function searchToObject() {
var pairs = window.location.search.substring(1).split("&"),
obj = {},
pair,
i;
for ( i in pairs ) {
if ( pairs[i] === "" ) continue;
pair = pairs[i].split("=");
obj[ decodeURIComponent( pair[0] ) ] = decodeURIComponent( pair[1] );
}
return obj;
}
为了方便起见,我只是将该函数放在两个文件中,index.html
它位于脚本标签的开头,enginegame.js
它是第一行。顺便说一句,我当然是从堆栈溢出中窃取的,但我似乎再也找不到那个答案了,老鼠。
index.html
newGame
函数希望看起来像这样:
newGame = function newGame() {
var baseTime = parseFloat($('#timeBase').val()) * 60;
var inc = parseFloat($('#timeInc').val());
var skill = parseInt($('#skillLevel').val());
game.reset();
let search = searchToObject();
if (search.player) {
game.setPlayerColor(search.player)
} else {
game.setPlayerColor($('#color-white').hasClass('active') ? 'white' : 'black');
}
if (search.fen) {
game.game.load(search.fen);
game.board.position(game.game.fen());
}
game.setTime(baseTime, inc);
game.setSkillLevel(skill);
game.setDisplayScore($('#showScore').is(':checked'));
game.start();
}
请注意 game.game 和 game.board -- 它们需要添加到返回对象的enginegame.js
中。如果我写这篇文章,我会以不同的方式做,但我没有耐心重命名东西。
接下来在enginegame.js
我们需要调整prepareMove
.
function prepareMove() {
stopClock();
$('#pgn').text(game.pgn());
board.position(game.fen());
updateClock();
var turn = game.turn() == 'w' ? 'white' : 'black';
if (!game.game_over()) {
if (turn != playerColor) {
let search = searchToObject();
if (search.fen) {
uciCmd('position fen ' + search.fen + ' moves ' + get_moves());
} else {
uciCmd('position startpos moves' + get_moves());
uciCmd('position startpos moves' + get_moves(), evaler);
}
evaluation_el.textContent = "";
uciCmd("eval", evaler);
if (time && time.wtime) {
uciCmd("go " + (time.depth ? "depth " + time.depth : "") + " wtime " + time.wtime + " winc " + time.winc + " btime " + time.btime + " binc " + time.binc);
} else {
uciCmd("go " + (time.depth ? "depth " + time.depth : ""));
}
isEngineRunning = true;
}
if (game.history().length >= 2 && !time.depth && !time.nodes) {
startClock();
}
}
}
看,诀窍在于,如果有一个 fen 字符串来启动游戏,那么每个后续position
调用都需要不同。我想这可能是让大多数人绊倒的原因——这绝对是让我失望的原因。
对我有帮助的是通读 UCI 文档。在此之前,我的董事会处于某种疯狂的无限循环中。
我偶然发现的一个奇怪但关键的一点是index.html
文件中的game.game.load(<fen string>)
函数调用。我找不到任何文档。我什至不记得我是如何找到它的。但它就是这样!