diff --git a/src/main/java/featurecat/lizzie/Config.java b/src/main/java/featurecat/lizzie/Config.java index cca15fc0d..f90263123 100644 --- a/src/main/java/featurecat/lizzie/Config.java +++ b/src/main/java/featurecat/lizzie/Config.java @@ -58,6 +58,7 @@ public class Config { public boolean showKataGoEstimateOnSubboard = true; public boolean showKataGoEstimateOnMainboard = true; public String kataGoEstimateMode = "small+dead"; + public boolean kataGoEstimateBlend = true; public boolean showStatus = true; public boolean showBranch = true; @@ -241,6 +242,7 @@ public Config() throws IOException { showKataGoEstimateOnSubboard = uiConfig.optBoolean("show-katago-estimate-onsubboard", true); showKataGoEstimateOnMainboard = uiConfig.optBoolean("show-katago-estimate-onmainboard", true); kataGoEstimateMode = uiConfig.optString("katago-estimate-mode", "small+dead"); + kataGoEstimateBlend = uiConfig.optBoolean("katago-estimate-blend", true); showWinrateInSuggestion = uiConfig.optBoolean("show-winrate-in-suggestion", true); showPlayoutsInSuggestion = uiConfig.optBoolean("show-playouts-in-suggestion", true); showScoremeanInSuggestion = uiConfig.optBoolean("show-scoremean-in-suggestion", true); @@ -383,6 +385,7 @@ public void toggleShowPolicy() { public void toggleKataGoEstimate() { showKataGoEstimate = !showKataGoEstimate; + uiConfig.put("show-katago-estimate", showKataGoEstimate); } public void cycleKataGoEstimateMode() { @@ -410,6 +413,12 @@ public void cycleKataGoEstimateMode() { kataGoEstimateMode = "small"; break; } + uiConfig.put("katago-estimate-mode", kataGoEstimateMode); + } + + public void toggleKataGoEstimateBlend() { + kataGoEstimateBlend = !kataGoEstimateBlend; + uiConfig.put("katago-estimate-blend", kataGoEstimateBlend); } public void toggleShowStatus() { @@ -544,6 +553,7 @@ private JSONObject createDefaultConfig() { ui.put("show-katago-estimate-onsubboard", true); ui.put("show-katago-estimate-onmainboard", true); ui.put("katago-estimate-mode", "small"); + ui.put("katago-estimate-blend", true); config.put("ui", ui); return config; } diff --git a/src/main/java/featurecat/lizzie/gui/BoardRenderer.java b/src/main/java/featurecat/lizzie/gui/BoardRenderer.java index f10e8a8a5..5109151f6 100644 --- a/src/main/java/featurecat/lizzie/gui/BoardRenderer.java +++ b/src/main/java/featurecat/lizzie/gui/BoardRenderer.java @@ -1721,6 +1721,10 @@ public void removeEstimateRect() { cachedEstimateSmallRectImage = new BufferedImage(boardWidth, boardHeight, TYPE_INT_ARGB); } + public static int roundToInt(double number) { + return (int) round(number); + } + // isZen: estimates are for black (Zen) rather than player to move (KataGo) // and estimates are just <0/=0/>0 (Zen) rather than -1..+1 (KataGo) public void drawEstimateRect(ArrayList estimateArray, boolean isZen) { @@ -1773,13 +1777,10 @@ public void drawEstimateRect(ArrayList estimateArray, boolean isZen) { double estimate = estimateArray.get(i); if (isZen) { // Zen's estimates are only <0 / =0 / >0 - if (estimate < 0) estimate = -1; - else if (estimate > 0) estimate = +1; - } - boolean isBlack = (estimate > 0); - if (!isZen) { + estimate = Math.signum(estimate); + } else { // KataGo's estimates are for player to move, not for black. - if (!Lizzie.board.getHistory().isBlacksTurn()) isBlack = !isBlack; + if (!Lizzie.board.getHistory().isBlacksTurn()) estimate = -estimate; } int[] c = Lizzie.board.getCoord(i); int x = c[1]; @@ -1788,13 +1789,20 @@ public void drawEstimateRect(ArrayList estimateArray, boolean isZen) { int stoneY = scaledMarginHeight + squareHeight * y; // g.setColor(Color.BLACK); - int grey = isBlack ? 0 : 255; - double alpha = Math.abs(estimate); + boolean blend = Lizzie.config.kataGoEstimateBlend; + int grey; + double alpha = 255; + if (blend) { + grey = (estimate > 0) ? 0 : 255; + alpha *= Math.abs(estimate); + } else { + grey = roundToInt((1 - estimate) * 255 / 2.0); + } // Large rectangles (will go behind stones). if (drawLarge) { - Color cl = new Color(grey, grey, grey, (int) (255 * (0.75 * alpha))); + Color cl = new Color(grey, grey, grey, roundToInt(blend ? 0.75 * alpha : alpha)); gl.setColor(cl); gl.fillRect( (int) (stoneX - squareWidth * 0.5), @@ -1806,17 +1814,18 @@ public void drawEstimateRect(ArrayList estimateArray, boolean isZen) { // Small rectangles (will go on top of stones; perhaps only "dead" stones). Stone stoneHere = Lizzie.board.getStones()[Board.getIndex(x, y)]; - boolean differentColor = isBlack ? stoneHere.isWhite() : stoneHere.isBlack(); - boolean anyColor = stoneHere.isWhite() || stoneHere.isBlack(); + boolean deadStone = + (estimate >= 0 && stoneHere.isWhite()) || (estimate <= 0 && stoneHere.isBlack()); + boolean anyStone = stoneHere.isWhite() || stoneHere.isBlack(); boolean allowed = drawSmart == 0 - || (drawSmart == 1 && differentColor) - || (drawSmart == 2 && anyColor) - || (drawSmart == 1 && !anyColor && drawSmall); + || (drawSmart == 1 && deadStone) + || (drawSmart == 2 && anyStone) + || (drawSmart == 1 && !anyStone && drawSmall); if (drawSmall && allowed) { double lengthFactor = drawSize ? 2 * convertLength(estimate) : 1.2; int length = (int) (lengthFactor * stoneRadius); - int ialpha = drawSize ? 180 : (int) (255 * alpha); + int ialpha = (blend && drawSize) ? 180 : roundToInt(alpha); Color cl = new Color(grey, grey, grey, ialpha); gs.setColor(cl); gs.fillRect(stoneX - length / 2, stoneY - length / 2, length, length); diff --git a/src/main/java/featurecat/lizzie/gui/Input.java b/src/main/java/featurecat/lizzie/gui/Input.java index 3a27b471d..9cbdfca74 100644 --- a/src/main/java/featurecat/lizzie/gui/Input.java +++ b/src/main/java/featurecat/lizzie/gui/Input.java @@ -451,6 +451,8 @@ public void keyPressed(KeyEvent e) { if (Lizzie.leelaz.isKataGo) { if (e.isAltDown()) { Lizzie.frame.toggleEstimateByZen(); + } else if (e.isShiftDown()) { + if (Lizzie.config.showKataGoEstimate) Lizzie.config.toggleKataGoEstimateBlend(); } else { if (e.isControlDown()) { // ctrl-. cycles modes, but only if estimates being displayed diff --git a/src/main/java/featurecat/lizzie/gui/Menu.java b/src/main/java/featurecat/lizzie/gui/Menu.java index 47f96bc8e..7985e9f88 100644 --- a/src/main/java/featurecat/lizzie/gui/Menu.java +++ b/src/main/java/featurecat/lizzie/gui/Menu.java @@ -916,6 +916,22 @@ public void actionPerformed(ActionEvent e) { } }); + final JCheckBoxMenuItem kataEstimateBlend = + new JCheckBoxMenuItem(resourceBundle.getString("Menu.view.kataGo.kataEstimate.blend")); + kataEstimateBlend.addActionListener( + new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Lizzie.config.toggleKataGoEstimateBlend(); + try { + Lizzie.config.save(); + } catch (IOException es) { + // TODO Auto-generated catch block + } + } + }); + kataEstimate.add(kataEstimateBlend); + viewMenu.addMenuListener( new MenuListener() { public void menuSelected(MenuEvent e) { @@ -960,6 +976,7 @@ public void menuSelected(MenuEvent e) { kataEstimateModeLargeAndStones.setState( Lizzie.config.kataGoEstimateMode.equals("large+stones")); kataEstimateModeSize.setState(Lizzie.config.kataGoEstimateMode.equals("size")); + kataEstimateBlend.setState(Lizzie.config.kataGoEstimateBlend); if (Lizzie.config.uiConfig.getBoolean("win-rate-always-black")) winrateAlwaysBlack.setState(true); else winrateAlwaysBlack.setState(false); diff --git a/src/main/resources/l10n/DisplayStrings.properties b/src/main/resources/l10n/DisplayStrings.properties index 34e9b5e20..2ee0b2611 100644 --- a/src/main/resources/l10n/DisplayStrings.properties +++ b/src/main/resources/l10n/DisplayStrings.properties @@ -253,6 +253,7 @@ Menu.view.kataGo.kataEstimate.mode.largeAndSmall=Large + small everywhere Menu.view.kataGo.kataEstimate.mode.largeAndDead=Large + small on "dead" stones Menu.view.kataGo.kataEstimate.mode.largeAndStones=Large + small on all stones Menu.view.kataGo.kataEstimate.mode.size=Small, of varying size +Menu.view.kataGo.kataEstimate.blend=Blend with board Menu.game=Game Menu.game.newGame=NewGame(N) Menu.game.continueGameBlack=Continue(Play black)