Skip to content

Commit

Permalink
fix liberty check for fractional go
Browse files Browse the repository at this point in the history
Wrong intersection indices were compared. E.g. the surrounded corner stone in the test was not checked,
because it was changedIntersection[7] and AbstractBaduk's this.intersection[7]
was already checked as a part of the long black chain.
  • Loading branch information
JonKo314 committed Nov 24, 2024
1 parent 90751b8 commit 00ad4e7
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 22 deletions.
3 changes: 2 additions & 1 deletion packages/shared/src/lib/abstractBaduk/abstractBaduk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,14 @@ export abstract class AbstractBaduk<
[];
const checkedIntersections: Map<number, Set<TChainType>> = new Map();

changedIntersections.forEach((intersection, index) => {
changedIntersections.forEach((intersection) => {
if (!intersection.stone) {
// This shouldn't be possible.
// Maybe use better typing to show that all intersections here have stones.
return;
}

const index = this.intersections.indexOf(intersection);
const uncheckedChainTypes = new Set(
Array.from(intersection.stone.getChainTypes()).filter(
(chainType) =>
Expand Down
65 changes: 44 additions & 21 deletions packages/shared/src/variants/fractional/fractional.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,24 @@ import {
} from "./fractional";

class FractionalTestGame extends Fractional {
readonly firstCorner: FractionalIntersection | undefined;
readonly corners: FractionalIntersection[];

constructor(config: Pick<FractionalConfig, "players">) {
super({
...config,
board: { type: BoardPattern.Grid, width: 9, height: 9 },
});

this.firstCorner = this.intersections.find(
(i) => i.neighbours.length === 2,
);
this.corners = this.intersections.filter((i) => i.neighbours.length === 2);
}

indexOf(intersection: FractionalIntersection): number | undefined {
indexOf(intersection: FractionalIntersection): number {
return this.intersections.indexOf(intersection);
}
idOf(intersection: FractionalIntersection): string | "" {
const index = this.intersections.indexOf(intersection);
return index < 0 ? "" : `${index}`;
}
}

test("Surrounded merge stone", () => {
Expand All @@ -33,28 +35,21 @@ test("Surrounded merge stone", () => {
],
});

// TODO: Better typing

expect(game.firstCorner).toBeTruthy();
expect(game.firstCorner?.neighbours.length).toBe(2);
expect(game.firstCorner?.neighbours[0]).toBeTruthy();
expect(game.firstCorner?.neighbours[1]).toBeTruthy();
expect(game.corners).toHaveLength(4);
expect(game.corners[0]).toBeTruthy();
expect(game.corners[0]?.neighbours.length).toBe(2);
expect(game.corners[0]?.neighbours[0]).toBeTruthy();
expect(game.corners[0]?.neighbours[1]).toBeTruthy();

const cornerId = game.firstCorner
? game.indexOf(game.firstCorner)?.toString() ?? ""
: "";
const neighbour0Id = game.firstCorner
? game.indexOf(game.firstCorner.neighbours[0])?.toString() ?? ""
: "";
const neighbour1Id = game.firstCorner
? game.indexOf(game.firstCorner.neighbours[1])?.toString() ?? ""
: "";
const cornerId = game.idOf(game.corners[0]);
const neighbour0Id = game.idOf(game.corners[0].neighbours[0]);
const neighbour1Id = game.idOf(game.corners[0].neighbours[1]);

// Round 1
game.playMove(0, neighbour0Id);
game.playMove(1, neighbour1Id);
game.playMove(2, cornerId);
expect(game.firstCorner?.stone).toBeNull();
expect(game.corners[0]?.stone).toBeNull();

// Round 2
game.playMove(0, cornerId);
Expand All @@ -65,3 +60,31 @@ test("Surrounded merge stone", () => {
expect(state.boardState.filter((i) => i).length).toBe(2);
expect(state.boardState.at(Number(cornerId))).toBeNull();
});

test("A surrounded stone with other long chains on the board", () => {
const game = new FractionalTestGame({
players: [
{ primaryColor: "black", secondaryColor: "green" },
{ primaryColor: "white", secondaryColor: "green" },
],
});

// . . . . .(B)B B B // Additional chains on the board have historically
// . . . . . . W W W // caused issues with the liberty check
// . ...5 lines... .
// . . . . . . . . W
// . . . . . . .(W)B // White's last move should capture black's corner stone

game.playMove(0, game.idOf(game.corners[3]));
game.playMove(1, game.idOf(game.corners[3].neighbours[0]));

for (let i = 8; i >= 6; --i) {
game.playMove(0, `${i}`);
game.playMove(1, `${i + 9}`);
}

game.playMove(0, "5");
game.playMove(1, game.idOf(game.corners[3].neighbours[1]));

expect(game.corners[3].stone).toBeFalsy();
});

0 comments on commit 00ad4e7

Please sign in to comment.