big version with draft order and weather cards

This commit is contained in:
2026-04-08 17:46:42 -04:00
parent 4034ca55cf
commit a99a1f32e3
8 changed files with 966 additions and 59 deletions

51
src/rules-initiative.ts Normal file
View File

@@ -0,0 +1,51 @@
import type { GameState, InitiativeDraftState, PlayerId } from "./types";
export function getSeatBonuses(state: GameState) {
const graceRounds = Math.max(0, Math.floor(state.config.columns / state.players.length) - state.players.length);
const firstSeatBonus = state.round <= graceRounds ? 0 : 1;
return Array.from({ length: state.players.length }, (_, index) => (index === 0 ? firstSeatBonus : 0));
}
export function getRotatingBiddingOrder(state: GameState) {
const start = (state.initiativeAnchorPlayerId + state.round - 1) % state.players.length;
return Array.from({ length: state.players.length }, (_, index) => (start + index) % state.players.length);
}
export function getLowestGrowthBiddingOrder(state: GameState) {
const orderRank = new Map<PlayerId, number>(state.turnOrder.map((playerId, index) => [playerId, index]));
return [...state.players]
.sort((left, right) => {
if (left.lifetimeGrowthIncome !== right.lifetimeGrowthIncome) {
return left.lifetimeGrowthIncome - right.lifetimeGrowthIncome;
}
const leftRank = orderRank.get(left.id) ?? left.id;
const rightRank = orderRank.get(right.id) ?? right.id;
if (leftRank !== rightRank) {
return leftRank - rightRank;
}
return left.id - right.id;
})
.map((player) => player.id);
}
export function createInitiativeDraft(state: GameState): InitiativeDraftState {
const biddingOrder = state.config.biddingOrderRule === "lowest_growth_income"
? getLowestGrowthBiddingOrder(state)
: getRotatingBiddingOrder(state);
return {
biddingOrder,
biddingIndex: 0,
seatAssignments: Array.from({ length: state.players.length }, () => null),
seatBonuses: getSeatBonuses(state),
};
}
export function getSeatNumberForPlayer(draft: InitiativeDraftState, playerId: PlayerId) {
const seatIndex = draft.seatAssignments.findIndex((assignedPlayerId) => assignedPlayerId === playerId);
return seatIndex === -1 ? null : seatIndex + 1;
}