이것저것 수정중.. 지금상태로는 안돌아감
This commit is contained in:
parent
992737ef33
commit
97a0533afd
@ -1,7 +1,11 @@
|
||||
import type { DurableObjectNamespace, DurableObjectState } from '@cloudflare/workers-types';
|
||||
import type { Session, BettingInfo } from './types';
|
||||
import type { Session } from './types';
|
||||
import { applyBetResults } from './game-results';
|
||||
|
||||
// 게임 지속 시간 상수 (ms)
|
||||
export const NO_MORE_BET_DURATION_MS = 15_000; // 15초
|
||||
export const BETTING_DURATION_MS = 45_000; // 45초
|
||||
|
||||
export interface Env {
|
||||
COUNTER: DurableObjectNamespace;
|
||||
}
|
||||
@ -141,18 +145,15 @@ export class CounterDurableObject {
|
||||
private startNoMoreBetPeriod() {
|
||||
this.noMoreBet = true;
|
||||
this.noMoreBetStartTime = Date.now();
|
||||
this.noMoreBetEndTime = this.noMoreBetStartTime + 15000; // 15초
|
||||
this.noMoreBetEndTime = this.noMoreBetStartTime + NO_MORE_BET_DURATION_MS; // 15초
|
||||
|
||||
// 3개의 주사위 랜덤 생성 (1-6)
|
||||
this.dice1 = Math.floor(Math.random() * 6) + 1;
|
||||
this.dice2 = Math.floor(Math.random() * 6) + 1;
|
||||
this.dice3 = Math.floor(Math.random() * 6) + 1;
|
||||
|
||||
// 주사위 합계
|
||||
const sum = this.dice1 + this.dice2 + this.dice3;
|
||||
|
||||
// 추출된 함수로 배팅 결과 계산 및 세션 갱신
|
||||
applyBetResults(this.sessions, sum);
|
||||
applyBetResults(this.sessions, this.dice1, this.dice2, this.dice3);
|
||||
|
||||
// 상태 저장
|
||||
this.ctx.storage.put('noMoreBet', this.noMoreBet);
|
||||
@ -166,14 +167,14 @@ export class CounterDurableObject {
|
||||
}
|
||||
this.gameTimer = setTimeout(() => {
|
||||
this.startBettingPeriod();
|
||||
}, 15000);
|
||||
}, NO_MORE_BET_DURATION_MS);
|
||||
}
|
||||
|
||||
// 2번 로직: noMoreBet = false, 45초간 유지
|
||||
private startBettingPeriod() {
|
||||
this.noMoreBet = false;
|
||||
this.noMoreBetStartTime = Date.now();
|
||||
this.noMoreBetEndTime = this.noMoreBetStartTime + 45000; // 45초
|
||||
this.noMoreBetEndTime = this.noMoreBetStartTime + BETTING_DURATION_MS; // 45초
|
||||
|
||||
// 주사위 값 클리어
|
||||
this.dice1 = null;
|
||||
@ -205,7 +206,7 @@ export class CounterDurableObject {
|
||||
}
|
||||
this.gameTimer = setTimeout(() => {
|
||||
this.startNoMoreBetPeriod();
|
||||
}, 45000);
|
||||
}, BETTING_DURATION_MS);
|
||||
}
|
||||
|
||||
async webSocketClose(ws: WebSocket, code: number, _reason: string, _wasClean: boolean) {
|
||||
@ -222,21 +223,6 @@ export class CounterDurableObject {
|
||||
// WebSocket Hibernation API를 사용할 때는 getWebSockets()로 실제 연결 수를 확인
|
||||
const connectedWebSockets = this.ctx.getWebSockets();
|
||||
|
||||
// 전체 사용자 배팅 내역 수집
|
||||
const allBettings: BettingInfo[] = [];
|
||||
|
||||
this.sessions.forEach((session) => {
|
||||
if (session.nickname && (session.oddBet > 0 || session.evenBet > 0 || session.bigBet > 0 || session.smallBet > 0)) {
|
||||
allBettings.push({
|
||||
nickname: session.nickname,
|
||||
oddBet: session.oddBet,
|
||||
evenBet: session.evenBet,
|
||||
bigBet: session.bigBet,
|
||||
smallBet: session.smallBet
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 각 세션별로 메시지 전송
|
||||
// @ts-ignore - Cloudflare Workers types 불일치
|
||||
connectedWebSockets.forEach((ws: WebSocket) => {
|
||||
@ -258,8 +244,7 @@ export class CounterDurableObject {
|
||||
bigResult: session?.bigResult,
|
||||
smallResult: session?.smallResult,
|
||||
lastWinAmount: session?.lastWinAmount,
|
||||
// 전체 사용자 배팅 내역
|
||||
allBettings: allBettings
|
||||
|
||||
});
|
||||
|
||||
ws.send(message);
|
||||
|
||||
@ -5,7 +5,9 @@ import type { Session } from './types';
|
||||
* 승리 시 배팅금액 * 2 지급, 패배 시 이미 차감된 상태 유지.
|
||||
* lastWinAmount = (총 승리 수령액 - 총 배팅액)
|
||||
*/
|
||||
export function applyBetResults(sessions: Map<WebSocket, Session>, sum: number) {
|
||||
export function applyBetResults(sessions: Map<WebSocket, Session>, dice1: number, dice2: number, dice3: number) {
|
||||
// 주사위 합계
|
||||
const sum = dice1 + dice2 + dice3;
|
||||
const isOdd = sum % 2 === 1;
|
||||
const isBig = sum >= 10; // 10~18: 대
|
||||
|
||||
|
||||
132
src/lib/types.ts
132
src/lib/types.ts
@ -1,82 +1,72 @@
|
||||
export interface Session {
|
||||
id: string;
|
||||
token: string;
|
||||
webSocket: WebSocket;
|
||||
nickname?: string;
|
||||
capital?: number;
|
||||
// 배팅 정보
|
||||
oddBet: number;
|
||||
evenBet: number;
|
||||
bigBet: number;
|
||||
smallBet: number;
|
||||
// 결과
|
||||
oddResult?: 'win' | 'lose' | null;
|
||||
evenResult?: 'win' | 'lose' | null;
|
||||
bigResult?: 'win' | 'lose' | null;
|
||||
smallResult?: 'win' | 'lose' | null;
|
||||
lastWinAmount?: number;
|
||||
betInfo: BettingInfo[]; // 배팅 정보
|
||||
capital?: number; // 현재 자본금
|
||||
}
|
||||
|
||||
export interface BettingInfo {
|
||||
nickname: string;
|
||||
oddBet: number;
|
||||
evenBet: number;
|
||||
bigBet: number;
|
||||
smallBet: number;
|
||||
gameId: string; // 게임 고유 ID
|
||||
betType: BetTypeKey;
|
||||
betMoney: number; //배팅금액
|
||||
isWin?: boolean; //승리여부
|
||||
winMoney?: number; //승리금액
|
||||
}
|
||||
|
||||
export const BetType = {
|
||||
BIG: {
|
||||
category: 'A',
|
||||
typeDescriptionEng: 'Big / Small Bet',
|
||||
typeDescriptionKr: '대/소 배팅',
|
||||
tripeLose: true,
|
||||
key: 'big',
|
||||
keyName: 'Big Bet',
|
||||
rslt: 'big_rslt',
|
||||
rsltName: 'Big Result',
|
||||
winConditionDescription: '주사위 총합 10~18',
|
||||
maxAmount: 300000,
|
||||
payout: 2,
|
||||
},
|
||||
SMALL: {
|
||||
category: 'A',
|
||||
typeDescriptionEng: 'Big / Small Bet',
|
||||
typeDescriptionKr: '대/소 배팅',
|
||||
tripeLose: true,
|
||||
key: 'small',
|
||||
keyName: 'Small Bet',
|
||||
rslt: 'small_rslt',
|
||||
rsltName: 'Small Result',
|
||||
winConditionDescription: '주사위 총합 1~9',
|
||||
maxAmount: 300000,
|
||||
payout: 2,
|
||||
},
|
||||
EVEN: {
|
||||
category: 'B',
|
||||
typeDescriptionEng: 'Even / Odd Bet',
|
||||
typeDescriptionKr: '홀/짝 배팅',
|
||||
tripeLose: true,
|
||||
key: 'even',
|
||||
keyName: 'Even Bet',
|
||||
rslt: 'even_rslt',
|
||||
rsltName: 'Even Result',
|
||||
winConditionDescription: '주사위 총합 짝수',
|
||||
maxAmount: 300000,
|
||||
payout: 2,
|
||||
},
|
||||
ODD: {
|
||||
category: 'B',
|
||||
typeDescriptionEng: 'Even / Odd Bet',
|
||||
typeDescriptionKr: '홀/짝 배팅',
|
||||
tripeLose: true,
|
||||
key: 'odd',
|
||||
keyName: 'Odd Bet',
|
||||
rslt: 'odd_rslt',
|
||||
rsltName: 'Odd Result',
|
||||
winConditionDescription: '주사위 총합 홀수',
|
||||
maxAmount: 300000,
|
||||
payout: 2,
|
||||
}
|
||||
// 11~17
|
||||
Big: { maxBet: 300, payout: 1 },
|
||||
Small: { maxBet: 300, payout: 1 },
|
||||
Even: { maxBet: 300, payout: 1 },
|
||||
Odd: { maxBet: 300, payout: 1 },
|
||||
Pair1: { maxBet: 35, payout: 8 },
|
||||
Pair2: { maxBet: 35, payout: 8 },
|
||||
Pair3: { maxBet: 35, payout: 8 },
|
||||
Pair4: { maxBet: 35, payout: 8 },
|
||||
Pair5: { maxBet: 35, payout: 8 },
|
||||
Pair6: { maxBet: 35, payout: 8 },
|
||||
Triple1: { maxBet: 2, payout: 150 },
|
||||
Triple2: { maxBet: 2, payout: 150 },
|
||||
Triple3: { maxBet: 2, payout: 150 },
|
||||
Triple4: { maxBet: 2, payout: 150 },
|
||||
Triple5: { maxBet: 2, payout: 150 },
|
||||
Triple6: { maxBet: 2, payout: 150 },
|
||||
TripleAny: { maxBet: 10, payout: 24 },
|
||||
Total4: { maxBet: 5, payout: 50 },
|
||||
Total5: { maxBet: 10, payout: 30 },
|
||||
Total6: { maxBet: 15, payout: 18 },
|
||||
Total7: { maxBet: 25, payout: 12 },
|
||||
Total8: { maxBet: 35, payout: 8 },
|
||||
Total9: { maxBet: 50, payout: 6 },
|
||||
Total10: { maxBet: 50, payout: 6 },
|
||||
Total11: { maxBet: 50, payout: 6 },
|
||||
Total12: { maxBet: 50, payout: 6 },
|
||||
Total13: { maxBet: 35, payout: 8 },
|
||||
Total14: { maxBet: 25, payout: 12 },
|
||||
Total15: { maxBet: 15, payout: 18 },
|
||||
Total16: { maxBet: 10, payout: 30 },
|
||||
Total17: { maxBet: 5, payout: 50 },
|
||||
Domino12:{ maxBet: 60, payout: 5 },
|
||||
Domino13:{ maxBet: 60, payout: 5 },
|
||||
Domino14:{ maxBet: 60, payout: 5 },
|
||||
Domino15:{ maxBet: 60, payout: 5 },
|
||||
Domino16:{ maxBet: 60, payout: 5 },
|
||||
Domino23:{ maxBet: 60, payout: 5 },
|
||||
Domino24:{ maxBet: 60, payout: 5 },
|
||||
Domino25:{ maxBet: 60, payout: 5 },
|
||||
Domino26:{ maxBet: 60, payout: 5 },
|
||||
Domino34:{ maxBet: 60, payout: 5 },
|
||||
Domino35:{ maxBet: 60, payout: 5 },
|
||||
Domino36:{ maxBet: 60, payout: 5 },
|
||||
Domino45:{ maxBet: 60, payout: 5 },
|
||||
Domino46:{ maxBet: 60, payout: 5 },
|
||||
Domino56:{ maxBet: 60, payout: 5 },
|
||||
Single1_N1:{ maxBet: 100 },
|
||||
Single2_N1:{ maxBet: 100 },
|
||||
Single3_N1:{ maxBet: 100 },
|
||||
Single4_N1:{ maxBet: 100 },
|
||||
Single5_N1:{ maxBet: 100 },
|
||||
Single6_N1:{ maxBet: 100 },
|
||||
} as const;
|
||||
|
||||
export type BetTypeKey = keyof typeof BetType;
|
||||
|
||||
@ -538,61 +538,6 @@
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- 전체 사용자 배팅 내역 -->
|
||||
{#if isConnected && allBettings.length > 0}
|
||||
<div class="mb-8 p-6 bg-gradient-to-br from-slate-50 to-gray-50 rounded-xl border-2 border-slate-200">
|
||||
<h2 class="text-xl font-bold text-center mb-4 text-gray-800">
|
||||
📊 전체 배팅 현황
|
||||
</h2>
|
||||
<div class="space-y-3 max-h-60 overflow-y-auto">
|
||||
{#each allBettings as betting}
|
||||
<div class="p-3 bg-white rounded-lg border border-gray-200">
|
||||
<div class="font-semibold text-gray-800 mb-2">{betting.nickname}</div>
|
||||
<div class="grid grid-cols-4 gap-2 text-sm">
|
||||
{#if betting.oddBet > 0}
|
||||
<div class="bg-blue-50 p-2 rounded text-center">
|
||||
<div class="text-xs text-gray-600">홀</div>
|
||||
<div class="font-semibold text-blue-600">{betting.oddBet.toLocaleString()}</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if betting.evenBet > 0}
|
||||
<div class="bg-pink-50 p-2 rounded text-center">
|
||||
<div class="text-xs text-gray-600">짝</div>
|
||||
<div class="font-semibold text-pink-600">{betting.evenBet.toLocaleString()}</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if betting.bigBet > 0}
|
||||
<div class="bg-orange-50 p-2 rounded text-center">
|
||||
<div class="text-xs text-gray-600">대</div>
|
||||
<div class="font-semibold text-orange-600">{betting.bigBet.toLocaleString()}</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if betting.smallBet > 0}
|
||||
<div class="bg-purple-50 p-2 rounded text-center">
|
||||
<div class="text-xs text-gray-600">소</div>
|
||||
<div class="font-semibold text-purple-600">{betting.smallBet.toLocaleString()}</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- 설명 -->
|
||||
<div class="mt-8 p-4 bg-gray-50 rounded-lg border border-gray-200">
|
||||
<h2 class="font-semibold text-gray-800 mb-2">게임 규칙</h2>
|
||||
<ul class="text-sm text-gray-600 space-y-1">
|
||||
<li>✅ Cloudflare Durable Objects로 상태 관리</li>
|
||||
<li>✅ WebSocket으로 실시간 양방향 통신</li>
|
||||
<li>🎲 <strong>베팅 기간 (45초)</strong>: 홀수 또는 짝수 선택 가능</li>
|
||||
<li>🚫 <strong>베팅 마감 (15초)</strong>: 주사위 결과 확인 및 대기</li>
|
||||
<li>📊 Progress bar로 남은 시간 시각화</li>
|
||||
<li>🔄 게임은 자동으로 반복됩니다</li>
|
||||
<li>👥 모든 접속자에게 실시간 동기화</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user