// One question, one answer. // // The round before this found the bank check and the standings reading `seat.stack` // where the felt reads the table's starting stack — two parts of the tool disagreeing // about how much money is on the table. This is the sweep that followed: everywhere // else the same two questions get asked, asked the same way. // // "What is this seat holding?" -> HoldemState.chipsHeldBy // "Is anybody in this chair?" -> HoldemState.seatInPlay const test = require("node:test"); const { describe } = require("node:test"); const assert = require("node:assert"); const { HoldemState, Betting, SettleUp } = require("./load"); const openedOnTheDefault = (stack = 200) => { const state = HoldemState.createDefault(); HoldemState.resizeSeats(state, 6); state.defaultStack = stack; ["Ann", "Ben", "Cal"].forEach((name, i) => { state.seats[i].name = name; state.seats[i].inHand = true; state.seats[i].buyIns = stack; }); return state; }; describe("what a seat is holding", () => { test("is the same number the felt plays with", () => { const state = openedOnTheDefault(); state.seats.forEach((player, i) => { if (i > 2) return; assert.equal(HoldemState.chipsHeldBy(state, player), Betting.stackOf(state, player)); }); }); test("and is nothing at all for an empty chair", () => { const state = openedOnTheDefault(); // Betting's own answer for an empty chair is the table default, because it is // only ever asked about seats that are in a hand. The money side has to ask // about all ten chairs, so it checks whether anybody is in them first. assert.equal(Betting.stackOf(state, state.seats[5]), 200); assert.equal(HoldemState.chipsHeldBy(state, state.seats[5]), 0); }); test("counts a stack the dealer typed over the table's default", () => { const state = openedOnTheDefault(); state.seats[0].stack = 75; assert.equal(HoldemState.chipsHeldBy(state, state.seats[0]), 75); }); }); describe("is anybody in this chair", () => { const empty = () => HoldemState.createDefault().seats[0]; test("an untouched chair is empty", () => { assert.equal(HoldemState.seatInPlay(empty()), false); assert.equal(HoldemState.seatInPlay(null), false); }); test("a name, chips, cash, a bet or a dealt hand all count", () => { [ ["a name", p => { p.name = "Ann"; }], ["chips", p => { p.stack = 50; }], ["cash taken", p => { p.buyIns = 100; }], ["a bet in front of them", p => { p.committed = 5; }], ["money already swept in", p => { p.amountOverride = 20; }], ["a hand dealt to them", p => { p.inHand = true; }], ].forEach(([what, mark]) => { const seat = empty(); mark(seat); assert.equal(HoldemState.seatInPlay(seat), true, what); }); }); test("whitespace is not a name", () => { const seat = empty(); seat.name = " "; assert.equal(HoldemState.seatInPlay(seat), false); }); }); describe("the parts that used to disagree", () => { test("the open seats and the seat count see the same empty chairs", () => { const state = openedOnTheDefault(); // Three players, six chairs. assert.deepEqual(HoldemState.openSeats(state), [3, 4, 5]); const occupied = state.seats.filter(p => HoldemState.seatInPlay(p)).length; assert.equal(occupied + HoldemState.openSeats(state).length, state.seats.length); }); test("a chair holding only a dealt hand is not offered to the waiting list", () => { // The old test looked at name, buy-ins and stack. A seat marked in-hand with // none of those would have been handed to the next person in the queue, on top // of whoever was already playing it. const state = openedOnTheDefault(); state.seats[4].inHand = true; assert.deepEqual(HoldemState.openSeats(state), [3, 5]); HoldemState.addToWaitingList(state, "Priya"); const result = HoldemState.seatFromWaitingList(state, state.waitingList[0].id, 4); assert.equal(result.ok, false); }); test("the bank, the standings and the settle-up all price the night the same way", () => { const state = openedOnTheDefault(); state.seats[0].stack = 320; // Ann is up state.seats[1].stack = 80; // Ben is down const bank = HoldemState.bankReconciliation(state); const standings = HoldemState.sessionStandings(state); const chipsFromStandings = standings .filter(row => !row.cashedOut) .reduce((sum, row) => sum + row.chipsInFront, 0); assert.equal(bank.chipsInPlay, chipsFromStandings, "same chips on the table"); assert.equal(bank.balanced, true); // And the payments the dealer is told to make add up to the same money. const plan = SettleUp.plan(standings); const owed = standings.reduce((sum, row) => sum + Math.max(0, row.cashPosition), 0); const paid = plan.payments.reduce((sum, row) => sum + row.amount, 0); assert.equal(paid + (plan.shortBy || 0) - (plan.overBy || 0), owed); }); test("a player still holding the table's starting stack is in all three", () => { const state = openedOnTheDefault(); const standings = HoldemState.sessionStandings(state); assert.equal(standings.length, 3); assert.deepEqual(standings.map(row => row.chipsInFront), [200, 200, 200]); assert.equal(HoldemState.bankReconciliation(state).chipsInPlay, 600); assert.deepEqual(SettleUp.plan(standings).payments, [], "everyone is even, so nobody pays anybody"); }); });