diff --git a/interface/index.ts b/interface/index.ts index 0cf1028..66f3650 100644 --- a/interface/index.ts +++ b/interface/index.ts @@ -11,5 +11,4 @@ export * from "./types/ExternalNode"; export * from "./types/InternalNode"; export * from "./types/Piece"; export * from "./types/PlacedPiece"; -export * from "./types/Node"; export * from "./BoardBuilder"; diff --git a/interface/types/Cell.ts b/interface/types/Cell.ts index 757e471..9f79fad 100644 --- a/interface/types/Cell.ts +++ b/interface/types/Cell.ts @@ -1,7 +1,10 @@ import { CellType } from "../constants/CellType"; import { Direction } from "../constants/Direction"; +import { ExitType } from "../constants/ExitType"; import { PieceId, pieceMap } from "../constants/Pieces"; +import { Exit } from "./Exit"; import { ExternalNode } from "./ExternalNode"; +import { InternalNode } from "./InternalNode"; import { PlacedPiece } from "./PlacedPiece"; export class Cell { @@ -30,8 +33,44 @@ export class Cell { public placePiece(pieceId: PieceId) { 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 = { - piece: pieceMap[pieceId].toPlacedPiece(this), + piece: piece.toPlacedPiece(this), id: pieceId, }; } diff --git a/interface/types/Node.ts b/interface/types/Node.ts deleted file mode 100644 index fa5bbe0..0000000 --- a/interface/types/Node.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { ExternalNode } from "./ExternalNode"; -import { InternalNode } from "./InternalNode"; - -export type Node = ExternalNode | InternalNode; diff --git a/interface/types/PlacedPiece.ts b/interface/types/PlacedPiece.ts index 7582a42..cdbc1f0 100644 --- a/interface/types/PlacedPiece.ts +++ b/interface/types/PlacedPiece.ts @@ -1,22 +1,25 @@ +import { Direction } from "../constants/Direction"; import { TrackType } from "../constants/TrackType"; import { Cell } from "./Cell"; +import { ExternalNode } from "./ExternalNode"; import { InternalNode } from "./InternalNode"; -import { Node } from "./Node"; export class PlacedPiece { tracks: Set<{ nodes: { - firstNode: Node; - secondNode: Node; + firstNode: ExternalNode; + secondNode: ExternalNode | InternalNode; }; type: TrackType; }>; internalNode?: InternalNode; cell: Cell; - constructor( tracks: Set<{ - nodes: { firstNode: Node; secondNode: Node }; + nodes: { + firstNode: ExternalNode; + secondNode: ExternalNode | InternalNode; + }; type: TrackType; }>, internalNodes: InternalNode | undefined, @@ -26,4 +29,13 @@ export class PlacedPiece { this.internalNode = internalNodes; 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), + ); + } } diff --git a/web/src/pages/game/components/BoardCell.tsx b/web/src/pages/game/components/BoardCell.tsx index 2e1d5af..220e7f6 100644 --- a/web/src/pages/game/components/BoardCell.tsx +++ b/web/src/pages/game/components/BoardCell.tsx @@ -25,7 +25,12 @@ const BoardCell = (props: BoardCellProps) => { const handleBoardCellClick = () => { const selectedDie = dice.find((die) => die.isSelected); if (!selectedDie) return; - cell.placePiece(selectedDie.pieceId); + try { + cell.placePiece(selectedDie.pieceId); + } catch (error) { + console.log(error); + return; + } setDice( dice.map((die) => { return die !== selectedDie