diff --git a/src/components/Goban.js b/src/components/Goban.js index 359fea21..3c72e437 100644 --- a/src/components/Goban.js +++ b/src/components/Goban.js @@ -220,6 +220,7 @@ export default class Goban extends Component { paintMap = [], analysis, analysisType, + showAnalysis, highlightVertices = [], dimmedStones = [], @@ -409,41 +410,59 @@ export default class Goban extends Component { let heatMap = [] - if (drawHeatMap && analysis != null) { - let maxVisitsWin = Math.max( - ...analysis.variations.map(x => x.visits * x.winrate) - ) - heatMap = board.signMap.map(row => row.map(_ => null)) - - for (let { - vertex: [x, y], - visits, - winrate, - scoreLead - } of analysis.variations) { - let strength = Math.round((visits * winrate * 8) / maxVisitsWin) + 1 - - winrate = - strength <= 3 ? Math.floor(winrate) : Math.floor(winrate * 10) / 10 - scoreLead = scoreLead == null ? null : Math.round(scoreLead * 10) / 10 - if (scoreLead === 0) scoreLead = 0 // Avoid -0 - - heatMap[y][x] = { - strength, - text: - visits < 10 - ? '' - : [ - analysisType === 'winrate' - ? i18n.formatNumber(winrate) + - (Math.floor(winrate) === winrate ? '%' : '') - : analysisType === 'scoreLead' && scoreLead != null - ? (scoreLead >= 0 ? '+' : '') + i18n.formatNumber(scoreLead) - : '–', - visits < 1000 - ? i18n.formatNumber(visits) - : i18n.formatNumber(Math.round(visits / 100) / 10) + 'k' - ].join('\n') + if (drawHeatMap && showAnalysis) { + let variations + + if (analysis != null) { + variations = analysis.variations + } else { + variations = [] + for (const v in board.childrenInfo) { + const [x, y] = v.split(',').map(x => +x) + const {visits, winrate, scoreLead} = board.childrenInfo[v] + if (isFinite(visits) && isFinite(winrate)) { + variations.push({vertex: [x, y], visits, winrate, scoreLead}) + } + } + } + + if (variations.length) { + let maxVisitsWin = Math.max( + ...variations.map(x => x.visits * x.winrate) + ) + heatMap = board.signMap.map(row => row.map(_ => null)) + + for (let { + vertex: [x, y], + visits, + winrate, + scoreLead + } of variations) { + let strength = Math.round((visits * winrate * 8) / maxVisitsWin) + 1 + + winrate = + strength <= 3 ? Math.floor(winrate) : Math.floor(winrate * 10) / 10 + scoreLead = scoreLead == null ? null : Math.round(scoreLead * 10) / 10 + if (scoreLead === 0) scoreLead = 0 // Avoid -0 + + heatMap[y][x] = { + strength, + text: + visits < 10 + ? '' + : [ + analysisType === 'winrate' + ? i18n.formatNumber(winrate) + + (Math.floor(winrate) === winrate ? '%' : '') + : analysisType === 'scoreLead' && scoreLead != null + ? (scoreLead >= 0 ? '+' : '') + + i18n.formatNumber(scoreLead) + : '–', + visits < 1000 + ? i18n.formatNumber(visits) + : i18n.formatNumber(Math.round(visits / 100) / 10) + 'k' + ].join('\n') + } } } } diff --git a/src/components/MainView.js b/src/components/MainView.js index e497b426..2a20488f 100644 --- a/src/components/MainView.js +++ b/src/components/MainView.js @@ -144,6 +144,7 @@ export default class MainView extends Component { analysisTreePosition === treePosition ? analysis : null, + showAnalysis, paintMap, dimmedStones: ['scoring', 'estimator'].includes(mode) ? deadStones diff --git a/src/modules/gametree.js b/src/modules/gametree.js index 5d4e4ae3..d9cef89d 100644 --- a/src/modules/gametree.js +++ b/src/modules/gametree.js @@ -358,7 +358,20 @@ export function getBoard(tree, id) { type = 'good' } - list[v] = {sign, type} + let visits = null + let winrate = null + let scoreLead = null + if (isFinite(node.data.VISITS)) { + visits = +node.data.VISITS + } + if (isFinite(node.data.WINRATE)) { + winrate = (0.5 + sign * (node.data.WINRATE - 0.5)) * 100 + } + if (isFinite(node.data.SCORELEAD)) { + scoreLead = node.data.SCORELEAD * sign + } + + list[v] = {sign, type, visits, winrate, scoreLead} } for (let child of node.children) {