Disallow placing piece in places with invalid adjacent connections
parent
4db2aa7407
commit
b692caf93d
|
|
@ -18,5 +18,4 @@ export * from "./types/ExternalNode";
|
||||||
export * from "./types/InternalNode";
|
export * from "./types/InternalNode";
|
||||||
export * from "./types/Piece";
|
export * from "./types/Piece";
|
||||||
export * from "./types/PlacedPiece";
|
export * from "./types/PlacedPiece";
|
||||||
export * from "./types/Node";
|
|
||||||
export * from "./BoardBuilder";
|
export * from "./BoardBuilder";
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
import { CellType } from "../constants/CellType";
|
import { CellType } from "../constants/CellType";
|
||||||
import { Direction } from "../constants/Direction";
|
import { Direction } from "../constants/Direction";
|
||||||
|
import { ExitType } from "../constants/ExitType";
|
||||||
import { PieceId, pieceMap } from "../constants/Pieces";
|
import { PieceId, pieceMap } from "../constants/Pieces";
|
||||||
|
import { Exit } from "./Exit";
|
||||||
import { ExternalNode } from "./ExternalNode";
|
import { ExternalNode } from "./ExternalNode";
|
||||||
|
import { InternalNode } from "./InternalNode";
|
||||||
import { PlacedPiece } from "./PlacedPiece";
|
import { PlacedPiece } from "./PlacedPiece";
|
||||||
|
|
||||||
export class Cell {
|
export class Cell {
|
||||||
|
|
@ -30,8 +33,44 @@ export class Cell {
|
||||||
|
|
||||||
public placePiece(pieceId: PieceId) {
|
public placePiece(pieceId: PieceId) {
|
||||||
if (this.placedPiece !== undefined) return;
|
if (this.placedPiece !== undefined) return;
|
||||||
|
const piece = pieceMap[pieceId];
|
||||||
|
const connectionTypes = Array.from(piece.tracks).flatMap((track) => {
|
||||||
|
const directions =
|
||||||
|
track.joinedPoints.secondPoint instanceof InternalNode
|
||||||
|
? [track.joinedPoints.firstPoint]
|
||||||
|
: [track.joinedPoints.firstPoint, track.joinedPoints.secondPoint];
|
||||||
|
return directions.map((direction) => {
|
||||||
|
return { direction: direction, type: track.type };
|
||||||
|
});
|
||||||
|
});
|
||||||
|
connectionTypes.forEach(({ direction, type }) => {
|
||||||
|
const adjacentPoint = this.getNodeAt(direction).traverseBorder();
|
||||||
|
if (adjacentPoint instanceof Exit) {
|
||||||
|
if (
|
||||||
|
adjacentPoint.type !== ExitType.AMBIVALENT &&
|
||||||
|
adjacentPoint.type.toString() !== type.toString()
|
||||||
|
) {
|
||||||
|
throw Error(
|
||||||
|
`Unable to place piece, invalid border at direction ${direction}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (adjacentPoint.cell.placedPiece !== undefined) {
|
||||||
|
const adjacentTrack =
|
||||||
|
adjacentPoint.cell.placedPiece.piece.findTrackForDirection(
|
||||||
|
adjacentPoint.direction,
|
||||||
|
);
|
||||||
|
if (adjacentTrack !== undefined && adjacentTrack.type !== type) {
|
||||||
|
throw Error(
|
||||||
|
`Unable to place piece next to another due to conflicting track types at ${direction}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.placedPiece = {
|
this.placedPiece = {
|
||||||
piece: pieceMap[pieceId].toPlacedPiece(this),
|
piece: piece.toPlacedPiece(this),
|
||||||
id: pieceId,
|
id: pieceId,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
import { ExternalNode } from "./ExternalNode";
|
|
||||||
import { InternalNode } from "./InternalNode";
|
|
||||||
|
|
||||||
export type Node = ExternalNode | InternalNode;
|
|
||||||
|
|
@ -1,22 +1,25 @@
|
||||||
|
import { Direction } from "../constants/Direction";
|
||||||
import { TrackType } from "../constants/TrackType";
|
import { TrackType } from "../constants/TrackType";
|
||||||
import { Cell } from "./Cell";
|
import { Cell } from "./Cell";
|
||||||
|
import { ExternalNode } from "./ExternalNode";
|
||||||
import { InternalNode } from "./InternalNode";
|
import { InternalNode } from "./InternalNode";
|
||||||
import { Node } from "./Node";
|
|
||||||
|
|
||||||
export class PlacedPiece {
|
export class PlacedPiece {
|
||||||
tracks: Set<{
|
tracks: Set<{
|
||||||
nodes: {
|
nodes: {
|
||||||
firstNode: Node;
|
firstNode: ExternalNode;
|
||||||
secondNode: Node;
|
secondNode: ExternalNode | InternalNode;
|
||||||
};
|
};
|
||||||
type: TrackType;
|
type: TrackType;
|
||||||
}>;
|
}>;
|
||||||
internalNode?: InternalNode;
|
internalNode?: InternalNode;
|
||||||
cell: Cell;
|
cell: Cell;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
tracks: Set<{
|
tracks: Set<{
|
||||||
nodes: { firstNode: Node; secondNode: Node };
|
nodes: {
|
||||||
|
firstNode: ExternalNode;
|
||||||
|
secondNode: ExternalNode | InternalNode;
|
||||||
|
};
|
||||||
type: TrackType;
|
type: TrackType;
|
||||||
}>,
|
}>,
|
||||||
internalNodes: InternalNode | undefined,
|
internalNodes: InternalNode | undefined,
|
||||||
|
|
@ -26,4 +29,13 @@ export class PlacedPiece {
|
||||||
this.internalNode = internalNodes;
|
this.internalNode = internalNodes;
|
||||||
this.cell = cell;
|
this.cell = cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public findTrackForDirection(direction: Direction) {
|
||||||
|
return Array.from(this.tracks).find(
|
||||||
|
(track) =>
|
||||||
|
track.nodes.firstNode.direction === direction ||
|
||||||
|
(track.nodes.secondNode instanceof ExternalNode &&
|
||||||
|
track.nodes.secondNode.direction === direction),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,12 @@ const BoardCell = (props: BoardCellProps) => {
|
||||||
const handleBoardCellClick = () => {
|
const handleBoardCellClick = () => {
|
||||||
const selectedDie = dice.find((die) => die.isSelected);
|
const selectedDie = dice.find((die) => die.isSelected);
|
||||||
if (!selectedDie) return;
|
if (!selectedDie) return;
|
||||||
|
try {
|
||||||
cell.placePiece(selectedDie.pieceId);
|
cell.placePiece(selectedDie.pieceId);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
setDice(
|
setDice(
|
||||||
dice.map((die) => {
|
dice.map((die) => {
|
||||||
return die !== selectedDie
|
return die !== selectedDie
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue