consolidate puzzle dests

pull/6261/head
Niklas Fiekas 2020-03-30 22:50:35 +02:00
parent af6c5888cd
commit d109deb664
9 changed files with 27 additions and 85 deletions

View File

@ -25,7 +25,7 @@
"chat": "2.0.0",
"chess": "2.0.0",
"chessground": "^7.6",
"chessops": "^0.3.4",
"chessops": "^0.3.5",
"common": "2.0.0",
"game": "2.0.0",
"nvui": "2.0.0",

View File

@ -24,7 +24,7 @@
},
"dependencies": {
"chess": "2.0.0",
"chessops": "^0.3.4",
"chessops": "^0.3.5",
"common": "2.0.0",
"snabbdom": "ornicar/snabbdom#0.7.1-lichess"
}

View File

@ -1,5 +1,4 @@
import { piotr } from './piotr';
export { uciCharPair } from './ucicharpair';
export const initialFen: Fen = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1';

View File

@ -1,34 +0,0 @@
type Square = number;
type Role = 'pawn' | 'knight' | 'bishop' | 'rook' | 'queen' | 'king';
interface UciMove {
from: Square;
to: Square;
promotion?: Role;
}
interface UciDrop {
role: Role;
to: Square;
}
type Uci = UciMove | UciDrop;
function square(sq: Square): number {
return 35 + sq;
}
function drop(role: Role): number {
return 35 + 64 + 8 * 5 + ['queen', 'rook', 'bishop', 'knight', 'pawn'].indexOf(role);
}
function promotion(file: number, role: Role): number {
return 35 + 64 + 8 * ['queen', 'rook', 'bishop', 'knight', 'king'].indexOf(role) + file;
}
export function uciCharPair(uci: Uci): string {
if ('role' in uci) return String.fromCharCode(square(uci.to), drop(uci.role));
else if (!uci.promotion) return String.fromCharCode(square(uci.to), square(uci.from));
else return String.fromCharCode(square(uci.from), promotion(uci.to & 7, uci.promotion));
}

View File

@ -17,7 +17,7 @@
},
"dependencies": {
"chessground": "^7.6",
"chessops": "^0.3.4",
"chessops": "^0.3.5",
"snabbdom": "ornicar/snabbdom#0.7.1-lichess",
"common": "2.0.0"
}

View File

@ -21,7 +21,7 @@
"ceval": "2.0.0",
"chess": "2.0.0",
"chessground": "^7.6",
"chessops": "^0.3.4",
"chessops": "^0.3.5",
"common": "2.0.0",
"snabbdom": "ornicar/snabbdom#0.7.1-lichess",
"tree": "2.0.0"

View File

