diff --git a/src/sim/transactions.ts b/src/sim/transactions.ts index 047d112..6a104c7 100644 --- a/src/sim/transactions.ts +++ b/src/sim/transactions.ts @@ -2,7 +2,7 @@ import { Catalog, getGame } from './catalog'; import { customerMinimumAsk, priceOf } from './economy'; import { Customer } from './customers'; import { addToBackroom, getSlot, ItemRef, takeFromSlot } from './inventory'; -import { addStamp, currentProgram, issueCard, joinProbability, Reward, StampType } from './loyalty'; +import { addStamp, currentProgram, issueCard, joinProbability, Reward, setProgram, StampTrack, StampType } from './loyalty'; import { random } from './rng'; import { adjustReputation, GameState } from './state'; @@ -128,6 +128,12 @@ export function trade( return { accepted: true, customerPaysCents, shopPaysCents, voucherGivenCents }; } +/** Replaces the loyalty program and applies the reputation penalty for a less generous one. */ +export function changeLoyaltyProgram(state: GameState, tracks: StampTrack[]): void { + const { reputationDelta } = setProgram(state.loyalty, tracks); + adjustReputation(state, reputationDelta); +} + export function recordLostRequest(state: GameState): void { state.day.lostRequests += 1; adjustReputation(state, -1); diff --git a/tests/sim/transactions.test.ts b/tests/sim/transactions.test.ts index f7dab32..41cba3d 100644 --- a/tests/sim/transactions.test.ts +++ b/tests/sim/transactions.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { buyBack, recordLostRequest, recordSatisfiedRequest, sell, trade } from '../../src/sim/transactions'; +import { buyBack, changeLoyaltyProgram, recordLostRequest, recordSatisfiedRequest, sell, trade } from '../../src/sim/transactions'; import { createNewGame } from '../../src/sim/state'; import { backroomQty, getSlot } from '../../src/sim/inventory'; import { issueCard, setProgram } from '../../src/sim/loyalty'; @@ -198,3 +198,20 @@ describe('reward and cash edge cases', () => { expect(s.day.trades).toBe(0); }); }); + +describe('changeLoyaltyProgram', () => { + it('lowers reputation by 2 when the program becomes less generous', () => { + const s = createNewGame(1); + s.reputation = 50; + changeLoyaltyProgram(s, [{ stampType: 'buy_new', slots: 20, reward: { kind: 'voucher', valueCents: 500 } }]); + expect(s.reputation).toBe(48); + expect(s.loyalty.programs).toHaveLength(2); + }); + + it('leaves reputation unchanged when the program is more generous', () => { + const s = createNewGame(1); + s.reputation = 50; + changeLoyaltyProgram(s, [{ stampType: 'buy_new', slots: 5, reward: { kind: 'voucher', valueCents: 1000 } }]); + expect(s.reputation).toBe(50); + }); +});