Skip to content

Commit

Permalink
Allow write winrate etc. to comment of sgf by append-winrate-to-comment
Browse files Browse the repository at this point in the history
  • Loading branch information
zsalch committed Nov 7, 2018
1 parent 9257fd3 commit cc7d3c7
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 46 deletions.
2 changes: 2 additions & 0 deletions src/main/java/featurecat/lizzie/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public class Config {
public Color winrateMissLineColor = null;
public Color blunderBarColor = null;
public boolean solidStoneIndicator = false;
public boolean appendWinrateToComment = false;

private JSONObject loadAndMergeConfig(
JSONObject defaultCfg, String fileName, boolean needValidation) throws IOException {
Expand Down Expand Up @@ -156,6 +157,7 @@ public Config() throws IOException {
handicapInsteadOfWinrate = uiConfig.getBoolean("handicap-instead-of-winrate");
startMaximized = uiConfig.getBoolean("window-maximized");
showDynamicKomi = uiConfig.getBoolean("show-dynamic-komi");
appendWinrateToComment = uiConfig.optBoolean("append-winrate-to-comment");

winrateStrokeWidth = theme.winrateStrokeWidth();
minimumBlunderBarWidth = theme.minimumBlunderBarWidth();
Expand Down
21 changes: 1 addition & 20 deletions src/main/java/featurecat/lizzie/gui/BoardRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ private void drawLeelazSuggestions(Graphics2D g) {
suggestionX,
suggestionY + stoneRadius * 2 / 5,
LizzieFrame.uiFont,
getPlayoutsString(move.playouts),
Lizzie.frame.getPlayoutsString(move.playouts),
(float) (stoneRadius * 0.8),
stoneRadius * 1.4);
}
Expand Down Expand Up @@ -1072,25 +1072,6 @@ private Font makeFont(Font fontBase, int style) {
return font.deriveFont(atts);
}

/**
* @return a shorter, rounded string version of playouts. e.g. 345 -> 345, 1265 -> 1.3k, 44556 ->
* 45k, 133523 -> 134k, 1234567 -> 1.2m
*/
private String getPlayoutsString(int playouts) {
if (playouts >= 1_000_000) {
double playoutsDouble = (double) playouts / 100_000; // 1234567 -> 12.34567
return round(playoutsDouble) / 10.0 + "m";
} else if (playouts >= 10_000) {
double playoutsDouble = (double) playouts / 1_000; // 13265 -> 13.265
return round(playoutsDouble) + "k";
} else if (playouts >= 1_000) {
double playoutsDouble = (double) playouts / 100; // 1265 -> 12.65
return round(playoutsDouble) / 10.0 + "k";
} else {
return String.valueOf(playouts);
}
}

private int[] calculatePixelMargins() {
return calculatePixelMargins(boardLength);
}
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/featurecat/lizzie/gui/LizzieFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static java.awt.image.BufferedImage.TYPE_INT_RGB;
import static java.lang.Math.max;
import static java.lang.Math.min;
import static java.lang.Math.round;

import com.jhlabs.image.GaussianFilter;
import featurecat.lizzie.Lizzie;
Expand Down Expand Up @@ -605,6 +606,25 @@ private void drawPonderingState(Graphics2D g, String text, int x, int y, double
text, x + (width - stringWidth) / 2, y + stringHeight + (height - stringHeight) / 2);
}

/**
* @return a shorter, rounded string version of playouts. e.g. 345 -> 345, 1265 -> 1.3k, 44556 ->
* 45k, 133523 -> 134k, 1234567 -> 1.2m
*/
public String getPlayoutsString(int playouts) {
if (playouts >= 1_000_000) {
double playoutsDouble = (double) playouts / 100_000; // 1234567 -> 12.34567
return round(playoutsDouble) / 10.0 + "m";
} else if (playouts >= 10_000) {
double playoutsDouble = (double) playouts / 1_000; // 13265 -> 13.265
return round(playoutsDouble) + "k";
} else if (playouts >= 1_000) {
double playoutsDouble = (double) playouts / 100; // 1265 -> 12.65
return round(playoutsDouble) / 10.0 + "k";
} else {
return String.valueOf(playouts);
}
}

/**
* Truncate text that is too long for the given width
*
Expand Down
38 changes: 12 additions & 26 deletions src/main/java/featurecat/lizzie/rules/Board.java
Original file line number Diff line number Diff line change
Expand Up @@ -323,13 +323,7 @@ public void place(int x, int y, Stone color, boolean newBranch) {
if (!isValid(x, y) || (history.getStones()[getIndex(x, y)] != Stone.EMPTY && !newBranch))
return;

// Update winrate
Leelaz.WinrateStats stats = Lizzie.leelaz.getWinrateStats();

if (stats.maxWinrate >= 0 && stats.totalPlayouts > history.getData().playouts) {
history.getData().winrate = stats.maxWinrate;
history.getData().playouts = stats.totalPlayouts;
}
updateWinrate();
double nextWinrate = -100;
if (history.getData().winrate >= 0) nextWinrate = 100 - history.getData().winrate;

Expand Down Expand Up @@ -583,12 +577,7 @@ public int[] getMoveNumberList() {
/** Goes to the next coordinate, thread safe */
public boolean nextMove() {
synchronized (this) {
// Update win rate statistics
Leelaz.WinrateStats stats = Lizzie.leelaz.getWinrateStats();
if (stats.totalPlayouts >= history.getData().playouts) {
history.getData().winrate = stats.maxWinrate;
history.getData().playouts = stats.totalPlayouts;
}
updateWinrate();
if (history.next().isPresent()) {
// update leelaz board position, before updating to next node
Optional<int[]> lastMoveOpt = history.getData().lastMove;
Expand All @@ -614,12 +603,7 @@ public boolean nextMove() {
*/
public boolean nextMove(int fromBackChildren) {
synchronized (this) {
// Update win rate statistics
Leelaz.WinrateStats stats = Lizzie.leelaz.getWinrateStats();
if (stats.totalPlayouts >= history.getData().playouts) {
history.getData().winrate = stats.maxWinrate;
history.getData().playouts = stats.totalPlayouts;
}
updateWinrate();
return nextVariation(fromBackChildren);
}
}
Expand Down Expand Up @@ -944,13 +928,7 @@ public void clear() {
public boolean previousMove() {
synchronized (this) {
if (inScoreMode()) setScoreMode(false);
// Update win rate statistics
Leelaz.WinrateStats stats = Lizzie.leelaz.getWinrateStats();

if (stats.totalPlayouts >= history.getData().playouts) {
history.getData().winrate = stats.maxWinrate;
history.getData().playouts = stats.totalPlayouts;
}
updateWinrate();
if (history.previous().isPresent()) {
Lizzie.leelaz.undo();
Lizzie.frame.repaint();
Expand Down Expand Up @@ -1285,4 +1263,12 @@ public void resumePreviousGame() {
} catch (JSONException err) {
}
}

public void updateWinrate() {
Leelaz.WinrateStats stats = Lizzie.leelaz.getWinrateStats();
if (stats.maxWinrate >= 0 && stats.totalPlayouts > history.getData().playouts) {
history.getData().winrate = stats.maxWinrate;
history.getData().playouts = stats.totalPlayouts;
}
}
}
3 changes: 3 additions & 0 deletions src/main/java/featurecat/lizzie/rules/BoardData.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ public static BoardData empty(int size) {
*/
public void addProperty(String key, String value) {
SGFParser.addProperty(properties, key, value);
if ("N".equals(key) && comment.isEmpty()) {
comment = value;
}
}

/**
Expand Down
64 changes: 64 additions & 0 deletions src/main/java/featurecat/lizzie/rules/SGFParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import featurecat.lizzie.Lizzie;
import featurecat.lizzie.analysis.GameInfo;
import featurecat.lizzie.analysis.Leelaz;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.HashMap;
Expand Down Expand Up @@ -307,6 +308,11 @@ private static void saveToStream(Board board, Writer writer) throws IOException
"KM[%s]PW[%s]PB[%s]DT[%s]AP[Lizzie: %s]",
komi, playerW, playerB, date, Lizzie.lizzieVersion));

// To append the winrate to the comment of sgf we might need to update the Winrate
if (Lizzie.config.appendWinrateToComment) {
Lizzie.board.updateWinrate();
}

// move to the first move
history.toStart();

Expand Down Expand Up @@ -398,6 +404,11 @@ private static String generateNode(Board board, BoardHistoryNode node) throws IO
// Node properties
builder.append(data.propertiesString());

if (Lizzie.config.appendWinrateToComment) {
// Append the winrate to the comment of sgf
data.comment = formatComment(node);
}

// Write the comment
if (!data.comment.isEmpty()) {
builder.append(String.format("C[%s]", data.comment));
Expand All @@ -421,6 +432,59 @@ private static String generateNode(Board board, BoardHistoryNode node) throws IO
return builder.toString();
}

/**
* Format Comment with following format: Move <Move number> <Winrate> (<Last Move Rate
* Difference>) (<Weight name> / <Playouts>)
*/
private static String formatComment(BoardHistoryNode node) {
BoardData data = node.getData();
String engine = Lizzie.leelaz.currentWeight();

// Playouts
String playouts = Lizzie.frame.getPlayoutsString(data.playouts);

// Last winrate
BoardData lastNode = node.previous().get().getData();
boolean validLastWinrate = (lastNode.playouts > 0);
double lastWR = validLastWinrate ? lastNode.winrate : 50;

// Current winrate
boolean validWinrate = (data.playouts > 0);
double curWR = validWinrate ? data.winrate : 100 - lastWR;
String curWinrate = "";
if (Lizzie.config.handicapInsteadOfWinrate) {
curWinrate = String.format("%.2f", Leelaz.winrateToHandicap(100 - curWR));
} else {
curWinrate = String.format("%.1f%%", 100 - curWR);
}

// Last move difference winrate
String lastMoveDiff = "";
if (validLastWinrate && validWinrate) {
if (Lizzie.config.handicapInsteadOfWinrate) {
double currHandicapedWR = Leelaz.winrateToHandicap(100 - curWR);
double lastHandicapedWR = Leelaz.winrateToHandicap(lastWR);
lastMoveDiff = String.format(": %.2f", currHandicapedWR - lastHandicapedWR);
} else {
lastMoveDiff = String.format("(%.1f%%)", 100 - lastWR - curWR);
}
}

String wf = "Move %d\n%s %s\n(%s / %s playouts)";
String nc = String.format(wf, data.moveNumber, curWinrate, lastMoveDiff, engine, playouts);

if (!data.comment.isEmpty()) {
String wp =
"Move [0-9]+\n[0-9\\.\\-]+%* \\(*[0-9\\.\\-]*%*\\)*\n\\([^\\(\\)/]* \\/ [0-9\\.]*[kmKM]* playouts\\)";
if (data.comment.matches("(?s).*" + wp + "(?s).*")) {
nc = data.comment.replaceAll(wp, nc);
} else {
nc = String.format("%s\n\n%s", nc, data.comment);
}
}
return nc;
}

public static boolean isListProperty(String key) {
return asList(listProps).contains(key);
}
Expand Down

0 comments on commit cc7d3c7

Please sign in to comment.