@ -1,7 +1,6 @@
import { build as treeBuild, ops as treeOps, path as treePath, TreeWrapper } from 'tree';
import { ctrl as cevalCtrl, CevalCtrl } from 'ceval';
import { readDests, decomposeUci, sanToRole } from 'chess';
import { opposite } from 'chessground/util';
import { decomposeUci, sanToRole } from 'chess';
import keyboard from './keyboard';
import socketBuild from './socket';
import moveTestBuild from './moveTest';
@ -14,6 +13,9 @@ import throttle from 'common/throttle';
import * as xhr from './xhr';
import * as speech from './speech';
import { sound } from './sound';
import { parseFen } from 'chessops/fen';
import { Chess } from 'chessops/chess';
import { chessgroundDests } from 'chessops/compat';
import { Config as CgConfig } from 'chessground/config';
import { Api as CgApi } from 'chessground/api';
import * as cg from 'chessground/types';
@ -83,13 +85,18 @@ export default function(opts: PuzzleOpts, redraw: Redraw): Controller {
history.replaceState(null, '', '/training/' + data.puzzle.id);
}
function position(): Chess {
const setup = parseFen(vm.node.fen).unwrap();
return Chess.fromSetup(setup).unwrap();
}
function makeCgOpts(): CgConfig {
const node = vm.node;
const color: Color = node.ply % 2 === 0 ? 'white' : 'black';
const dests = readDests(node.dests);
const dests = chessgroundDests(position());
const movable = (vm.mode === 'view' || color === data.puzzle.color) ? {
color: (dests && Object.keys(dests).length > 0) ? color : undefined,
dests: dests || {}
color: (Object.keys(dests).length > 0) ? color : undefined,
dests
} : {
color: undefined,
dests: {}
@ -106,13 +113,7 @@ export default function(opts: PuzzleOpts, redraw: Redraw): Controller {
lastMove: uciToLastMove(node.uci)
};
if (node.ply >= vm.initialNode.ply) {
if (!dests && !node.check) {
// premove while dests are loading from server
// can't use when in check because it highlights the wrong king
config.turnColor = opposite(color);
config.movable.color = color;
config.premovable.enabled = true;
} else if (vm.mode !== 'view' && color !== data.puzzle.color) {
if (vm.mode !== 'view' && color !== data.puzzle.color) {
config.movable.color = data.puzzle.color;
config.premovable.enabled = true;
}
@ -123,7 +124,6 @@ export default function(opts: PuzzleOpts, redraw: Redraw): Controller {
function showGround(g: CgApi): void {
g.set(makeCgOpts());
if (!vm.node.dests) getDests();
}
function userMove(orig: Key, dest: Key): void {
@ -142,14 +142,6 @@ export default function(opts: PuzzleOpts, redraw: Redraw): Controller {
socket.sendAnaMove(move);
}
var getDests = throttle(800, function() {
if (!vm.node.dests && treePath.contains(vm.path, vm.initialPath))
socket.sendAnaDests({
fen: vm.node.fen,
path: vm.path
});
});
function uciToLastMove(uci: string | undefined): [Key, Key] | undefined {
// assuming standard chess
return defined(uci) ? [uci.substr(0, 2) as Key, uci.substr(2, 2) as Key] : undefined;
@ -242,16 +234,6 @@ export default function(opts: PuzzleOpts, redraw: Redraw): Controller {
});
};
function addDests(dests, path: Tree.Path): void {
tree.addDests(dests, path);
if (path === vm.path) {
withGround(showGround);
// redraw();
if (gameOver()) ceval.stop();
}
withGround(function(g) { g.playPremove(); });
}
function instanciateCeval(): void {
if (ceval) ceval.destroy();
ceval = cevalCtrl({
@ -342,8 +324,10 @@ export default function(opts: PuzzleOpts, redraw: Redraw): Controller {
}
function gameOver(): false | 'checkmate' | 'draw' {
if (vm.node.dests !== '') return false;
return vm.node.check ? 'checkmate' : 'draw';
const pos = position();
if (pos.isCheckmate()) return 'checkmate';
if (pos.isInsufficientMaterial()) return 'draw';
return false;
}
function jump(path: Tree.Path): void {
@ -402,7 +386,6 @@ export default function(opts: PuzzleOpts, redraw: Redraw): Controller {
const socket = socketBuild({
addNode: addNode,
addDests: addDests,
reset: function() {
withGround(showGround);
redraw();

View File

@ -2,7 +2,8 @@ import { Chess } from 'chessops/chess';
import { parseFen, makeFen } from 'chessops/fen';
import { makeSanAndPlay } from 'chessops/san';
import { makeSquare, parseSquare, squareFile, makeUci, parseUci } from 'chessops/util';
import { altCastles, uciCharPair } from 'chess';
import { uciCharPair } from 'chessops/compat';
import { altCastles } from 'chess';
import { defined } from 'common';
export default function(opts) {
@ -57,14 +58,7 @@ export default function(opts) {
}, req.path), 10);
}
function sendAnaDests(req) {
const setup = parseFen(req.fen).unwrap();
const pos = Chess.fromSetup(setup).unwrap();
setTimeout(() => opts.addDests(makeDests(pos), req.path), 10);
}
return {
sendAnaMove: sendAnaMove,
sendAnaDests: sendAnaDests,
};
}

View File

@ -803,10 +803,10 @@ chessground@^7.6:
resolved "https://registry.yarnpkg.com/chessground/-/chessground-7.6.11.tgz#fd215e8e9f49394032de39a71a67b6df3632edb2"
integrity sha512-97LmMJtP/XuG+/ysjiitiHBaWy0saXXFxkZkfXkaWi/GVzPWdQCxEay2jquqZsztQPHNxUMBwHS+KKC2r4HZAw==
chessops@^0.3.4:
version "0.3.4"
resolved "https://registry.yarnpkg.com/chessops/-/chessops-0.3.4.tgz#17a2e6394897dbd5e087727278fb11a836297a56"
integrity sha512-cDuLlZhFqZcF5dyukKsZoFoNDpWv7yHCC2SMoBFsw4KwDVxBJCwLeiCGhAo08atoCGzXAzAw1wnR35QM3+e6OA==
chessops@^0.3.5:
version "0.3.5"
resolved "https://registry.yarnpkg.com/chessops/-/chessops-0.3.5.tgz#ec259a9cd10bfbf3b33df5041e4aa3b4362a9be2"
integrity sha512-CeoIOf2XICjIAA5U0zZfSaFzYUZX/dEyY2lXcCdPsuH/jZQ04F9Mbs7sAM/TCuS9FvgLSA7TMn/2LYDCwCMNWw==
dependencies:
"@badrap/result" "^0.2.6"