Disallow piece placement when piece is not connected to adjacent piece or exit
parent
b692caf93d
commit
949969bda3
|
|
@ -294,7 +294,7 @@ const T_JUNCTION_ROAD: Piece = new Piece({
|
|||
},
|
||||
{
|
||||
startPoint: Direction.WEST,
|
||||
type: TrackType.RAIL,
|
||||
type: TrackType.ROAD,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
import { CellType } from "../constants/CellType";
|
||||
import { Direction } from "../constants/Direction";
|
||||
import { Direction, directions } from "../constants/Direction";
|
||||
import { ExitType } from "../constants/ExitType";
|
||||
import { PieceId, pieceMap } from "../constants/Pieces";
|
||||
import { TrackType } from "../constants/TrackType";
|
||||
import { Exit } from "./Exit";
|
||||
import { ExternalNode } from "./ExternalNode";
|
||||
import { InternalNode } from "./InternalNode";
|
||||
import { Piece } from "./Piece";
|
||||
import { PlacedPiece } from "./PlacedPiece";
|
||||
|
||||
export class Cell {
|
||||
|
|
@ -33,45 +35,72 @@ 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}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
const piece: Piece = pieceMap[pieceId];
|
||||
|
||||
this.validatePiecePlacement(piece);
|
||||
|
||||
this.placedPiece = {
|
||||
piece: piece.toPlacedPiece(this),
|
||||
id: pieceId,
|
||||
};
|
||||
}
|
||||
|
||||
private validatePiecePlacement(piece: Piece) {
|
||||
const hasAnyConnection = Array.from(piece.tracks)
|
||||
.map((track) => {
|
||||
const trackExternalNodes = [
|
||||
this.getNodeAt(track.joinedPoints.firstPoint),
|
||||
];
|
||||
if (!(track.joinedPoints.secondPoint instanceof InternalNode)) {
|
||||
trackExternalNodes.push(
|
||||
this.getNodeAt(track.joinedPoints.secondPoint),
|
||||
);
|
||||
}
|
||||
return {
|
||||
trackExternalNodes: trackExternalNodes,
|
||||
trackType: track.type,
|
||||
};
|
||||
})
|
||||
.some(({ trackExternalNodes, trackType }) => {
|
||||
let isTrackConnected: boolean = false;
|
||||
trackExternalNodes
|
||||
.filter((node) => node.traverseBorder() instanceof Exit)
|
||||
.forEach((node) => {
|
||||
const exitType = (node.traverseBorder() as Exit).type;
|
||||
isTrackConnected = true;
|
||||
if (
|
||||
exitType !== ExitType.AMBIVALENT &&
|
||||
exitType.toString() !== trackType.toString()
|
||||
) {
|
||||
throw Error(
|
||||
`Unable to place piece, invalid exit type at direction ${node.direction}`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
trackExternalNodes
|
||||
.filter((node) => node.traverseBorder() instanceof ExternalNode)
|
||||
.forEach((node) => {
|
||||
const adjacentExternalNode = node.traverseBorder() as ExternalNode;
|
||||
const adjacentTrack =
|
||||
adjacentExternalNode.cell.placedPiece?.piece.findTrackForDirection(
|
||||
adjacentExternalNode.direction,
|
||||
);
|
||||
if (adjacentTrack !== undefined) {
|
||||
isTrackConnected = true;
|
||||
if (adjacentTrack.type !== trackType) {
|
||||
throw Error(
|
||||
`Unable to place piece next to another due to conflicting track types at ${node.direction}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return isTrackConnected;
|
||||
});
|
||||
|
||||
if (!hasAnyConnection) {
|
||||
throw Error("No adjacent exit or piece available to connect to");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue