|
|
|
@@ -70,7 +70,19 @@ const Betting = {
|
|
|
|
|
for (let step = 1; step <= count; step++) {
|
|
|
|
|
const index = this.seatAt(state, fromIndex, step);
|
|
|
|
|
const player = state.seats[index];
|
|
|
|
|
if (player.inHand && !player.folded && this.stackOf(state, player) >= 0) return index;
|
|
|
|
|
if (player.inHand && !player.folded) return index;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Who the dealer asks next. A player who is all-in is still in the hand and still
|
|
|
|
|
// wins pots, but has no decision left, so the action passes over them.
|
|
|
|
|
nextToAct(state, fromIndex) {
|
|
|
|
|
const count = state.seatCount;
|
|
|
|
|
for (let step = 1; step <= count; step++) {
|
|
|
|
|
const index = this.seatAt(state, fromIndex, step);
|
|
|
|
|
const player = state.seats[index];
|
|
|
|
|
if (player.inHand && !player.folded && this.stackOf(state, player) > this.EPSILON_CHIPS) return index;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
},
|
|
|
|
@@ -156,7 +168,7 @@ const Betting = {
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
passAction(state, index) {
|
|
|
|
|
state.actingSeatIndex = this.isStreetComplete(state) ? null : this.nextLiveIndex(state, index);
|
|
|
|
|
state.actingSeatIndex = this.isStreetComplete(state) ? null : this.nextToAct(state, index);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// ---- Street and hand boundaries ----
|
|
|
|
@@ -184,8 +196,13 @@ const Betting = {
|
|
|
|
|
|
|
|
|
|
const nextStreetIndex = this.STREETS.indexOf(state.street || "preflop") + 1;
|
|
|
|
|
state.street = this.STREETS[nextStreetIndex] || "river";
|
|
|
|
|
state.actingSeatIndex = this.liveSeats(state).length > 1
|
|
|
|
|
? this.nextLiveIndex(state, state.dealerSeatIndex)
|
|
|
|
|
|
|
|
|
|
// It takes two players with chips to have a bet. Once everyone left is all-in
|
|
|
|
|
// — or only one player still has anything behind — the rest of the board is
|
|
|
|
|
// just dealt out, and asking someone to check when they have nothing to check
|
|
|
|
|
// with only slows the dealer down.
|
|
|
|
|
state.actingSeatIndex = this.canStillBet(state)
|
|
|
|
|
? this.nextToAct(state, state.dealerSeatIndex)
|
|
|
|
|
: null;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
@@ -193,6 +210,24 @@ const Betting = {
|
|
|
|
|
return this.liveSeats(state).length <= 1;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Players still in the hand who have chips left to put in. Fewer than two of them
|
|
|
|
|
// means the betting is finished even though the hand isn't.
|
|
|
|
|
seatsWithChips(state) {
|
|
|
|
|
return this.liveSeats(state).filter(s => this.stackOf(state, s.player) > this.EPSILON_CHIPS);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
EPSILON_CHIPS: 0.004,
|
|
|
|
|
|
|
|
|
|
canStillBet(state) {
|
|
|
|
|
return this.liveSeats(state).length > 1 && this.seatsWithChips(state).length > 1;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// True when the hand is still live but nobody can bet again — the dealer is just
|
|
|
|
|
// running the board out.
|
|
|
|
|
isRunningOut(state) {
|
|
|
|
|
return this.liveSeats(state).length > 1 && !this.canStillBet(state);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Deals a fresh betting round: blinds posted, action to the seat after the big
|
|
|
|
|
// blind, which is where a dealer expects to be looking when the cards go out.
|
|
|
|
|
beginHand(state) {
|
|
|
|
@@ -215,7 +250,7 @@ const Betting = {
|
|
|
|
|
|
|
|
|
|
state.currentBet = this.round(Math.max(this.committed(state.seats[sbIndex]), this.committed(state.seats[bbIndex])));
|
|
|
|
|
state.lastRaiseSize = bb || 0;
|
|
|
|
|
state.actingSeatIndex = this.nextLiveIndex(state, bbIndex);
|
|
|
|
|
state.actingSeatIndex = this.nextToAct(state, bbIndex);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Winners get their share put back in front of them.
|
|
|
|
|