v0.4.4 — New Game dialog for the opening hand and the three revenue rates, Yard renamed Interchange, and two movement bugs behind a mirrored consist
This commit is contained in:
@@ -332,7 +332,20 @@ describe('ABS Signals amend the collision rule', () => {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('one Revenue to EVERY player when a train completes its run', () => {
|
||||
describe('train revenue per transit — paid to EVERY player when a train completes its run', () => {
|
||||
/**
|
||||
* `trainPerTransit` is a dial now, and it defaults to ZERO: at 1 it was worth ~5.4 Revenue against
|
||||
* a bot mean of 7.0, drowning out the freight and passenger economies the game is about. These
|
||||
* tests are about the rule, so they set the rate; the last one is about the default.
|
||||
*/
|
||||
const paying = (rate = 1, seed = 5): GameState =>
|
||||
createGame({
|
||||
id: 'g',
|
||||
seed,
|
||||
config: { ...config, houseRules: { revenue: { trainPerTransit: rate } } },
|
||||
playerNames: ['p'],
|
||||
});
|
||||
|
||||
/** A train sitting on the A/D track, made up and ready to highball. */
|
||||
const readyToLeave = (s: GameState, direction: 'east' | 'west' = 'east'): string => {
|
||||
const id = 'leaving';
|
||||
@@ -364,7 +377,7 @@ describe('one Revenue to EVERY player when a train completes its run', () => {
|
||||
});
|
||||
|
||||
it('pays every player once the train runs off the end of the Division', () => {
|
||||
const s = game();
|
||||
const s = paying();
|
||||
const before = s.players.map((p) => p.revenue);
|
||||
readyToLeave(s, 'east');
|
||||
|
||||
@@ -395,7 +408,7 @@ describe('one Revenue to EVERY player when a train completes its run', () => {
|
||||
});
|
||||
|
||||
it('pays nothing for a local crew, which is switching rather than running', () => {
|
||||
const s = game();
|
||||
const s = paying();
|
||||
const before = s.players[0]!.revenue;
|
||||
const id = readyToLeave(s, 'east');
|
||||
s.trays.get(id)!.trainNumber = null;
|
||||
@@ -404,6 +417,32 @@ describe('one Revenue to EVERY player when a train completes its run', () => {
|
||||
|
||||
assert.equal(s.players[0]!.revenue, before, 'a switching crew was paid as though it had completed a run');
|
||||
});
|
||||
|
||||
it('pays at the rate the game was dealt with, and nothing at the default of zero', () => {
|
||||
// Zero is not "one, suppressed": no revenue event is emitted at all, so the history does not
|
||||
// fill with "+0 Revenue" for work that did not pay.
|
||||
const run = (rate: number): { revenue: number; events: number } => {
|
||||
const s = rate === 0 ? game() : paying(rate);
|
||||
readyToLeave(s, 'east');
|
||||
let events = 0;
|
||||
let done = false;
|
||||
for (let i = 0; i < 20 && !done; i++) {
|
||||
s.movedThisPhase = new Set();
|
||||
s.clock.phase = 'mainline';
|
||||
const r = advance(s);
|
||||
events += r.events.filter(
|
||||
(e) => e.type === 'revenueChanged' && e.reason === 'a train completed its run',
|
||||
).length;
|
||||
done = r.events.some((e) => e.type === 'trainCompleted');
|
||||
}
|
||||
assert.ok(done, `the train never left the Division at rate ${rate}`);
|
||||
return { revenue: s.players[0]!.revenue, events };
|
||||
};
|
||||
|
||||
assert.deepEqual(run(0), { revenue: 0, events: 0 }, 'the default paid for a transit');
|
||||
assert.deepEqual(run(1), { revenue: 1, events: 1 });
|
||||
assert.deepEqual(run(5), { revenue: 5, events: 1 }, 'the top of the range pays 5 in one event');
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user