90 lines
2.5 KiB
TypeScript
90 lines
2.5 KiB
TypeScript
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";
|
|
import { InternalNodeType } from "../constants/InternalNodeType";
|
|
|
|
export interface PieceProps {
|
|
readonly useInternalTracks: boolean;
|
|
readonly internalNodeType?: InternalNodeType;
|
|
readonly trackDefinitions: {
|
|
readonly startPoint: Direction;
|
|
readonly endPoint?: Direction;
|
|
readonly type: TrackType;
|
|
}[];
|
|
}
|
|
|
|
type Track = {
|
|
readonly joinedPoints: {
|
|
readonly firstPoint: Direction;
|
|
readonly secondPoint: Direction | InternalNode;
|
|
};
|
|
readonly type: TrackType;
|
|
};
|
|
|
|
export class Piece {
|
|
readonly tracks: Set<Track>;
|
|
readonly internalNode?: InternalNode;
|
|
|
|
constructor(pieceProps: PieceProps) {
|
|
if (pieceProps.useInternalTracks) {
|
|
if (!pieceProps.internalNodeType) {
|
|
throw Error(
|
|
"Expected to find internal node type when useInternalTracks is set",
|
|
);
|
|
}
|
|
this.internalNode = new InternalNode(pieceProps.internalNodeType);
|
|
this.tracks = new Set(
|
|
pieceProps.trackDefinitions.map((trackDefinition) => {
|
|
return {
|
|
joinedPoints: {
|
|
firstPoint: trackDefinition.startPoint,
|
|
secondPoint: this.internalNode!,
|
|
},
|
|
type: trackDefinition.type,
|
|
};
|
|
}),
|
|
);
|
|
} else {
|
|
this.internalNode = undefined;
|
|
this.tracks = new Set(
|
|
pieceProps.trackDefinitions.map((trackDefinition) => {
|
|
if (!trackDefinition.endPoint) {
|
|
throw Error("Missing end point for non-internal track");
|
|
}
|
|
return {
|
|
joinedPoints: {
|
|
firstPoint: trackDefinition.startPoint,
|
|
secondPoint: trackDefinition.endPoint,
|
|
},
|
|
type: trackDefinition.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.internalNode,
|
|
cell,
|
|
);
|
|
}
|
|
}
|