๐ฐ ์ค๋์ ๋ณต๊ถ ์๋ฎฌ๋ ์ดํฐ - ๋น์ฒจ ํ๋ฅ ์ฒดํํ๊ธฐ
lottery-odds-simulator
๋ฌธ์ ์ค๋ช
๐ฏ ํ๋ก์ ํธ ๊ฐ์
๋ก๋, ์ฐ๊ธ๋ณต๊ถ, ์คํฌ๋์น ๋ฑ ๋ค์ํ ๋ณต๊ถ์ ๋น์ฒจ ํ๋ฅ ์ ์๋ฎฌ๋ ์ด์ ์ผ๋ก ์ฒดํํ๋ ์ธํฐ๋ํฐ๋ธ ํ์ด์ง์ ๋๋ค. ์ฌ์ฉ์๊ฐ ๋ณต๊ถ ์ข ๋ฅ๋ฅผ ์ ํํ๊ณ '๊ตฌ๋งค' ๋ฒํผ์ ๋๋ฅด๋ฉด ์ค์ ํ๋ฅ ์ ๊ธฐ๋ฐํ ๊ฒฐ๊ณผ๊ฐ ์ฆ์ ํ์๋๋ฉฐ, ๋์ ํต๊ณ(์ด ๊ตฌ๋งค ํ์, ๋น์ฒจ ํ์, ์์ต๋ฅ )๋ฅผ ์๊ฐ์ ์ผ๋ก ํ์ธํ ์ ์์ต๋๋ค. ํ๋ฅ ์ ์์ธํจ์ ์ฌ๋ฏธ์๊ฒ ๊ฒฝํํ๋ฉด์๋ ์ฌํ์ฑ ๊ฒฝ๊ณ ๋ฉ์์ง๋ฅผ ํจ๊ป ๋ ธ์ถํ์ฌ ๊ต์ก์ ํจ๊ณผ๋ฅผ ๋ ธ๋ฆฝ๋๋ค.
โจ ํ์ ๊ธฐ๋ฅ
-
๋ณต๊ถ ์ข ๋ฅ ์ ํ ์นด๋
- ๋ก๋(1๋ฑ ํ๋ฅ 1/8,145,060), ์ฐ๊ธ๋ณต๊ถ(1๋ฑ 1/5,000,000), ์คํฌ๋์น(1๋ฑ 1/500,000) ๋ฑ 3์ข ์ด์
- ๊ฐ ์นด๋์ ๋ณต๊ถ ์ด๋ฏธ์ง, ๊ฐ๊ฒฉ, 1๋ฑ ๋น์ฒจ๊ธ, ๋น์ฒจ ํ๋ฅ ํ์
- ์ ํ ์ ์นด๋ ๊ฐ์กฐ ํจ๊ณผ(border glow)
-
์๋ฎฌ๋ ์ด์ ์คํ
- '1ํ ๊ตฌ๋งค', '10ํ ๊ตฌ๋งค', '100ํ ๊ตฌ๋งค', '1000ํ ๊ตฌ๋งค' ๋ฒํผ
- ํด๋ฆญ ์ ์ ํ๋ ๋ณต๊ถ ์ข ๋ฅ์ ๋ฐ๋ผ ๋์ ์์ฑ โ ๋น์ฒจ ์ฌ๋ถ ํ์
- ์ ๋๋ฉ์ด์ ํจ๊ณผ(ํ์ ํ๋ ๋ณต๊ถ ์ด๋ฏธ์ง โ ๊ฒฐ๊ณผ ํ์ด๋์ธ)
-
๊ฒฐ๊ณผ ํ์ ์์ญ
- ๋น์ฒจ ์: ์ถํ ๋ฉ์์ง + ๋น์ฒจ๊ธ์ก (ํฐ ํฐํธ, ๊ธ์ ๋ฐฐ๊ฒฝ)
- ๋์ฒจ ์: ์๋ก ๋ฉ์์ง + "๋ค์ ๋์ !" ๋ฒํผ
- ์ต๊ทผ 5ํ ๊ฒฐ๊ณผ ํ์คํ ๋ฆฌ (๋น์ฒจ/๋์ฒจ ๋ฑ์ง)
-
๋์ ํต๊ณ ๋์๋ณด๋
- ์ด ๊ตฌ๋งค ํ์, ์ด ์ง์ถ ๊ธ์ก
- ๋น์ฒจ ํ์ (1๋ฑ/2๋ฑ/3๋ฑ ๋ฑ๊ธ๋ณ)
- ์ด ๋น์ฒจ๊ธ, ์์์ต (์ง์ถ - ๋น์ฒจ๊ธ, ๋ง์ด๋์ค์ผ ํ๋ฅ 99.9%)
- ์์ต๋ฅ ๊ทธ๋ํ (Chart.js ๋๋ ์์ CSS ํ๋ก๊ทธ๋ ์ค ๋ฐ)
-
๋ฆฌ์ & ๊ฒฝ๊ณ ๋ฉ์์ง
- ํต๊ณ ์ด๊ธฐํ ๋ฒํผ
- ํ์ด์ง ํ๋จ์ "์ด ์๋ฎฌ๋ ์ดํฐ๋ ๊ต์ก ๋ชฉ์ ์ ๋๋ค. ์ค์ ๋ณต๊ถ ๊ตฌ๋งค๋ ์ ์คํ ํ์ธ์" ๊ฒฝ๊ณ ๋ฌธ๊ตฌ
๐ ์ ํ ์ถ๊ฐ ๊ธฐ๋ฅ (๋ณด๋์ค)
- ์๋ ๊ตฌ๋งค ๋ชจ๋: 1์ด๋ง๋ค ์๋์ผ๋ก ๋ณต๊ถ ๊ตฌ๋งค (Start/Stop ๋ฒํผ)
- ๋น์ฒจ ์ฌ์ด๋ ํจ๊ณผ: Web Audio API๋ก ๋น์ฒจ ์ ํจ๊ณผ์ ์ฌ์
- ๋ณต๊ถ ์ปค์คํฐ๋ง์ด์ง: ์ฌ์ฉ์๊ฐ ์ง์ ๋ณต๊ถ ์ด๋ฆ, ๊ฐ๊ฒฉ, ํ๋ฅ ์ค์ ๊ฐ๋ฅ (LocalStorage ์ ์ฅ)
- ์์ํ: LocalStorage ๊ธฐ๋ฐ ์ ์ฒด ์ฌ์ฉ์ ์ต๊ณ ์์ต๋ฅ ์์ (์ต๋ช )
- ๋คํฌ๋ชจ๋ ์๋ ๋์: g5se modern shell ๋์์ธ ํ ํฐ ํ์ฉ
- ๊ณต์ ๊ธฐ๋ฅ: "๋ด ๋ณต๊ถ ๊ฒฐ๊ณผ ๊ณต์ ํ๊ธฐ" ๋ฒํผ โ ํด๋ฆฝ๋ณด๋ ๋ณต์ฌ (ํ ์คํธ ํํ)
๐จ ๋์์ธ ๊ฐ์ด๋
- ๋ณต๊ถ ์นด๋๋ 3์ด ๊ทธ๋ฆฌ๋ (๋ชจ๋ฐ์ผ์์ 1์ด)
- ๋น์ฒจ ์ confetti ์ ๋๋ฉ์ด์ (CSS keyframes ๋๋ canvas-confetti CDN)
- ํต๊ณ ์ซ์๋ ์นด์ดํ ์ ๋๋ฉ์ด์ ํจ๊ณผ
- ์์: ๋ก๋=๋ณด๋ผ, ์ฐ๊ธ๋ณต๊ถ=์ด๋ก, ์คํฌ๋์น=์ฃผํฉ ๋ฑ ๋ณต๊ถ๋ณ ๋ธ๋๋ ์ปฌ๋ฌ
- modern shell์
--m-surface,--m-text,--m-shadow๋ณ์๋ก ์นด๋ ๋ฐฐ๊ฒฝ/ํ ์คํธ/๊ทธ๋ฆผ์ ์ฒ๋ฆฌ
๐ ๊ธฐ์ ์คํ
- ํ๋ ์์ํฌ: g5se (๊ทธ๋๋ณด๋5 SE) โ PHP ๊ธฐ๋ฐ CMS
- DB: SQLite (์ ํ ์ฌํญ, ํต๊ณ ์์ํ ์ ์ฌ์ฉ. ๊ธฐ๋ณธ์ LocalStorage๋ก ์ถฉ๋ถ)
- ํ๋ก ํธ: ์์ HTML/CSS/JavaScript (Vanilla JS)
- ์คํ์ผ: g5se modern shell ๋์์ธ ํ ํฐ + ์ปค์คํ CSS
- ์ ๋๋ฉ์ด์ : CSS transitions + keyframes
์ ์ฝ ์กฐ๊ฑด
- โข g5se๊ฐ ์ค์น๋ ํ๊ฒฝ์์ ์์ (https://github.com/gnuboard/g5se main ๋ธ๋์น)
- โข Laravel/Composer/npm/Vite/React/Vue ๋ฑ ์ธ๋ถ ๋น๋ ๋๊ตฌ ์ ๋ ์ฌ์ฉ ๊ธ์ง
- โข ์์ PHP + g5se ์ปจ๋ฒค์ ๋ง ์ฌ์ฉ
- โข ํด๋ ๊ธฐ๋ฐ ์๋ ๋ผ์ฐํ : app/modules/lottery-odds-simulator/index.php ์์ฑ โ URL์ /lottery-odds-simulator
- โข modern shell ํ์ ์ ์ฉ (_head.inc.php + m-shell + _nav.inc.php + m-container + _footer.inc.php)
- โข ๋์์ธ ํ ํฐ ์ฌ์ฉ: var(--m-surface), var(--m-text), var(--m-shadow) ๋ฑ์ผ๋ก ๋คํฌ๋ชจ๋ ์๋ ๋์
- โข DB ์ฌ์ฉ ์ ์์ฒด SQLite ํ์ผ (G5_DATA_PATH.'/modules/lottery-odds-simulator.sqlite') โ g5se ๋ฉ์ธ DB ํ ์ด๋ธ ์์ฑ ๊ธ์ง
- โข ์ฌ์ฉ์ ๋ฐ์ดํฐ๋ htmlspecialchars()๋ก ์ด์ค์ผ์ดํ
- โข ์ธ๋ถ CDN ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ต์ํ (confetti๋ ์ ํ ์ฌํญ)
- โข ํต๊ณ ์ ์ฅ์ LocalStorage ์ฐ์ (SQLite๋ ๋ณด๋์ค)
ํ๋กฌํํธ ๋ ์ํผ
์๋ ํ๋กฌํํธ๋ฅผ ์์๋๋ก AI์๊ฒ ๋ณด๋ด๋ฉด ๋ฉ๋๋ค. ๋ณต์ฌ ๋ฒํผ์ ๋๋ฌ ๋ฐ๋ก ์ฌ์ฉํ์ธ์.
g5se๊ฐ ์ค์น๋ ๋๋ ํฐ๋ฆฌ(๋ฃจํธ์ `index.php`ยท`app/`์ด ์๋ ๊ณณ)์์ ์์ ์ ์์ํฉ๋๋ค. (g5se ์ค์น๋ https://github.com/gnuboard/g5se ์ฐธ๊ณ ) ์ด ๋จ๊ณ์์๋ ๋ณต๊ถ ์๋ฎฌ๋ ์ดํฐ ํ์ด์ง์ ๊ธฐ๋ณธ ๊ณจ๊ฒฉ์ ๋ง๋ญ๋๋ค. **์์ ๋ด์ฉ:** 1. `app/modules/lottery-odds-simulator/index.php` ํ์ผ์ ์์ฑํฉ๋๋ค. 2. modern shell ๊ณจ๊ฒฉ์ ์ ์ฉํฉ๋๋ค: - `_common.php` ์ธํด๋ฃจ๋ (g5se ์ง์ ์ปจํ ์คํธ) - `G5_THEME_PATH.'/modern/_head.inc.php'` ์ธํด๋ฃจ๋ (HTML head + ๋์์ธ ํ ํฐ ๋ก๋) - `./head.sub.php` ์ธํด๋ฃจ๋ (g5se ๊ณตํต ํค๋) - `<div class="m-shell">` ๋ํผ - `G5_THEME_PATH.'/modern/_nav.inc.php'` ์ธํด๋ฃจ๋ (์๋จ ๋ค๋น๊ฒ์ด์ ) - `<main class="m-container" style="padding: 32px 20px 48px;">`๋ก ๋ณธ๋ฌธ ์์ญ - `G5_THEME_PATH.'/modern/_footer.inc.php'` ์ธํด๋ฃจ๋ (ํ๋จ ํธํฐ) - `./tail.sub.php` ์ธํด๋ฃจ๋ (g5se ๊ณตํต ๊ผฌ๋ฆฌ) 3. ํ์ด์ง ์ ๋ชฉ์ `<h1 style="font-size: 2rem; font-weight: 700; margin-bottom: 1rem; color: var(--m-text);">๐ฐ ์ค๋์ ๋ณต๊ถ ์๋ฎฌ๋ ์ดํฐ</h1>`๋ก ์ถ๋ ฅํฉ๋๋ค. 4. ํ๋จ์ ๊ฒฝ๊ณ ๋ฌธ๊ตฌ๋ฅผ ๋ฃ์ต๋๋ค: `<p style="margin-top: 2rem; padding: 16px; background: var(--m-surface); border-left: 4px solid #f59e0b; color: var(--m-text-muted); font-size: 0.9rem;">โ ๏ธ ์ด ์๋ฎฌ๋ ์ดํฐ๋ ๊ต์ก ๋ชฉ์ ์ ๋๋ค. ์ค์ ๋ณต๊ถ ๊ตฌ๋งค๋ ์ ์คํ ํ์ธ์.</p>` **์ฐธ๊ณ :** - ๋ผ์ฐํธ ๋ฑ๋ก ๋ถํ์ (ํด๋ ๊ธฐ๋ฐ ์๋ ๋ผ์ฐํ ) - ์๋๊ฒฝ๋ก `./_common.php`, `./head.sub.php`, `./tail.sub.php`๋ g5se ์ง์ ์ด cwd๋ฅผ `app/`๋ก ์ก์์ฃผ๋ฏ๋ก ๊ทธ๋๋ก ์ฌ์ฉ - `G5_THEME_PATH`๋ `_common.php` ์ธํด๋ฃจ๋ ํ ์ฌ์ฉ ๊ฐ๋ฅ (ํ์ฌ ํ ๋ง ๊ฒฝ๋ก) **์์ ์ถ๋ ฅ:** ๋ธ๋ผ์ฐ์ ์์ `/lottery-odds-simulator` ์ ์ ์ g5se ์ฌ์ดํธ ๋ค๋น๊ฒ์ด์ /ํธํฐ์ ํจ๊ป "๐ฐ ์ค๋์ ๋ณต๊ถ ์๋ฎฌ๋ ์ดํฐ" ์ ๋ชฉ๊ณผ ๊ฒฝ๊ณ ๋ฌธ๊ตฌ๊ฐ ํ์๋ฉ๋๋ค.
๊ธฐ๋ ๊ฒฐ๊ณผ: app/modules/lottery-odds-simulator/index.php ํ์ผ์ด ์์ฑ๋๊ณ , /lottery-odds-simulator URL๋ก ์ ์ํ๋ฉด g5se modern shell(๋ค๋น๊ฒ์ด์ /ํธํฐ ํฌํจ)๊ณผ ํจ๊ป ํ์ด์ง ์ ๋ชฉ '๐ฐ ์ค๋์ ๋ณต๊ถ ์๋ฎฌ๋ ์ดํฐ'๊ฐ ํ์๋ฉ๋๋ค. ํ๋จ์ ๊ฒฝ๊ณ ๋ฌธ๊ตฌ๊ฐ ๋ ธ์ถ๋ฉ๋๋ค.
๋ณต๊ถ ์ข
๋ฅ ์ ํ ์นด๋ UI๋ฅผ ๋ง๋ญ๋๋ค.
**์์
๋ด์ฉ:**
1. `<main>` ์์ ๋ณต๊ถ ์ ํ ์น์
์ ์ถ๊ฐํฉ๋๋ค:
```html
<section style="margin-bottom: 2rem;">
<h2 style="font-size: 1.5rem; font-weight: 600; margin-bottom: 1rem; color: var(--m-text);">๋ณต๊ถ ์ข
๋ฅ ์ ํ</h2>
<div id="lotteryCards" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1rem;">
<!-- ์นด๋๋ JavaScript๋ก ๋์ ์์ฑ -->
</div>
</section>
```
2. `<main>` ๋๋๊ธฐ ์ ์ `<script>` ๋ธ๋ก์ ์ถ๊ฐํ์ฌ ๋ณต๊ถ ๋ฐ์ดํฐ๋ฅผ ์ ์ํ๊ณ ์นด๋๋ฅผ ๋ ๋๋งํฉ๋๋ค:
```javascript
const lotteries = [
{ id: 'lotto', name: '๋ก๋ 6/45', price: 1000, jackpot: '20์ต์', odds: 8145060, color: '#8b5cf6', emoji: '๐ฑ' },
{ id: 'pension', name: '์ฐ๊ธ๋ณต๊ถ', price: 1000, jackpot: '์ 700๋ง์ (20๋
)', odds: 5000000, color: '#10b981', emoji: '๐ฐ' },
{ id: 'scratch', name: '์คํฌ๋์น', price: 2000, jackpot: '1์ต์', odds: 500000, color: '#f97316', emoji: '๐ซ' }
];
let selectedLottery = null;
function renderCards() {
const container = document.getElementById('lotteryCards');
container.innerHTML = lotteries.map(lot => `
<div class="lottery-card" data-id="${lot.id}" style="
background: var(--m-surface);
border: 2px solid transparent;
border-radius: var(--m-radius-lg);
padding: 1.5rem;
cursor: pointer;
transition: all 0.3s;
box-shadow: var(--m-shadow);
">
<div style="font-size: 3rem; text-align: center; margin-bottom: 0.5rem;">${lot.emoji}</div>
<h3 style="font-size: 1.25rem; font-weight: 600; margin-bottom: 0.5rem; color: var(--m-text);">${lot.name}</h3>
<p style="color: var(--m-text-muted); font-size: 0.9rem; margin-bottom: 0.5rem;">๊ฐ๊ฒฉ: ${lot.price.toLocaleString()}์</p>
<p style="color: var(--m-text-muted); font-size: 0.9rem; margin-bottom: 0.5rem;">1๋ฑ: ${lot.jackpot}</p>
<p style="color: var(--m-text-muted); font-size: 0.85rem;">ํ๋ฅ : 1/${lot.odds.toLocaleString()}</p>
</div>
`).join('');
// ์นด๋ ํด๋ฆญ ์ด๋ฒคํธ
document.querySelectorAll('.lottery-card').forEach(card => {
card.addEventListener('click', () => {
selectedLottery = card.dataset.id;
document.querySelectorAll('.lottery-card').forEach(c => c.style.borderColor = 'transparent');
const lot = lotteries.find(l => l.id === selectedLottery);
card.style.borderColor = lot.color;
card.style.boxShadow = `0 0 20px ${lot.color}80`;
});
});
}
renderCards();
```
**์์ ์ถ๋ ฅ:**
ํ์ด์ง์ 3๊ฐ์ ๋ณต๊ถ ์นด๋(๋ก๋, ์ฐ๊ธ๋ณต๊ถ, ์คํฌ๋์น)๊ฐ ๊ทธ๋ฆฌ๋๋ก ํ์๋๊ณ , ํด๋ฆญ ์ ์ ํ๋ ์นด๋์ ์์ ํ
๋๋ฆฌ glow ํจ๊ณผ๊ฐ ๋ํ๋ฉ๋๋ค.
๊ธฐ๋ ๊ฒฐ๊ณผ: ๋ณต๊ถ ์ ํ ์น์ ์ด ์ถ๊ฐ๋๊ณ , ๋ก๋/์ฐ๊ธ๋ณต๊ถ/์คํฌ๋์น 3์ข ์ ์นด๋๊ฐ ๊ทธ๋ฆฌ๋๋ก ํ์๋ฉ๋๋ค. ์นด๋ ํด๋ฆญ ์ ์ ํ๋ ์นด๋์ ์์ ํ ๋๋ฆฌ์ ๊ทธ๋ฆผ์ ํจ๊ณผ๊ฐ ์ ์ฉ๋ฉ๋๋ค.
์๋ฎฌ๋ ์ด์
์คํ ๋ฒํผ๊ณผ ๊ฒฐ๊ณผ ํ์ ์์ญ์ ์ถ๊ฐํฉ๋๋ค.
**์์
๋ด์ฉ:**
1. ๋ณต๊ถ ์ ํ ์น์
์๋์ ๊ตฌ๋งค ๋ฒํผ ์น์
์ ์ถ๊ฐํฉ๋๋ค:
```html
<section style="margin-bottom: 2rem;">
<h2 style="font-size: 1.5rem; font-weight: 600; margin-bottom: 1rem; color: var(--m-text);">์๋ฎฌ๋ ์ด์
์คํ</h2>
<div style="display: flex; gap: 0.5rem; flex-wrap: wrap;">
<button onclick="buySim(1)" style="padding: 12px 24px; background: var(--m-primary); color: white; border: none; border-radius: var(--m-radius-lg); cursor: pointer; font-weight: 600;">1ํ ๊ตฌ๋งค</button>
<button onclick="buySim(10)" style="padding: 12px 24px; background: var(--m-primary); color: white; border: none; border-radius: var(--m-radius-lg); cursor: pointer; font-weight: 600;">10ํ ๊ตฌ๋งค</button>
<button onclick="buySim(100)" style="padding: 12px 24px; background: var(--m-primary); color: white; border: none; border-radius: var(--m-radius-lg); cursor: pointer; font-weight: 600;">100ํ ๊ตฌ๋งค</button>
<button onclick="buySim(1000)" style="padding: 12px 24px; background: var(--m-primary); color: white; border: none; border-radius: var(--m-radius-lg); cursor: pointer; font-weight: 600;">1000ํ ๊ตฌ๋งค</button>
</div>
</section>
<section style="margin-bottom: 2rem;">
<h2 style="font-size: 1.5rem; font-weight: 600; margin-bottom: 1rem; color: var(--m-text);">๊ฒฐ๊ณผ</h2>
<div id="resultArea" style="background: var(--m-surface); padding: 2rem; border-radius: var(--m-radius-lg); box-shadow: var(--m-shadow); min-height: 150px; text-align: center; color: var(--m-text-muted);">
๋ณต๊ถ์ ์ ํํ๊ณ ๊ตฌ๋งค ๋ฒํผ์ ๋๋ฌ์ฃผ์ธ์.
</div>
</section>
```
2. `<script>` ๋ธ๋ก์ ์๋ฎฌ๋ ์ด์
๋ก์ง์ ์ถ๊ฐํฉ๋๋ค:
```javascript
let stats = {
totalBuys: 0,
totalSpent: 0,
wins: 0,
totalWinnings: 0,
history: []
};
function buySim(count) {
if (!selectedLottery) {
alert('๋ณต๊ถ ์ข
๋ฅ๋ฅผ ๋จผ์ ์ ํํด์ฃผ์ธ์!');
return;
}
const lot = lotteries.find(l => l.id === selectedLottery);
const resultArea = document.getElementById('resultArea');
resultArea.innerHTML = '<div style="font-size: 3rem;">๐ฐ</div><p>์ถ์ฒจ ์ค...</p>';
setTimeout(() => {
let winCount = 0;
let winnings = 0;
for (let i = 0; i < count; i++) {
const rand = Math.random();
if (rand < 1 / lot.odds) {
winCount++;
// ๊ฐ๋จํ 1๋ฑ๋ง ์ฒ๋ฆฌ (์ค์ ๋ก๋ 2๋ฑ/3๋ฑ ํ๋ฅ ๋ ์ถ๊ฐ ๊ฐ๋ฅ)
const prize = lot.id === 'lotto' ? 2000000000 : lot.id === 'pension' ? 168000000 : 100000000;
winnings += prize;
}
}
stats.totalBuys += count;
stats.totalSpent += lot.price * count;
stats.wins += winCount;
stats.totalWinnings += winnings;
const profit = stats.totalWinnings - stats.totalSpent;
const message = winCount > 0
? `<div style="font-size: 3rem;">๐</div><h3 style="color: #f59e0b; font-size: 1.5rem; margin: 1rem 0;">์ถํํฉ๋๋ค! ${winCount}ํ ๋น์ฒจ!</h3><p style="font-size: 1.25rem; font-weight: 600;">๋น์ฒจ๊ธ: ${winnings.toLocaleString()}์</p>`
: `<div style="font-size: 3rem;">๐ข</div><p style="font-size: 1.25rem;">์์ฝ๊ฒ๋ ${count}ํ ๋ชจ๋ ๋์ฒจ์
๋๋ค.</p><button onclick="buySim(1)" style="margin-top: 1rem; padding: 8px 16px; background: var(--m-primary); color: white; border: none; border-radius: var(--m-radius-lg); cursor: pointer;">๋ค์ ๋์ !</button>`;
resultArea.innerHTML = message + `<p style="margin-top: 1rem; color: var(--m-text-muted); font-size: 0.9rem;">์์์ต: ${profit >= 0 ? '+' : ''}${profit.toLocaleString()}์</p>`;
// ํ์คํ ๋ฆฌ ์ถ๊ฐ (์ต๊ทผ 5๊ฐ๋ง)
stats.history.unshift({ count, winCount, winnings, profit });
if (stats.history.length > 5) stats.history.pop();
updateStats();
}, 1000);
}
function updateStats() {
// ๋ค์ ๋จ๊ณ์์ ๊ตฌํ
}
```
**์์ ์ถ๋ ฅ:**
๊ตฌ๋งค ๋ฒํผ ํด๋ฆญ ์ 1์ด ํ ๊ฒฐ๊ณผ๊ฐ ํ์๋ฉ๋๋ค. ๋น์ฒจ ์ ์ถํ ๋ฉ์์ง์ ๋น์ฒจ๊ธ, ๋์ฒจ ์ ์๋ก ๋ฉ์์ง์ ๋ค์ ๋์ ๋ฒํผ์ด ๋ํ๋ฉ๋๋ค.
๊ธฐ๋ ๊ฒฐ๊ณผ: ์๋ฎฌ๋ ์ด์ ์คํ ๋ฒํผ(1ํ/10ํ/100ํ/1000ํ)๊ณผ ๊ฒฐ๊ณผ ํ์ ์์ญ์ด ์ถ๊ฐ๋ฉ๋๋ค. ๋ฒํผ ํด๋ฆญ ์ ์ ํ๋ ๋ณต๊ถ์ ํ๋ฅ ์ ๋ฐ๋ผ ๋น์ฒจ/๋์ฒจ ๊ฒฐ๊ณผ๊ฐ ์ ๋๋ฉ์ด์ ๊ณผ ํจ๊ป ํ์๋ฉ๋๋ค.
๋์ ํต๊ณ ๋์๋ณด๋๋ฅผ ์ถ๊ฐํ๊ณ ๋ฆฌ์
๊ธฐ๋ฅ์ ๊ตฌํํฉ๋๋ค.
**์์
๋ด์ฉ:**
1. ๊ฒฐ๊ณผ ์น์
์๋์ ํต๊ณ ์น์
์ ์ถ๊ฐํฉ๋๋ค:
```html
<section style="margin-bottom: 2rem;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
<h2 style="font-size: 1.5rem; font-weight: 600; color: var(--m-text);">๋์ ํต๊ณ</h2>
<button onclick="resetStats()" style="padding: 8px 16px; background: #ef4444; color: white; border: none; border-radius: var(--m-radius-lg); cursor: pointer; font-size: 0.9rem;">๋ฆฌ์
</button>
</div>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem;">
<div style="background: var(--m-surface); padding: 1.5rem; border-radius: var(--m-radius-lg); box-shadow: var(--m-shadow); text-align: center;">
<p style="color: var(--m-text-muted); font-size: 0.9rem; margin-bottom: 0.5rem;">์ด ๊ตฌ๋งค ํ์</p>
<p id="statBuys" style="font-size: 2rem; font-weight: 700; color: var(--m-text);">0</p>
</div>
<div style="background: var(--m-surface); padding: 1.5rem; border-radius: var(--m-radius-lg); box-shadow: var(--m-shadow); text-align: center;">
<p style="color: var(--m-text-muted); font-size: 0.9rem; margin-bottom: 0.5rem;">์ด ์ง์ถ</p>
<p id="statSpent" style="font-size: 2rem; font-weight: 700; color: var(--m-text);">0์</p>
</div>
<div style="background: var(--m-surface); padding: 1.5rem; border-radius: var(--m-radius-lg); box-shadow: var(--m-shadow); text-align: center;">
<p style="color: var(--m-text-muted); font-size: 0.9rem; margin-bottom: 0.5rem;">๋น์ฒจ ํ์</p>
<p id="statWins" style="font-size: 2rem; font-weight: 700; color: #10b981;">0</p>
</div>
<div style="background: var(--m-surface); padding: 1.5rem; border-radius: var(--m-radius-lg); box-shadow: var(--m-shadow); text-align: center;">
<p style="color: var(--m-text-muted); font-size: 0.9rem; margin-bottom: 0.5rem;">์ด ๋น์ฒจ๊ธ</p>
<p id="statWinnings" style="font-size: 2rem; font-weight: 700; color: #f59e0b;">0์</p>
</div>
<div style="background: var(--m-surface); padding: 1.5rem; border-radius: var(--m-radius-lg); box-shadow: var(--m-shadow); text-align: center; grid-column: span 2;">
<p style="color: var(--m-text-muted); font-size: 0.9rem; margin-bottom: 0.5rem;">์์์ต</p>
<p id="statProfit" style="font-size: 2rem; font-weight: 700;">0์</p>
</div>
</div>
</section>
<section>
<h2 style="font-size: 1.5rem; font-weight: 600; margin-bottom: 1rem; color: var(--m-text);">์ต๊ทผ ๊ธฐ๋ก</h2>
<div id="historyArea" style="background: var(--m-surface); padding: 1.5rem; border-radius: var(--m-radius-lg); box-shadow: var(--m-shadow); color: var(--m-text-muted);">
์์ง ๊ธฐ๋ก์ด ์์ต๋๋ค.
</div>
</section>
```
2. `<script>` ๋ธ๋ก์ ํต๊ณ ์
๋ฐ์ดํธ ๋ฐ ๋ฆฌ์
ํจ์๋ฅผ ๊ตฌํํฉ๋๋ค:
```javascript
function updateStats() {
document.getElementById('statBuys').textContent = stats.totalBuys.toLocaleString();
document.getElementById('statSpent').textContent = stats.totalSpent.toLocaleString() + '์';
document.getElementById('statWins').textContent = stats.wins.toLocaleString();
document.getElementById('statWinnings').textContent = stats.totalWinnings.toLocaleString() + '์';
const profit = stats.totalWinnings - stats.totalSpent;
const profitEl = document.getElementById('statProfit');
profitEl.textContent = (profit >= 0 ? '+' : '') + profit.toLocaleString() + '์';
profitEl.style.color = profit >= 0 ? '#10b981' : '#ef4444';
// ํ์คํ ๋ฆฌ ๋ ๋๋ง
const historyArea = document.getElementById('historyArea');
if (stats.history.length === 0) {
historyArea.innerHTML = '<p style="color: var(--m-text-muted);">์์ง ๊ธฐ๋ก์ด ์์ต๋๋ค.</p>';
} else {
historyArea.innerHTML = stats.history.map((h, i) => `
<div style="padding: 12px; background: ${i % 2 === 0 ? 'var(--m-surface)' : 'transparent'}; border-radius: 8px; margin-bottom: 8px; display: flex; justify-content: space-between; align-items: center;">
<span style="color: var(--m-text);">${h.count}ํ ๊ตฌ๋งค</span>
<span style="color: ${h.winCount > 0 ? '#10b981' : '#ef4444'}; font-weight: 600;">${h.winCount > 0 ? '๋น์ฒจ ' + h.winCount + 'ํ' : '๋์ฒจ'}</span>
<span style="color: var(--m-text-muted);">${(h.profit >= 0 ? '+' : '') + h.profit.toLocaleString()}์</span>
</div>
`).join('');
}
// LocalStorage ์ ์ฅ
localStorage.setItem('lotteryStats', JSON.stringify(stats));
}
function resetStats() {
if (!confirm('ํต๊ณ๋ฅผ ์ด๊ธฐํํ์๊ฒ ์ต๋๊น?')) return;
stats = { totalBuys: 0, totalSpent: 0, wins: 0, totalWinnings: 0, history: [] };
updateStats();
document.getElementById('resultArea').innerHTML = '<p style="color: var(--m-text-muted);">๋ณต๊ถ์ ์ ํํ๊ณ ๊ตฌ๋งค ๋ฒํผ์ ๋๋ฌ์ฃผ์ธ์.</p>';
}
// ํ์ด์ง ๋ก๋ ์ ์ ์ฅ๋ ํต๊ณ ๋ณต์
window.addEventListener('DOMContentLoaded', () => {
const saved = localStorage.getItem('lotteryStats');
if (saved) {
stats = JSON.parse(saved);
updateStats();
}
});
```
**์์ ์ถ๋ ฅ:**
๋์ ํต๊ณ ์นด๋(์ด ๊ตฌ๋งค ํ์, ์ง์ถ, ๋น์ฒจ ํ์, ๋น์ฒจ๊ธ, ์์์ต)์ ์ต๊ทผ 5ํ ๊ธฐ๋ก์ด ํ์๋ฉ๋๋ค. ๋ฆฌ์
๋ฒํผ ํด๋ฆญ ์ ๋ชจ๋ ํต๊ณ๊ฐ ์ด๊ธฐํ๋ฉ๋๋ค. LocalStorage์ ์ ์ฅ๋์ด ์๋ก๊ณ ์นจ ํ์๋ ํต๊ณ๊ฐ ์ ์ง๋ฉ๋๋ค.
๊ธฐ๋ ๊ฒฐ๊ณผ: ๋์ ํต๊ณ ๋์๋ณด๋(์ด ๊ตฌ๋งค ํ์/์ง์ถ/๋น์ฒจ ํ์/๋น์ฒจ๊ธ/์์์ต)์ ์ต๊ทผ 5ํ ๊ธฐ๋ก ์์ญ์ด ์ถ๊ฐ๋ฉ๋๋ค. ๋ฆฌ์ ๋ฒํผ์ผ๋ก ํต๊ณ ์ด๊ธฐํ๊ฐ ๊ฐ๋ฅํ๊ณ , LocalStorage์ ์ ์ฅ๋์ด ์๋ก๊ณ ์นจ ํ์๋ ํต๊ณ๊ฐ ์ ์ง๋ฉ๋๋ค. ํต๊ณ ์ซ์๊ฐ ๊ตฌ๋งค ์๋ง๋ค ์ค์๊ฐ ์ ๋ฐ์ดํธ๋ฉ๋๋ค.
์ ์ถ๋ ์ํ (0)
๋ก๊ทธ์ธ ํ ์ ์ถ์์ง ์ ์ถ๋ ์ํ์ด ์์ต๋๋ค. ์ฒซ ๋ฒ์งธ ๋์ ์๊ฐ ๋์ด๋ณด์ธ์!