Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add components for new board patterns that work with baduk #258

Merged
merged 3 commits into from
May 13, 2024

Conversation

merowin
Copy link
Collaborator

@merowin merowin commented May 11, 2024

Changes

  • take out the baduk adapter class
  • some more refactoring so the variants can work with graph boards
  • add components for graph boards in the vue-client that work with baduk and the board factory

Not done yet:

  • make it so Freeze, Quantum have boards that render the graph boards (they have their own components)
  • add game config input forms for variants that now support the new patterns.
  • Figure out what to do with Annotations on the board (I copied the Multicolored Grid board and made it work for the graphs).

But

It's already working for the most part. Here is variant Tetris on a rhombitrihexagonal board:

grafik

I had some problems with backwards compatibility at first, but I think that I sorted those out.

Comment on lines 133 to 136
const graph = new Graph<TColor>(adjacencyMatrix);
intersections.forEach((intersection) =>
graph.set(intersection.id, startColor),
);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: we've got a lot of Array-style methods on Graph!

Suggested change
const graph = new Graph<TColor>(adjacencyMatrix);
intersections.forEach((intersection) =>
graph.set(intersection.id, startColor),
);
const graph = new Graph<TColor>(adjacencyMatrix).fill(startColor);

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed accordingly, thanks!

): Graph<TColor> {
const adjacencyMatrix = intersections.map((intersection) =>
intersection.neighbours.map((_neighbour, index) => index),
intersection.neighbours.map((neighbour) =>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice fix! Could be worth a simple unit test - something like:

test("createGraph", () => {
  const intersections = createGridBoard({
    type: BoardPattern.Grid;
    width: 3;
    height: 3;
  });
  const graph = createGraph(intersections, 0);

  expect(graph.serialize()).toEqual(...);
});

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I Added a simple unit test.
It's rather difficult to write a meaningful unit test about the graph boards, because its rather abstract, and the one I added is not independent of the implementation (i.e. another implementation may work just fine, but fail the test).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeah, that's a good point, I agree implementation-independence is a good quality to strive for. I think your comment in the code is a sufficient mitigation, but some thoughts on how to create implementation-independent graph tests in general -

When testing createGraph, we could build intersections from scratch instead of a factory:

const intersections = [Intersection(...), Intersection(...);
intersections[0].connectTo(intersections[1], true);

const graph = createGraph(intersections);

// This should hold true regardless of impl (unless we decide to re-map IDs)
expect(graph.neighbors(0)).toEqual([1]);

When testing factories, just assert on properties that should remain invariant. E.g. counts and sizes:

expect(intersections.length).toBe(18)
// hard to assert on each intersection because order dependent, but
// maxes, mins and other aggregators should be mostly invariant
for (intersection of intersections) {
    expect(intersection.Neighbors.length).toBeGreaterThanOrEqualTo(2);
    expect(intersection.Neighbors.length).toBeLessThanOrEqualTo(4);
    // Same with positions
    expect(intersection.Position.x).toBeGreaterThan(0.0);
}

packages/shared/src/variants/baduk.ts Outdated Show resolved Hide resolved
packages/shared/src/variants/quantum.ts Outdated Show resolved Hide resolved
packages/vue-client/src/components/boards/BadukBoard.vue Outdated Show resolved Hide resolved

// Remark: This test case is not independent of implementation
// Also see PolygonalBoardHelper lines 4 - 28
expect(graph.neighbors(0)).toEqual([1, 5, 6, 17]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could expect() some other things here, that do not depend on the intersection IDs. Like the number of intersections and neighbors overall, or the number of neighbors per intersection.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added an assertion about the total number of neighbours (double counted edges).

There is already another test case that checks the total number of nodes of the rhombitrihexagonal board.

Comment on lines 133 to 134
const graph = new Graph<TColor>(adjacencyMatrix).fill(startColor);
return graph;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be changed into one line. Some IDEs will complain about using two lines.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an eslint rule that does this? If it's something we care about, I wouldn't mind adding it to the configs

Edit: I found this: eslint-plugin-sonarjs/prefer-immediate-return but I don't know what SonarJS or whether it's worth pulling in another plugin.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think eslint checks that. It's included in a big closed issue, but it was never implemented according to that. eslint/eslint#667

https://www.jetbrains.com/help/phpstorm/javascript-and-typescript-redundant-local-variable.html


I wouldn't bother adding another plugin just to do that, but I'd be okay with using it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplified to one line.

@merowin merowin merged commit 5ec2597 into main May 13, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants