- 6-digit access key gate with long-lived HttpOnly cookie, brute-force limits - Lobby with saved player name and live table list - Table creation (name, starting stack, blinds, blind timer) - Table play screen stub (seats, button/SB/BB, phase, blinds, timer) - Security hardening: strict CSP, origin checks, host pinning, input sanitizing Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
58 lines
1.7 KiB
JavaScript
58 lines
1.7 KiB
JavaScript
// ブラインド計算(サーバ・ブラウザ共用)
|
|
(function (root, factory) {
|
|
if (typeof module === 'object' && module.exports) module.exports = factory();
|
|
else root.Blinds = factory();
|
|
})(typeof self !== 'undefined' ? self : this, function () {
|
|
'use strict';
|
|
|
|
// 1, 2, 3, 4, 5, 6, 10, 15, 20, 25, 30, 40, 50, 60, 75, 100, 150, ...
|
|
const MANTISSAS = [1, 1.5, 2, 2.5, 3, 4, 5, 6, 7.5];
|
|
const LADDER = [];
|
|
for (let e = 0; e <= 9; e++) {
|
|
for (const m of MANTISSAS) {
|
|
const v = Math.round(m * Math.pow(10, e) * 100) / 100;
|
|
if (Number.isInteger(v)) LADDER.push(v);
|
|
}
|
|
}
|
|
|
|
function nearestNice(x) {
|
|
if (!(x >= 1)) return 1;
|
|
let best = LADDER[0];
|
|
for (const v of LADDER) if (Math.abs(v - x) < Math.abs(best - x)) best = v;
|
|
return best;
|
|
}
|
|
|
|
// 開始スタックに合うブラインド(BB = スタックの約1/100)
|
|
function defaultBlinds(stack) {
|
|
const sb = nearestNice(stack / 200);
|
|
return { sb, bb: sb * 2 };
|
|
}
|
|
|
|
// 1レベルごとに約1.5倍
|
|
function nextSmallBlind(sb) {
|
|
const target = sb * 1.4;
|
|
for (const v of LADDER) if (v >= target && v > sb) return v;
|
|
return Math.ceil(sb * 1.5);
|
|
}
|
|
|
|
// level は 1 始まり
|
|
function blindsAt(sb0, bb0, level) {
|
|
const ratio = bb0 / sb0;
|
|
let sb = sb0;
|
|
let bb = bb0;
|
|
for (let i = 2; i <= level; i++) {
|
|
sb = nextSmallBlind(sb);
|
|
bb = Math.round(sb * ratio);
|
|
}
|
|
return { sb, bb };
|
|
}
|
|
|
|
function schedule(sb0, bb0, levels) {
|
|
const out = [];
|
|
for (let i = 1; i <= levels; i++) out.push(Object.assign({ level: i }, blindsAt(sb0, bb0, i)));
|
|
return out;
|
|
}
|
|
|
|
return { defaultBlinds, blindsAt, schedule };
|
|
});
|