import { Direction } from "../constants/Direction"; import { TrackType } from "../constants/TrackType"; import { Cell } from "./Cell"; import { InternalNode } from "./InternalNode"; import { PlacedPiece } from "./PlacedPiece"; import { Node } from "./Node"; export interface TrackProps { startPoint: Direction; endPoint?: Direction; isInternal: boolean; type: TrackType; } export class Piece { tracks: Set<{ joinedPoints: { firstPoint: Direction; secondPoint: Direction | InternalNode; }; type: TrackType; }>; internalNodes: Set; constructor(hasInternalNode: boolean, trackDefinitions: TrackProps[]) { const internalNode = new InternalNode(); this.internalNodes = new Set(); if (hasInternalNode) { this.internalNodes.add(internalNode); } this.tracks = new Set( trackDefinitions.map((track) => { if (!track.isInternal && !track.endPoint) { throw Error("Missing direction for non-internal track"); } return { joinedPoints: { firstPoint: track.startPoint, secondPoint: track.isInternal ? internalNode : (track.endPoint as Direction), }, type: track.type, }; }), ); } toPlacedPiece(cell: Cell) { return new PlacedPiece( new Set( Array.from(this.tracks).map((track) => { return { nodes: { firstNode: cell.getNodeAt(track.joinedPoints.firstPoint), secondNode: track.joinedPoints.secondPoint instanceof Node ? track.joinedPoints.secondPoint as Node : cell.getNodeAt(track.joinedPoints.secondPoint as Direction), }, type: track.type, }; }), ), this.internalNodes, cell, ); } }