在我的一生中,我似乎无法设置河豚去做任何事情,除了在20级发出毁灭性的打击。下面是为配置河豚的技能水平和深度而设置的代码,以及代码执行的UCI命令的顺序。
这段代码在javascript中,但使用UCI就像最初的开源实现一样。我遵循的例子是:https://github.com/nmrugg/stockfish.js/blob/2b87d5d16a613f3ce05b1dd0bbb58465501ed30a/example/enginegame.js#L38。
Stockfish.js
import _ from 'lodash';
import ChessBoardState from './ChessBoardState';
import Move from './Move';
class Stockfish {
constructor() {
this.bestMove = null;
this.skill = null;
this.depth = null;
this.isThinking = false;
this.engineStatus = {};
this.stockfish = new Worker('stockfish.js');
this.stockfish.onmessage = (event) => {
const line = event && typeof event === 'object' ? event.data : event;
console.log('Stockfish: ', line);
if (line === 'uciok') {
this.engineStatus.engineLoaded = true;
} else if (line === 'readyok') {
this.engineStatus.engineReady = true;
} else {
const match = line.match('^bestmove ([a-h][1-8])([a-h][1-8])([qrbn])?');
if (match) {
this.bestMove = new Move(match[1], match[2], match[3] ? match[3] : null);
this.isThinking = false;
}
}
}
this.stockfish.postMessage('uci');
this.stockfish.postMessage('isready');
this.stockfish.postMessage('ucinewgame');
}
isEngineLoaded() {
return this.engineStatus.engineLoaded;
}
/**
* Update engine state to fenCode.
* @param {string} fenCode
*/
setFEN(fenCode) {
if (!this.engineStatus.engineLoaded) {
throw new Error('Engine not loaded');
}
this.stockfish.postMessage(`position fen ${fenCode}`);
}
/**
* Update engine depth
* @param {number} depth
*/
setDepth(depth) {
console.log(depth);
this.depth = _.clamp(depth, 1, 20);
}
/**
* Update engine skill level
* @param {number} skill
*/
setSkillLevel(skillLevel) {
if (!this.engineStatus.engineLoaded) {
throw new Error('Engine not loaded');
}
skillLevel = _.clamp(skillLevel, 0, 20);
console.log(skillLevel);
this.stockfish.postMessage(`setoption name Skill Level value ${skillLevel}`);
// Stockfish level 20 does not make errors (intentially), so these numbers have no effect on level 20.
// Level 0 starts at 1
const err_prob = Math.round((skillLevel * 6.35) + 1);
// Level 0 starts at 10
const max_err = Math.round((skillLevel * -0.5) + 10);
this.stockfish.postMessage(`setoption name Skill Level Maximum Error value ${max_err}`);
this.stockfish.postMessage(`setoption name Skill Level Probability value ${err_prob}`);
this.skillLevel = skillLevel;
}
/**
* Start churning for best move.
* @param {ChessBoardState} chessBoardState
* @param {number} depth
*/
searchBestMove(chessBoardState) {
this.bestMove = null;
this.isThinking = true;
this.setFEN(chessBoardState.toFEN());
this.stockfish.postMessage(`go depth ${this.depth}`);
}
/**
* Returns best move if one has been found.
*/
getBestMove() {
return this.isThinking ? null : this.bestMove;
}
}
export default StockfishChessGameUI.js (...用于表示无关代码)
...
const stockfish = new Stockfish()
this.state = {
...
stockfish: stockfish,
stockfishSkillLevel: 0,
stockfishDepth: 1,
}
...
this.intID = setInterval(() => {
this.state.stockfish.setSkillLevel(this.state.stockfishSkillLevel);
this.state.stockfish.setDepth(this.state.stockfishDepth);
...
const bestMove = this.state.stockfish.getBestMove();
if (!bestMove && !this.state.stockfish.isThinking) {
this.state.stockfish.searchBestMove(this.state.chessBoardState, this.state.stockfishDepth);
} else if (bestMove) {
this.state.chessBoardState.move(bestMove)
this.state.stockfish.bestMove = null;
this.setState(prev => ({
...prev,
chessBoardState: ChessBoardState.fromFEN(this.state.chessBoardState.toFEN()),
}));
}
}, 500);理论上,这段代码应该尝试每半秒积极地设置技能级别和深度,同时从Stockfish轮询一个新的bestMove。但这些设置似乎对发动机的难度没有任何影响。
调用(按顺序)的UCI命令:
uci
isready
ucinewgame
setoption name Skill Level value 0
setoption name Skill Level Maximum Error value 1
setoption name Skill Level Probability Value 10
position fen rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1
go depth 1发布于 2021-12-17 16:42:01
试着用这个,它对我有用:
const stockfish = new Worker('/stockfish.js');
stockfish.postMessage('uci');
stockfish.postMessage('ucinewgame');
stockfish.postMessage('setoption name Skill Level value 3');
stockfish.postMessage('setoption name Skill Level Maximum Error value 600');
stockfish.postMessage('setoption name Skill Level Probability value 128');
stockfish.postMessage('position fen ' + chess.fen());
stockfish.postMessage('go depth 10');https://stackoverflow.com/questions/66425952
复制相似问题