v0.3.0 — playtest fixes, two new rules, and §7 enforced
This commit is contained in:
+34
-14
@@ -123,7 +123,7 @@ export function connectionsFor(card: TrackCard): readonly PortPair[] {
|
||||
*/
|
||||
case 'curved':
|
||||
case 'sharpCurved': {
|
||||
const arc = card.geometry.arc ?? (card.geometry.hand === 'right' ? 'se' : 'sw');
|
||||
const arc = card.geometry.arc ?? (card.geometry.hand === 'right' ? 'sw' : 'se');
|
||||
return [[arc[0] as Port, arc[1] as Port]];
|
||||
}
|
||||
}
|
||||
@@ -131,8 +131,12 @@ export function connectionsFor(card: TrackCard): readonly PortPair[] {
|
||||
}
|
||||
|
||||
/**
|
||||
* A turnout with no stated orientation takes this one — the left-hand card at 0°, i.e. the
|
||||
* A turnout with no stated orientation takes this one — the right-hand card at 0°, i.e. the
|
||||
* `ne_sw` slope. Only hand-less fixtures reach it; `variantsFor` always states an orientation.
|
||||
*
|
||||
* The ORIENTATION here is unchanged by the handedness fix; only the word for it moved, because
|
||||
* `ne_sw` is now the right hand. Fixtures that lay a bare turnout get the same physical card as
|
||||
* before, which is what keeps existing tests and saves describing the same board.
|
||||
*/
|
||||
export const DEFAULT_TURNOUT: TurnoutOrientation = { stem: 'w', through: 'e', diverge: 's' };
|
||||
|
||||
@@ -197,9 +201,24 @@ export function joins(a: TrackCard, p: Port, b: TrackCard): boolean {
|
||||
* and south, but never between diagonals.
|
||||
*
|
||||
* So handedness is not decoration and not merely a supply label: it is the slope, and a siding
|
||||
* needs one card of each hand (a left turnout to drop off the main, a right curve to climb back).
|
||||
* Which printed row we call "left" is the one arbitrary bit, and it lives entirely in the two
|
||||
* tables below.
|
||||
* needs one card of each hand (a right turnout to drop off the main, a left curve to climb back).
|
||||
* Which printed row we call "left" is fixed by the prototype and lives entirely in the two tables
|
||||
* below.
|
||||
*
|
||||
* WHICH ROW IS WHICH. A turnout is named for the side the diverging route leaves toward, seen by a
|
||||
* train entering at the points. Take `{stem:'e', through:'w', diverge:'s'}`: the train enters at the
|
||||
* east edge heading west, and facing west its left hand points south — so a leg going south is a
|
||||
* LEFT-hand turnout. Turn the card 180° and it enters heading east with the leg going north, which
|
||||
* is left again; that invariance under rotation is exactly why the hand can be a property of the
|
||||
* card. Both orientations lie on `nw_se`, so LEFT IS `nw_se`.
|
||||
*
|
||||
* A curve has no points of its own, so it takes its hand from the turnout whose leg it continues —
|
||||
* which is what makes "a run-around needs one card of each hand" true. Both tables therefore put
|
||||
* left on the SAME diagonal: a left turnout's leg lands on `nw_se` and only a left curve can carry
|
||||
* it onward.
|
||||
*
|
||||
* Both tables were inverted until playtesting caught it, so every label named the mirror card. The
|
||||
* geometry was never wrong — the board draws from `connectionsFor` — only the words.
|
||||
*
|
||||
* §A.1's constraint is preserved: a turnout's two legs still never join each other.
|
||||
*/
|
||||
@@ -209,26 +228,27 @@ export type TrackVariant = {
|
||||
bypass?: Port;
|
||||
};
|
||||
|
||||
/** Left-hand cards lie on `ne_sw`, right-hand on `nw_se`; 0° sends the leg south, 180° north. */
|
||||
/** Left-hand curves lie on `nw_se`, right-hand on `ne_sw`; 0° sends the leg south, 180° north. */
|
||||
const CURVE_VARIANTS: Record<Hand, readonly TrackArc[]> = {
|
||||
left: ['sw', 'ne'],
|
||||
right: ['se', 'nw'],
|
||||
none: ['sw', 'ne'],
|
||||
left: ['se', 'nw'],
|
||||
right: ['sw', 'ne'],
|
||||
none: ['se', 'nw'],
|
||||
};
|
||||
|
||||
/** Left-hand turnouts lie on `nw_se`, right-hand on `ne_sw` — the same diagonals as the curves. */
|
||||
const TURNOUT_VARIANTS: Record<Hand, readonly TurnoutOrientation[]> = {
|
||||
left: [
|
||||
{ stem: 'w', through: 'e', diverge: 's' },
|
||||
{ stem: 'e', through: 'w', diverge: 'n' },
|
||||
],
|
||||
right: [
|
||||
{ stem: 'e', through: 'w', diverge: 's' },
|
||||
{ stem: 'w', through: 'e', diverge: 'n' },
|
||||
],
|
||||
none: [
|
||||
right: [
|
||||
{ stem: 'w', through: 'e', diverge: 's' },
|
||||
{ stem: 'e', through: 'w', diverge: 'n' },
|
||||
],
|
||||
none: [
|
||||
{ stem: 'e', through: 'w', diverge: 's' },
|
||||
{ stem: 'w', through: 'e', diverge: 'n' },
|
||||
],
|
||||
};
|
||||
|
||||
export function variantsFor(geometry: TrackGeometry, hand: Hand = 'none'): TrackVariant[] {
|
||||
|
||||
Reference in New Issue
Block a user