Stop telling a brand-new table its players are broke, and give it a way out #92
@@ -593,10 +593,19 @@ const ActionBar = {
|
||||
// thing: "only one player is dealt in" is wrong when four are sitting there
|
||||
// and three of them are just out of chips.
|
||||
const withChips = seated - broke.length;
|
||||
// "Nobody has chips left" is the wrong story for a table that never had
|
||||
// any. A dealer who has just named six people and not yet said what a
|
||||
// buy-in is gets told their players are busted, which sends them looking
|
||||
// for a rebuy button instead of the one field that fixes it.
|
||||
const nobodyHasEverBoughtIn = this.state.seats.every(p =>
|
||||
!(Number(p.buyIns) > 0) && !(Number(p.stack) > 0));
|
||||
|
||||
if (broke.length > 0 && withChips < 2) {
|
||||
line.textContent = withChips === 1
|
||||
? `Only ${listNames(Betting.liveSeats(this.state).map(s => s.index).filter(i => !broke.includes(i)))} has chips — ${listNames(broke)} ${broke.length === 1 ? "needs" : "need"} to buy in.`
|
||||
: "Nobody at the table has chips left. Add a buy-in to deal.";
|
||||
: nobodyHasEverBoughtIn
|
||||
? "Nobody has bought in yet. Set what everyone starts with, or give each seat their chips."
|
||||
: "Nobody at the table has chips left. Add a buy-in to deal.";
|
||||
} else {
|
||||
line.textContent = seated === 0
|
||||
? "Nobody is dealt in yet. Tap a seat to add a player."
|
||||
@@ -605,6 +614,26 @@ const ActionBar = {
|
||||
line.classList.add("dealPromptBlocked");
|
||||
wrap.appendChild(line);
|
||||
|
||||
// A blocked prompt with nothing to press is a dead end, and this was the
|
||||
// one a first-time dealer hits: six players named, a sentence saying they
|
||||
// have no chips, and no button anywhere on the bar. The starting stack is a
|
||||
// single field in the sidebar and the message never pointed at it.
|
||||
if (nobodyHasEverBoughtIn && seated > 0) {
|
||||
const row = document.createElement("div");
|
||||
row.className = "actionButtons";
|
||||
row.appendChild(this.button("Set starting stack", "actionDeal", () => {
|
||||
const field = document.getElementById("defaultStackInput");
|
||||
if (!field) return;
|
||||
const panel = field.closest("details");
|
||||
if (panel) panel.open = true;
|
||||
field.scrollIntoView({ block: "center", behavior: "smooth" });
|
||||
field.focus();
|
||||
field.select();
|
||||
}));
|
||||
wrap.appendChild(row);
|
||||
return wrap;
|
||||
}
|
||||
|
||||
// Named seats that aren't in the hand. Naming a chair now seats whoever is
|
||||
// in it, so reaching this takes something else — a table where everyone was
|
||||
// sat out, or a save from before that was true — but the way out of it
|
||||
|
||||
@@ -132,3 +132,50 @@ describe("the way back from a table where everybody is sat out", () => {
|
||||
assert.equal(state.seats.filter(p => p.inHand).length, 1, "empty chairs stay empty");
|
||||
});
|
||||
});
|
||||
|
||||
describe("a table where nobody has bought in", () => {
|
||||
// Different from a table that has busted out, and the difference is the whole
|
||||
// point: one needs a starting stack named, the other needs a rebuy. Telling a
|
||||
// dealer their brand-new players have "no chips left" sends them hunting for the
|
||||
// wrong thing.
|
||||
const neverBoughtIn = state => state.seats.every(p =>
|
||||
!(Number(p.buyIns) > 0) && !(Number(p.stack) > 0));
|
||||
|
||||
test("six freshly named players have never bought in", () => {
|
||||
const state = emptyTable();
|
||||
["Ann", "Ben", "Cal", "Dee", "Eve", "Fay"].forEach((name, i) => {
|
||||
state.seats[i].name = name;
|
||||
state.seats[i].inHand = true;
|
||||
});
|
||||
|
||||
assert.equal(neverBoughtIn(state), true);
|
||||
assert.equal(Betting.blindPreview(state), null, "and there is no hand to deal");
|
||||
});
|
||||
|
||||
test("a table that has busted out is not the same thing", () => {
|
||||
const state = makeTable({ seatCount: 6, seated: [0, 1], stack: 200 });
|
||||
state.seats.forEach(p => { p.buyIns = 200; p.stack = 0; });
|
||||
|
||||
assert.equal(neverBoughtIn(state), false, "they had chips — they lost them");
|
||||
});
|
||||
|
||||
test("one player still holding chips is not a never-bought-in table either", () => {
|
||||
const state = emptyTable();
|
||||
["Ann", "Ben"].forEach((name, i) => { state.seats[i].name = name; state.seats[i].inHand = true; });
|
||||
state.seats[0].stack = 50;
|
||||
|
||||
assert.equal(neverBoughtIn(state), false);
|
||||
});
|
||||
|
||||
test("naming a starting stack is enough to deal", () => {
|
||||
// The one field the message now points at. A seat with no stack of its own
|
||||
// falls back to the table default, so setting it seats everybody's chips at
|
||||
// once — which is why it's the right thing to send the dealer to.
|
||||
const state = emptyTable();
|
||||
["Ann", "Ben", "Cal"].forEach((name, i) => { state.seats[i].name = name; state.seats[i].inHand = true; });
|
||||
assert.equal(Betting.blindPreview(state), null);
|
||||
|
||||
state.defaultStack = 200;
|
||||
assert.ok(Betting.blindPreview(state), "one number and the table can play");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user