Skip to content

Instantly share code, notes, and snippets.

@adammark
Created June 20, 2023 15:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adammark/d2537e02179e42f86bd99b6f37a871ab to your computer and use it in GitHub Desktop.
Save adammark/d2537e02179e42f86bd99b6f37a871ab to your computer and use it in GitHub Desktop.
Go board
import { Board } from "./go";
describe("go", () => {
test("creates 19 x 19 board", () => {
const board = new Board();
for (let i = 0; i < 19; i++) {
for (let j = 0; j < 19; j++) {
const space = board.getSpace(i, j);
expect([space.row, space.col]).toEqual([i, j]);
expect(space.color).toBeUndefined();
}
}
});
test("creates adjacent references", () => {
const board = new Board();
const nwCornerSpace = board.getSpace(0, 0);
const neCornerSpace = board.getSpace(0, 18);
const swCornerSpace = board.getSpace(18, 0);
const seCornerSpace = board.getSpace(18, 18);
const nEdgeSpace = board.getSpace(0, 5);
const eEdgeSpace = board.getSpace(5, 18);
const sEdgeSpace = board.getSpace(18, 5);
const wEdgeSpace = board.getSpace(5, 0);
const middleSpace = board.getSpace(5, 5);
expect(nwCornerSpace.adjacents).toHaveLength(2);
expect(neCornerSpace.adjacents).toHaveLength(2);
expect(swCornerSpace.adjacents).toHaveLength(2);
expect(seCornerSpace.adjacents).toHaveLength(2);
expect(nEdgeSpace.adjacents).toHaveLength(3);
expect(eEdgeSpace.adjacents).toHaveLength(3);
expect(sEdgeSpace.adjacents).toHaveLength(3);
expect(wEdgeSpace.adjacents).toHaveLength(3);
expect(middleSpace.adjacents).toHaveLength(4);
});
test("assigns color", () => {
const board = new Board();
const space = board.getSpace(5, 5);
space.place("white");
expect(space.color).toBe("white");
});
test("determines if space is free (not trapped)", () => {
// trap a white stone in NW corner
const board = new Board();
board.getSpace(0, 0).place("white");
expect(board.getSpace(0, 0).isFree()).toBe(true);
board.getSpace(0, 1).place("black");
expect(board.getSpace(0, 0).isFree()).toBe(true);
board.getSpace(1, 0).place("black");
expect(board.getSpace(0, 0).isFree()).toBe(false);
// trap a white stone in the center
board.getSpace(5, 5).place("white");
expect(board.getSpace(5, 5).isFree()).toBe(true);
board.getSpace(4, 5).place("black");
board.getSpace(6, 5).place("black");
board.getSpace(5, 4).place("black");
board.getSpace(5, 6).place("black");
expect(board.getSpace(5, 5).isFree()).toBe(false);
// trap a 3x3 set of white stones in the center
board.getSpace(10, 10).place("white");
board.getSpace(10, 11).place("white");
board.getSpace(10, 12).place("white");
board.getSpace(11, 10).place("white");
board.getSpace(11, 11).place("white");
board.getSpace(11, 12).place("white");
board.getSpace(12, 10).place("white");
board.getSpace(12, 11).place("white");
board.getSpace(12, 12).place("white");
expect(board.getSpace(11, 11).isFree()).toBe(true);
board.getSpace(9, 9).place("black");
board.getSpace(9, 10).place("black");
board.getSpace(9, 11).place("black");
board.getSpace(9, 12).place("black");
board.getSpace(9, 13).place("black");
board.getSpace(10, 9).place("black");
board.getSpace(10, 13).place("black");
board.getSpace(11, 9).place("black");
board.getSpace(11, 13).place("black");
board.getSpace(12, 9).place("black");
board.getSpace(12, 13).place("black");
board.getSpace(13, 9).place("black");
board.getSpace(13, 10).place("black");
board.getSpace(13, 11).place("black");
board.getSpace(13, 12).place("black");
board.getSpace(13, 13).place("black");
expect(board.getSpace(11, 11).isFree()).toBe(false);
});
});
export type Color = "white" | "black";
export class Board {
private spaces: Space[][] = [];
constructor() {
for (let i = 0; i < 19; i++) {
this.spaces.push([]);
for (let j = 0; j < 19; j++) {
this.spaces[i].push(new Space(i, j));
}
}
this.spaces.flat().forEach((space) => {
space.adjacents = this.setAdjacents(space);
});
}
private setAdjacents(space: Space): Space[] {
const [row, col] = [space.row, space.col];
const spaces = [];
if (row > 0) {
spaces.push(this.spaces[row - 1][col]);
}
if (row < 19 - 1) {
spaces.push(this.spaces[row + 1][col]);
}
if (col > 0) {
spaces.push(this.spaces[row][col - 1]);
}
if (col < 19 - 1) {
spaces.push(this.spaces[row][col + 1]);
}
return spaces;
}
public getSpace(row: number, col: number): Space {
return this.spaces[row][col];
}
}
export class Space {
public row: number;
public col: number;
public color?: Color;
public adjacents: Space[];
constructor(row: number, col: number) {
this.row = row;
this.col = col;
this.adjacents = [];
}
public place(color: Color) {
this.color = color;
}
public isFree(evaluated: string[] = []): boolean {
const id = this.id();
const adjacents = this.adjacents.filter((space) => {
return !evaluated.includes(space.id());
});
return adjacents.some((space) => {
if (space.color === undefined) {
return true;
}
else if (space.color === this.color) {
evaluated.push(id);
return space.isFree(evaluated);
}
return false;
});
}
id() {
return [this.row, this.col].toString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment