Skip to content

Commit

Permalink
Use new autoscore data from the server for score estimates and stone …
Browse files Browse the repository at this point in the history
…removal
  • Loading branch information
anoek committed Jun 1, 2024
1 parent 484d36b commit dd131d9
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 14 deletions.
5 changes: 4 additions & 1 deletion .vscode/cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"autoplace",
"autoplaying",
"autoscore",
"autoscored",
"Autoscoring",
"autoscroll",
"autoscrolling",
Expand Down Expand Up @@ -186,5 +187,7 @@
"zoomable"
],
"language": "en,en-GB",
"ignorePaths": ["test/autoscore_test_files"]
"ignorePaths": [
"test/autoscore_test_files"
]
}
70 changes: 66 additions & 4 deletions src/ScoreEstimator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,34 @@ export interface ScoreEstimateRequest {
player_to_move: "black" | "white";
width: number;
height: number;
board_state: Array<Array<number>>;
board_state: JGOFNumericPlayerColor[][];
rules: GoEngineRules;
black_prisoners?: number;
white_prisoners?: number;
komi?: number;
jwt: string;

/** Whether to run autoscoring logic. If true, player_to_move is
* essentially ignored as we compute estimates with each player moving
* first in turn. */
autoscore?: boolean;
}

export interface ScoreEstimateResponse {
ownership: Array<Array<number>>;
/** Matrix of ownership estimates ranged from -1 (white) to 1 (black) */
ownership: number[][];

/** Estimated score */
score?: number;

/** Estimated win rate */
win_rate?: number;

/** Board state after autoscoring logic has been run. Only defined if autoscore was true in the request. */
autoscored_board_state?: JGOFNumericPlayerColor[][];

/** Intersections that are dead or dame. Only defined if autoscore was true in the request. */
autoscored_removed?: string;
}

let remote_scorer: ((req: ScoreEstimateRequest) => Promise<ScoreEstimateResponse>) | undefined;
Expand Down Expand Up @@ -117,6 +133,8 @@ export class ScoreEstimator {
estimated_hard_score: number;
when_ready: Promise<void>;
prefer_remote: boolean;
autoscored_state?: JGOFNumericPlayerColor[][];
autoscored_removed?: string;

constructor(
goban_callback: GobanCore | undefined,
Expand Down Expand Up @@ -184,6 +202,7 @@ export class ScoreEstimator {
height: this.engine.height,
rules: this.engine.rules,
board_state: board_state,
autoscore: true,
jwt: "", // this gets set by the remote_scorer method
})
.then((res: ScoreEstimateResponse) => {
Expand All @@ -201,8 +220,26 @@ export class ScoreEstimator {
res.score += 7.5 - komi; // we always ask katago to use 7.5 komi, so correct if necessary
res.score += captures_delta;
res.score -= this.engine.getHandicapPointAdjustmentForWhite();

this.updateEstimate(score_estimate, res.ownership, res.score);
this.autoscored_removed = res.autoscored_removed;
this.autoscored_state = res.autoscored_board_state;

if (this.autoscored_state) {
this.updateEstimate(
score_estimate,
this.autoscored_state.map((row) =>
row.map((cell) => (cell === 2 ? -1 : cell)),
),
res.score,
);
} else {
console.error(
"Remote scorer didn't have an autoscore board state, this should be unreachable",
);
// this was the old code, probably still works in case
// we have messed something up. Eventually this should
// be removed. - anoek 2024-06-01
this.updateEstimate(score_estimate, res.ownership, res.score);
}
resolve();
})
.catch((err: any) => {
Expand Down Expand Up @@ -260,6 +297,13 @@ export class ScoreEstimator {
}

getProbablyDead(): string {
if (this.autoscored_removed) {
console.info("Returning autoscored_removed for getProbablyDead");
return this.autoscored_removed;
} else {
console.warn("Not able to use autoscored_removed for getProbablyDead");
}

let ret = "";
const arr = [];

Expand Down Expand Up @@ -349,12 +393,15 @@ export class ScoreEstimator {
}
}
setRemoved(x: number, y: number, removed: number): void {
this.clearAutoScore();

this.removal[y][x] = removed;
if (this.goban_callback) {
this.goban_callback.setForRemoval(x, y, this.removal[y][x]);
}
}
clearRemoved(): void {
this.clearAutoScore();
for (let y = 0; y < this.height; ++y) {
for (let x = 0; x < this.width; ++x) {
if (this.removal[y][x]) {
Expand All @@ -363,7 +410,22 @@ export class ScoreEstimator {
}
}
}
clearAutoScore(): void {
if (this.autoscored_removed || this.autoscored_state) {
this.autoscored_removed = undefined;
this.autoscored_state = undefined;
console.warn("Clearing autoscored state");
}
}

getStoneRemovalString(): string {
if (this.autoscored_removed) {
console.info("Returning autoscored_removed for getStoneRemovalString");
return this.autoscored_removed;
} else {
console.warn("Not able to use autoscored_removed for getStoneRemovalString");
}

let ret = "";
const arr = [];
for (let y = 0; y < this.height; ++y) {
Expand Down
18 changes: 9 additions & 9 deletions src/autoscore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,15 @@ export function autoscore(
compute_final_ownership();
final_dame_pass();

return [
{
result: final_ownership,
removed_string: removed.map((pt) => `${num2char(pt[0])}${num2char(pt[1])}`).join(""),
removed,
},
debug_output,
];

/** Marks a position as being removed (either dead stone or dame) */
function remove(x: number, y: number, reason: string) {
if (removal[y][x]) {
Expand Down Expand Up @@ -527,15 +536,6 @@ export function autoscore(
}
}
}

return [
{
result: final_ownership,
removed_string: removed.map((pt) => `${num2char(pt[0])}${num2char(pt[1])}`).join(""),
removed,
},
debug_output,
];
}

function debug_ownership_output(ownership: number[][]) {
Expand Down

0 comments on commit dd131d9

Please sign in to comment.