Skip to content

Commit

Permalink
Mark snapback locations as settled and don't touch them for autoscoring
Browse files Browse the repository at this point in the history
  • Loading branch information
anoek committed Jun 19, 2024
1 parent 3bbc530 commit 3c0253d
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 7 deletions.
1 change: 1 addition & 0 deletions .vscode/cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@
"shownotesindicator",
"Sitewide",
"slowstrobe",
"snapbacks",
"sodos",
"stdev",
"styl",
Expand Down
10 changes: 5 additions & 5 deletions src/engine/StoneString.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ export class StoneString {

private __added_neighbors: { [group_id: number]: boolean };
private neighboring_space: StoneString[];
private neighboring_enemy: StoneString[];
private neighboring_stone_strings: StoneString[];

constructor(id: number, color: JGOFNumericPlayerColor) {
this.intersections = [];
this.neighbors = [];
this.neighboring_space = [];
this.neighboring_enemy = [];
this.neighboring_stone_strings = [];
this.id = id;
this.color = color;

Expand All @@ -61,8 +61,8 @@ export class StoneString {
}
}
public foreachNeighboringStoneString(fn: (stone_string: StoneString) => void): void {
for (let i = 0; i < this.neighbors.length; ++i) {
fn(this.neighboring_enemy[i]);
for (let i = 0; i < this.neighboring_stone_strings.length; ++i) {
fn(this.neighboring_stone_strings[i]);
}
}
public size(): number {
Expand All @@ -84,7 +84,7 @@ export class StoneString {
if (group.color === JGOFNumericPlayerColor.EMPTY) {
this.neighboring_space.push(group);
} else {
this.neighboring_enemy.push(group);
this.neighboring_stone_strings.push(group);
}
}
}
Expand Down
115 changes: 113 additions & 2 deletions src/engine/autoscore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ export function autoscore(
debug_groups("Groups", groups);

// Perform our removal logic
//normalize_ownership();
settle_snapback_locations();
settle_agreed_upon_stones();
settle_agreed_upon_territory();
remove_obviously_dead_stones();
Expand Down Expand Up @@ -126,6 +128,112 @@ export function autoscore(
stage_log(`Removing ${encodePrettyXCoordinate(x)}${height - y}: ${removal_reason}`);
}

/**
* Normalizes the string ownerships, this prevents single stones out of a group being marked
* as captured when there are snapback situation still left on the board.
*/
/*
function normalize_ownership() {
stage("Ownership normalization");
const stone_strings = new StoneStringBuilder(
new BoardState({
board,
removal,
}),
original_board,
);
stone_strings.foreachGroup((stone_string) => {
let black = 0;
let white = 0;
let avg = 0;
stone_string.intersections.forEach((point) => {
const { x, y } = point;
black += black_plays_first_ownership[y][x];
white += white_plays_first_ownership[y][x];
avg += average_ownership[y][x];
});
black /= stone_string.intersections.length;
white /= stone_string.intersections.length;
avg /= stone_string.intersections.length;
stone_string.intersections.forEach((point) => {
const { x, y } = point;
black_plays_first_ownership[y][x] = black;
white_plays_first_ownership[y][x] = white;
average_ownership[y][x] = avg;
});
});
debug_board_output("Board", board);
debug_ownership_output("Black plays first estimates", black_plays_first_ownership);
debug_ownership_output("White plays first estimates", white_plays_first_ownership);
debug_ownership_output("Average estimates", average_ownership);
}
*/

function settle_snapback_locations() {
stage("Settling snapbacks");

const snapbacks = makeMatrix(width, height, false);
const neighbors_of_snapbacks = makeMatrix(width, height, false);

const stone_strings = new StoneStringBuilder(
new BoardState({
board,
removal,
}),
original_board,
);
stone_strings.foreachGroup((stone_string) => {
if (stone_string.color === JGOFNumericPlayerColor.EMPTY) {
return;
}

let looks_like_snapback =
stone_string.intersections.some(({ x, y }) =>
isBlack(black_plays_first_ownership[y][x]),
) &&
stone_string.intersections.some(({ x, y }) =>
isWhite(black_plays_first_ownership[y][x]),
);
looks_like_snapback ||=
stone_string.intersections.some(({ x, y }) =>
isBlack(white_plays_first_ownership[y][x]),
) &&
stone_string.intersections.some(({ x, y }) =>
isWhite(white_plays_first_ownership[y][x]),
);
looks_like_snapback ||=
stone_string.intersections.some(({ x, y }) => isBlack(average_ownership[y][x])) &&
stone_string.intersections.some(({ x, y }) => isWhite(average_ownership[y][x]));

if (looks_like_snapback) {
const color = stone_string.color;
stone_string.intersections.forEach(({ x, y }) => {
is_settled[y][x] = 1;
settled[y][x] = color;
snapbacks[y][x] = true;
});

// settle our neighbors as well as they are likely part of the snapback
stone_string.foreachNeighboringStoneString((neighbor) => {
const color = neighbor.color;
neighbor.intersections.forEach(({ x, y }) => {
is_settled[y][x] = 1;
settled[y][x] = color;

neighbors_of_snapbacks[y][x] = true;
});
});
}
});

debug_boolean_board("Snapbacks", snapbacks, "s");
debug_boolean_board("Neighbors of snapbacks", neighbors_of_snapbacks, "n");
debug_boolean_board("Settled", is_settled);
}

/*
* Settle agreed-upon territory
*
Expand Down Expand Up @@ -229,6 +337,9 @@ export function autoscore(
stage("Removing stones both estimates agree upon");
for (let y = 0; y < height; ++y) {
for (let x = 0; x < width; ++x) {
if (is_settled[y][x]) {
continue;
}
if (
board[y][x] === JGOFNumericPlayerColor.WHITE &&
isBlack(black_plays_first_ownership[y][x]) &&
Expand Down Expand Up @@ -1010,11 +1121,11 @@ function finalize_debug_output(): string {
final_output = "";

let legend = "";
legend += "Legend:\n";
legend += "Stone string coloring legend (not boolean maps):\n";
legend += " " + black("Black") + "\n";
legend += " " + white("White") + "\n";
legend += " " + blue("Dame") + "\n";
legend += " " + yellow("Territory in Seki") + "\n";
//legend += " " + yellow("Territory in Seki") + "\n";
legend += " " + magenta("Undecided territory") + "\n";
legend += " " + red("Error") + "\n";

Expand Down
47 changes: 47 additions & 0 deletions test/autoscore_test_files/game_17150.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"game_id": 17150,
"board": [
" bWW WW ",
"WWbW WbWb",
"WWbWWWbb ",
"bbbWbbWb ",
" bWWb W ",
" bWWWWWW",
" bbbbbbW",
" b bWWWb",
" b bbWW "
],
"black": [
[-0.6, -0.7, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0],
[ 0.3, -0.7, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0],
[ 0.7, 0.9, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0],
[ 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0],
[ 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0],
[ 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0],
[ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0],
[ 1.0, 1.0, 1.0, 1.0, 1.0, 0.9, 0.7, -0.7, -0.7],
[ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.7, 0.1, -0.6]
],
"white": [
[-0.6, -0.7, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0],
[ 0.1, -0.7, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0],
[ 0.6, 0.8, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0],
[ 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0],
[ 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0],
[ 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0],
[ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0],
[ 1.0, 1.0, 1.0, 1.0, 1.0, 0.9, 0.7, -0.7, -0.7],
[ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.7, -0.1, -0.6]
],
"correct_ownership": [
" BWWWWWWW",
"WWBWWWWWW",
"WWBWWWWWW",
"BBBWWWWWW",
"BBBWWWWWW",
"BBBWWWWWW",
"BBBBBBBBW",
"BBBBBWWWB",
"BBBBBBWW "
]
}

0 comments on commit 3c0253d

Please sign in to comment.