Re-structure pieces builder and add include first pieces batch
parent
6bb0e1aa74
commit
6fab2d94a0
|
|
@ -13,5 +13,7 @@ module.exports = {
|
|||
jest: true,
|
||||
},
|
||||
ignorePatterns: [".eslintrc.js", "dist/"],
|
||||
rules: {},
|
||||
rules: {
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
export enum InternalNodeType {
|
||||
NONE = "NONE",
|
||||
STATION = "STATION",
|
||||
}
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
import { Piece } from "../types/Piece";
|
||||
import { Direction } from "./Direction";
|
||||
import { InternalNodeType } from "./InternalNodeType";
|
||||
import { TrackType } from "./TrackType";
|
||||
|
||||
const STRAIGHT_RAIL: Piece = new Piece({
|
||||
useInternalTracks: false,
|
||||
trackDefinitions: [
|
||||
{
|
||||
startPoint: Direction.NORTH,
|
||||
endPoint: Direction.SOUTH,
|
||||
type: TrackType.RAIL,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const TURN_RAIL: Piece = new Piece({
|
||||
useInternalTracks: false,
|
||||
trackDefinitions: [
|
||||
{
|
||||
startPoint: Direction.SOUTH,
|
||||
endPoint: Direction.EAST,
|
||||
type: TrackType.RAIL,
|
||||
},
|
||||
],
|
||||
});
|
||||
const FOUR_WAY_CROSS_RAIL: Piece = new Piece({
|
||||
useInternalTracks: true,
|
||||
internalNodeType: InternalNodeType.NONE,
|
||||
trackDefinitions: [
|
||||
{
|
||||
startPoint: Direction.NORTH,
|
||||
type: TrackType.RAIL,
|
||||
},
|
||||
{
|
||||
startPoint: Direction.EAST,
|
||||
type: TrackType.RAIL,
|
||||
},
|
||||
{
|
||||
startPoint: Direction.SOUTH,
|
||||
type: TrackType.RAIL,
|
||||
},
|
||||
{
|
||||
startPoint: Direction.WEST,
|
||||
type: TrackType.RAIL,
|
||||
},
|
||||
],
|
||||
});
|
||||
const T_JUNCTION_RAIL: Piece = new Piece({
|
||||
useInternalTracks: true,
|
||||
internalNodeType: InternalNodeType.NONE,
|
||||
trackDefinitions: [
|
||||
{
|
||||
startPoint: Direction.WEST,
|
||||
type: TrackType.RAIL,
|
||||
},
|
||||
{
|
||||
startPoint: Direction.SOUTH,
|
||||
type: TrackType.RAIL,
|
||||
},
|
||||
{
|
||||
startPoint: Direction.EAST,
|
||||
type: TrackType.RAIL,
|
||||
},
|
||||
],
|
||||
});
|
||||
const DEAD_END_STATION_RAIL: Piece = new Piece({
|
||||
useInternalTracks: true,
|
||||
internalNodeType: InternalNodeType.STATION,
|
||||
trackDefinitions: [
|
||||
{
|
||||
startPoint: Direction.SOUTH,
|
||||
type: TrackType.RAIL,
|
||||
},
|
||||
],
|
||||
});
|
||||
const TURN_RAIL_TO_ROAD: Piece = new Piece({
|
||||
useInternalTracks: true,
|
||||
internalNodeType: InternalNodeType.STATION,
|
||||
trackDefinitions: [
|
||||
{
|
||||
startPoint: Direction.SOUTH,
|
||||
type: TrackType.RAIL,
|
||||
},
|
||||
{
|
||||
startPoint: Direction.EAST,
|
||||
type: TrackType.ROAD,
|
||||
},
|
||||
],
|
||||
});
|
||||
const T_JUNCTION_WITH_ROAD_ON_SIDE: Piece = new Piece({
|
||||
useInternalTracks: true,
|
||||
internalNodeType: InternalNodeType.STATION,
|
||||
trackDefinitions: [
|
||||
{
|
||||
startPoint: Direction.SOUTH,
|
||||
type: TrackType.RAIL,
|
||||
},
|
||||
{
|
||||
startPoint: Direction.WEST,
|
||||
type: TrackType.RAIL,
|
||||
},
|
||||
{
|
||||
startPoint: Direction.EAST,
|
||||
type: TrackType.ROAD,
|
||||
},
|
||||
],
|
||||
});
|
||||
const FOUR_WAY_WITH_ONE_ROAD: Piece = new Piece({
|
||||
useInternalTracks: true,
|
||||
internalNodeType: InternalNodeType.STATION,
|
||||
trackDefinitions: [
|
||||
{
|
||||
startPoint: Direction.NORTH,
|
||||
type: TrackType.RAIL,
|
||||
},
|
||||
{
|
||||
startPoint: Direction.EAST,
|
||||
type: TrackType.ROAD,
|
||||
},
|
||||
{
|
||||
startPoint: Direction.SOUTH,
|
||||
type: TrackType.RAIL,
|
||||
},
|
||||
{
|
||||
startPoint: Direction.WEST,
|
||||
type: TrackType.RAIL,
|
||||
},
|
||||
],
|
||||
});
|
||||
const T_JUNCTION_WITH_ROAD_AT_CENTER: Piece = new Piece({
|
||||
useInternalTracks: true,
|
||||
internalNodeType: InternalNodeType.STATION,
|
||||
trackDefinitions: [
|
||||
{
|
||||
startPoint: Direction.NORTH,
|
||||
type: TrackType.RAIL,
|
||||
},
|
||||
{
|
||||
startPoint: Direction.EAST,
|
||||
type: TrackType.ROAD,
|
||||
},
|
||||
{
|
||||
startPoint: Direction.SOUTH,
|
||||
type: TrackType.RAIL,
|
||||
},
|
||||
],
|
||||
});
|
||||
const STRAIGHT_TRACK_CHANGE: Piece = new Piece({
|
||||
useInternalTracks: true,
|
||||
internalNodeType: InternalNodeType.STATION,
|
||||
trackDefinitions: [
|
||||
{
|
||||
startPoint: Direction.EAST,
|
||||
type: TrackType.ROAD,
|
||||
},
|
||||
{
|
||||
startPoint: Direction.WEST,
|
||||
type: TrackType.RAIL,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
export enum PieceId {
|
||||
P01 = "P01",
|
||||
P02 = "P02",
|
||||
P03 = "P03",
|
||||
P04 = "P04",
|
||||
P05 = "P05",
|
||||
P06 = "P06",
|
||||
P07 = "P07",
|
||||
P08 = "P08",
|
||||
P09 = "P09",
|
||||
P10 = "P10",
|
||||
P11 = "P11",
|
||||
P12 = "P12",
|
||||
P13 = "P13",
|
||||
P14 = "P14",
|
||||
P15 = "P15",
|
||||
P16 = "P16",
|
||||
P17 = "P17",
|
||||
P18 = "P18",
|
||||
P19 = "P19",
|
||||
P20 = "P20",
|
||||
P21 = "P21",
|
||||
P22 = "P22",
|
||||
}
|
||||
|
||||
export const pieceMap: Record<PieceId, Piece> = {
|
||||
[PieceId.P01]: STRAIGHT_RAIL,
|
||||
[PieceId.P02]: TURN_RAIL,
|
||||
[PieceId.P03]: FOUR_WAY_CROSS_RAIL,
|
||||
[PieceId.P04]: T_JUNCTION_RAIL,
|
||||
[PieceId.P05]: DEAD_END_STATION_RAIL,
|
||||
[PieceId.P06]: TURN_RAIL_TO_ROAD,
|
||||
[PieceId.P07]: T_JUNCTION_WITH_ROAD_ON_SIDE,
|
||||
[PieceId.P08]: FOUR_WAY_WITH_ONE_ROAD,
|
||||
[PieceId.P09]: T_JUNCTION_WITH_ROAD_AT_CENTER,
|
||||
[PieceId.P10]: STRAIGHT_TRACK_CHANGE,
|
||||
};
|
||||
|
|
@ -19,6 +19,6 @@ export class Cell {
|
|||
public getNodeAt(direction: Direction): ExternalNode {
|
||||
const node = this.externalNodes.get(direction);
|
||||
if (!node) throw Error(`Could not find node at ${direction}`);
|
||||
return this.externalNodes.get(direction) as ExternalNode;
|
||||
return node!;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,6 @@ export class ExternalNode {
|
|||
if (!this.border) {
|
||||
throw Error(`Missing border for node`);
|
||||
}
|
||||
return (this.border as Border).traverseFrom(this);
|
||||
return this.border.traverseFrom(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import { randomUUID } from "crypto";
|
||||
import { InternalNodeType } from "../constants/InternalNodeType";
|
||||
|
||||
export class InternalNode {
|
||||
id: string;
|
||||
type: string;
|
||||
type: InternalNodeType;
|
||||
|
||||
constructor() {
|
||||
constructor(type: InternalNodeType) {
|
||||
this.id = randomUUID();
|
||||
this.type = "STATION";
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,46 +4,66 @@ import { Cell } from "./Cell";
|
|||
import { InternalNode } from "./InternalNode";
|
||||
import { PlacedPiece } from "./PlacedPiece";
|
||||
import { Node } from "./Node";
|
||||
import { InternalNodeType } from "../constants/InternalNodeType";
|
||||
|
||||
export interface TrackProps {
|
||||
startPoint: Direction;
|
||||
endPoint?: Direction;
|
||||
isInternal: boolean;
|
||||
type: TrackType;
|
||||
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 {
|
||||
tracks: Set<{
|
||||
joinedPoints: {
|
||||
firstPoint: Direction;
|
||||
secondPoint: Direction | InternalNode;
|
||||
};
|
||||
type: TrackType;
|
||||
}>;
|
||||
internalNodes: Set<InternalNode>;
|
||||
readonly tracks: Set<Track>;
|
||||
readonly internalNode?: InternalNode;
|
||||
|
||||
constructor(hasInternalNode: boolean, trackDefinitions: TrackProps[]) {
|
||||
const internalNode = new InternalNode();
|
||||
this.internalNodes = new Set();
|
||||
if (hasInternalNode) {
|
||||
this.internalNodes.add(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(
|
||||
trackDefinitions.map((track) => {
|
||||
if (!track.isInternal && !track.endPoint) {
|
||||
throw Error("Missing direction for non-internal track");
|
||||
}
|
||||
pieceProps.trackDefinitions.map((trackDefinition) => {
|
||||
return {
|
||||
joinedPoints: {
|
||||
firstPoint: track.startPoint,
|
||||
secondPoint: track.isInternal
|
||||
? internalNode
|
||||
: (track.endPoint as Direction),
|
||||
firstPoint: trackDefinition.startPoint,
|
||||
secondPoint: this.internalNode!,
|
||||
},
|
||||
type: track.type,
|
||||
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) {
|
||||
|
|
@ -55,14 +75,14 @@ export class Piece {
|
|||
firstNode: cell.getNodeAt(track.joinedPoints.firstPoint),
|
||||
secondNode:
|
||||
track.joinedPoints.secondPoint instanceof Node
|
||||
? track.joinedPoints.secondPoint as Node
|
||||
? (track.joinedPoints.secondPoint as Node)
|
||||
: cell.getNodeAt(track.joinedPoints.secondPoint as Direction),
|
||||
},
|
||||
type: track.type,
|
||||
};
|
||||
}),
|
||||
),
|
||||
this.internalNodes,
|
||||
this.internalNode,
|
||||
cell,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ export class PlacedPiece {
|
|||
};
|
||||
type: TrackType;
|
||||
}>;
|
||||
internalNodes: Set<InternalNode>;
|
||||
internalNode?: InternalNode;
|
||||
cell: Cell;
|
||||
|
||||
constructor(
|
||||
|
|
@ -19,11 +19,11 @@ export class PlacedPiece {
|
|||
nodes: { firstNode: Node; secondNode: Node };
|
||||
type: TrackType;
|
||||
}>,
|
||||
internalNodes: Set<InternalNode>,
|
||||
internalNodes: InternalNode | undefined,
|
||||
cell: Cell,
|
||||
) {
|
||||
this.tracks = tracks;
|
||||
this.internalNodes = internalNodes;
|
||||
this.internalNode = internalNodes;
|
||||
this.cell = cell;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue