diff --git a/ui/ceval/src/winningChances.ts b/ui/ceval/src/winningChances.ts index 69a7b6b3223ef..32c846e18ba3e 100644 --- a/ui/ceval/src/winningChances.ts +++ b/ui/ceval/src/winningChances.ts @@ -40,5 +40,5 @@ export const povDiff = (color: Color, e1: EvalScore, e2: EvalScore): number => // stricter than lichess-puzzler v49 check // to avoid false positives and only report really faulty puzzles export const areSimilarEvals = (pov: Color, bestEval: EvalScore, secondBestEval: EvalScore): boolean => { - return povDiff(pov, bestEval, secondBestEval) < 0.15; + return povDiff(pov, bestEval, secondBestEval) < 0.14; }; diff --git a/ui/ceval/tests/winningChances.test.ts b/ui/ceval/tests/winningChances.test.ts index 3e18ea591c2db..6ed771c5665d3 100644 --- a/ui/ceval/tests/winningChances.test.ts +++ b/ui/ceval/tests/winningChances.test.ts @@ -36,6 +36,7 @@ describe('similarEvals', () => { ['black', -293, -9], ['black', -179, 61], ['black', -816, -357], + ['black', -225, -51], ])('be different', (color, bestEval, secondBestEval) => { expect(similarEvalsCp(color, bestEval, secondBestEval)).toBe(false); }); diff --git a/ui/puzzle/src/report.ts b/ui/puzzle/src/report.ts index 52935fd23853a..a73ac91eb7ca4 100644 --- a/ui/puzzle/src/report.ts +++ b/ui/puzzle/src/report.ts @@ -5,6 +5,7 @@ import { winningChances } from 'ceval'; import * as licon from 'common/licon'; import { type StoredProp, storedIntProp } from 'common/storage'; import { domDialog } from 'common/dialog'; +import { plyToTurn } from './util'; export default class Report { // if local eval suspect multiple solutions, report the puzzle, once at most @@ -13,7 +14,7 @@ export default class Report { tsHideReportDialog: StoredProp; // bump when logic is changed, to distinguish cached clients from new ones - private version = 3; + private version = 5; constructor() { this.tsHideReportDialog = storedIntProp('puzzle.report.hide.ts', 0); @@ -55,7 +56,7 @@ export default class Report { ) { // in all case, we do not want to show the dialog more than once this.reported = true; - const reason = `(v${this.version}) after move ${node.ply}. ${node.san}, at depth ${ev.depth}, multiple solutions, pvs ${ev.pvs.map(pv => `${pv.moves[0]}: ${pv.cp}`).join(', ')}`; + const reason = `(v${this.version}) after move ${plyToTurn(node.ply)}. ${node.san}, at depth ${ev.depth}, multiple solutions, pvs ${ev.pvs.map(pv => `${pv.moves[0]}: ${showPv(pv)}`).join(', ')}`; this.reportDialog(ctrl.data.puzzle.id, reason); } } @@ -111,3 +112,7 @@ const nextMoveInSolution = (before: Tree.Node) => { const node = before.children[0]; return node && (node.puzzle === 'good' || node.puzzle === 'win'); }; + +const showPv = (pv: Tree.PvData): string => { + return pv.mate ? `#${pv.mate}` : `${pv.cp}`; +}; diff --git a/ui/puzzle/src/util.ts b/ui/puzzle/src/util.ts new file mode 100644 index 0000000000000..84a456e9eac11 --- /dev/null +++ b/ui/puzzle/src/util.ts @@ -0,0 +1 @@ +export const plyToTurn = (ply: number): number => Math.floor((ply - 1) / 2) + 1; diff --git a/ui/puzzle/src/view/tree.ts b/ui/puzzle/src/view/tree.ts index 7b0cb023fa1b3..3ef6619011bfa 100644 --- a/ui/puzzle/src/view/tree.ts +++ b/ui/puzzle/src/view/tree.ts @@ -5,6 +5,7 @@ import { renderEval as normalizeEval } from 'ceval'; import { path as treePath } from 'tree'; import { type MaybeVNode, type LooseVNodes, looseH as h } from 'common/snabbdom'; import type PuzzleCtrl from '../ctrl'; +import { plyToTurn } from '../util'; interface Ctx { ctrl: PuzzleCtrl; @@ -36,10 +37,6 @@ function pathContains(ctx: Ctx, path: Tree.Path): boolean { return treePath.contains(ctx.ctrl.path, path); } -function plyToTurn(ply: number): number { - return Math.floor((ply - 1) / 2) + 1; -} - export function renderIndex(ply: number, withDots: boolean): VNode { return h('index', plyToTurn(ply) + (withDots ? (ply % 2 === 1 ? '.' : '...') : '')); }