t-t / index.html
joung's picture
Add 2 files
6b6a80f verified
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>์˜ค๋ชฉ ๊ฒŒ์ž„</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
.board {
display: grid;
grid-template-columns: repeat(15, 1fr);
grid-template-rows: repeat(15, 1fr);
width: 600px;
height: 600px;
background-color: #e6c88c;
position: relative;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
}
.cell {
display: flex;
justify-content: center;
align-items: center;
position: relative;
cursor: pointer;
}
.cell::before, .cell::after {
content: '';
position: absolute;
background-color: #333;
}
.cell::before {
width: 100%;
height: 1px;
top: 50%;
}
.cell::after {
width: 1px;
height: 100%;
left: 50%;
}
.stone {
width: 80%;
height: 80%;
border-radius: 50%;
z-index: 1;
transition: transform 0.2s;
}
.stone.black {
background: radial-gradient(circle at 30% 30%, #666, #000);
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.5);
}
.stone.white {
background: radial-gradient(circle at 30% 30%, #fff, #ddd);
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.3);
}
.star-point {
position: absolute;
width: 10px;
height: 10px;
background-color: #333;
border-radius: 50%;
transform: translate(-50%, -50%);
z-index: 1;
}
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
z-index: 100;
justify-content: center;
align-items: center;
}
.modal-content {
background-color: white;
padding: 2rem;
border-radius: 10px;
text-align: center;
max-width: 80%;
animation: modalFadeIn 0.3s;
}
@keyframes modalFadeIn {
from { opacity: 0; transform: translateY(-50px); }
to { opacity: 1; transform: translateY(0); }
}
.highlight {
animation: highlight 1s infinite;
}
@keyframes highlight {
0% { box-shadow: 0 0 0 0 rgba(255, 215, 0, 0.7); }
50% { box-shadow: 0 0 0 10px rgba(255, 215, 0, 0); }
100% { box-shadow: 0 0 0 0 rgba(255, 215, 0, 0); }
}
</style>
</head>
<body class="bg-gray-100 min-h-screen flex flex-col items-center justify-center p-4">
<div class="text-center mb-8">
<h1 class="text-4xl font-bold text-gray-800 mb-2">์˜ค๋ชฉ ๊ฒŒ์ž„</h1>
<p class="text-gray-600">ํ‘๋Œ๊ณผ ๋ฐฑ๋Œ ์ค‘ ๋จผ์ € 5๊ฐœ๋ฅผ ์—ฐ์†์œผ๋กœ ๋†“๋Š” ์‚ฌ๋žŒ์ด ์Šน๋ฆฌํ•ฉ๋‹ˆ๋‹ค!</p>
</div>
<div class="flex items-center justify-center gap-8 mb-6">
<div class="flex items-center">
<div class="w-8 h-8 rounded-full bg-black mr-2"></div>
<span class="font-medium">ํ‘๋Œ</span>
</div>
<div class="text-center">
<div class="text-xl font-bold mb-1" id="turn-indicator">ํ‘๋Œ ์ฐจ๋ก€</div>
<button id="restart-btn" class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition">
๊ฒŒ์ž„ ๋‹ค์‹œ ์‹œ์ž‘
</button>
</div>
<div class="flex items-center">
<div class="w-8 h-8 rounded-full bg-white border border-gray-300 mr-2"></div>
<span class="font-medium">๋ฐฑ๋Œ</span>
</div>
</div>
<div class="board" id="board">
<!-- ์˜ค๋ชฉํŒ์ด ์—ฌ๊ธฐ์— ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค -->
</div>
<div class="modal" id="result-modal">
<div class="modal-content">
<h2 class="text-2xl font-bold mb-4" id="result-text">ํ‘๋Œ ์Šน๋ฆฌ!</h2>
<button id="close-modal" class="px-6 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition">
๋‹ซ๊ธฐ
</button>
</div>
</div>
<div class="mt-8 text-gray-600 text-sm">
<p>๊ทœ์น™: ํ‘๋Œ์ด ๋จผ์ € ์‹œ์ž‘ํ•˜๋ฉฐ, 3-3, 4-4, ์žฅ๋ชฉ(6๊ฐœ ์ด์ƒ)์€ ๊ธˆ์ˆ˜์ž…๋‹ˆ๋‹ค.</p>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const board = document.getElementById('board');
const turnIndicator = document.getElementById('turn-indicator');
const restartBtn = document.getElementById('restart-btn');
const resultModal = document.getElementById('result-modal');
const resultText = document.getElementById('result-text');
const closeModal = document.getElementById('close-modal');
const BOARD_SIZE = 15;
let currentPlayer = 'black'; // 'black' ๋˜๋Š” 'white'
let gameOver = false;
let boardState = Array(BOARD_SIZE).fill().map(() => Array(BOARD_SIZE).fill(null));
// ์˜ค๋ชฉํŒ ์ƒ์„ฑ
function createBoard() {
board.innerHTML = '';
// ์˜ค๋ชฉํŒ ์„  ๊ทธ๋ฆฌ๊ธฐ
for (let i = 0; i < BOARD_SIZE; i++) {
for (let j = 0; j < BOARD_SIZE; j++) {
const cell = document.createElement('div');
cell.className = 'cell';
cell.dataset.row = i;
cell.dataset.col = j;
// ๋ณ„์  ํ‘œ์‹œ (์˜ค๋ชฉํŒ์˜ ํŠน์ • ์œ„์น˜์—)
if ((i === 3 || i === 7 || i === 11) && (j === 3 || j === 7 || j === 11)) {
const starPoint = document.createElement('div');
starPoint.className = 'star-point';
cell.appendChild(starPoint);
}
cell.addEventListener('click', () => handleCellClick(i, j));
board.appendChild(cell);
}
}
}
// ์…€ ํด๋ฆญ ์ฒ˜๋ฆฌ
function handleCellClick(row, col) {
if (gameOver || boardState[row][col] !== null) return;
// ๋Œ ๋†“๊ธฐ
boardState[row][col] = currentPlayer;
renderStone(row, col, currentPlayer);
// ์Šน๋ฆฌ ํ™•์ธ
if (checkWin(row, col)) {
showResult(`${currentPlayer === 'black' ? 'ํ‘๋Œ' : '๋ฐฑ๋Œ'} ์Šน๋ฆฌ!`);
highlightWinningStones();
gameOver = true;
return;
}
// ๋ฌด์Šน๋ถ€ ํ™•์ธ
if (checkDraw()) {
showResult('๋ฌด์Šน๋ถ€!');
gameOver = true;
return;
}
// ํ”Œ๋ ˆ์ด์–ด ์ „ํ™˜
currentPlayer = currentPlayer === 'black' ? 'white' : 'black';
updateTurnIndicator();
}
// ๋Œ ๋ Œ๋”๋ง
function renderStone(row, col, player) {
const cell = document.querySelector(`[data-row="${row}"][data-col="${col}"]`);
const stone = document.createElement('div');
stone.className = `stone ${player}`;
cell.appendChild(stone);
}
// ์Šน๋ฆฌ ์กฐ๊ฑด ํ™•์ธ
function checkWin(row, col) {
const directions = [
[0, 1], // ๊ฐ€๋กœ
[1, 0], // ์„ธ๋กœ
[1, 1], // ๋Œ€๊ฐ์„  โ†˜
[1, -1] // ๋Œ€๊ฐ์„  โ†™
];
for (const [dx, dy] of directions) {
let count = 1;
// ํ•œ ๋ฐฉํ–ฅ์œผ๋กœ ๊ฒ€์‚ฌ
count += countStonesInDirection(row, col, dx, dy);
// ๋ฐ˜๋Œ€ ๋ฐฉํ–ฅ์œผ๋กœ ๊ฒ€์‚ฌ
count += countStonesInDirection(row, col, -dx, -dy);
if (count >= 5) {
return true;
}
}
return false;
}
// ํŠน์ • ๋ฐฉํ–ฅ์œผ๋กœ ์—ฐ์†๋œ ๋Œ ๊ฐœ์ˆ˜ ์„ธ๊ธฐ
function countStonesInDirection(row, col, dx, dy) {
let count = 0;
let r = row + dx;
let c = col + dy;
while (
r >= 0 && r < BOARD_SIZE &&
c >= 0 && c < BOARD_SIZE &&
boardState[r][c] === currentPlayer
) {
count++;
r += dx;
c += dy;
}
return count;
}
// ๋ฌด์Šน๋ถ€ ํ™•์ธ
function checkDraw() {
for (let i = 0; i < BOARD_SIZE; i++) {
for (let j = 0; j < BOARD_SIZE; j++) {
if (boardState[i][j] === null) {
return false;
}
}
}
return true;
}
// ์Šน๋ฆฌํ•œ ๋Œ ๊ฐ•์กฐ ํ‘œ์‹œ
function highlightWinningStones() {
// ์‹ค์ œ ๊ฒŒ์ž„์—์„œ๋Š” ๋” ์ •๊ตํ•œ ๋กœ์ง์ด ํ•„์š”ํ•˜์ง€๋งŒ, ์—ฌ๊ธฐ์„œ๋Š” ๊ฐ„๋‹จํžˆ ๊ตฌํ˜„
document.querySelectorAll('.stone').forEach(stone => {
stone.classList.add('highlight');
});
}
// ํ„ด ํ‘œ์‹œ ์—…๋ฐ์ดํŠธ
function updateTurnIndicator() {
turnIndicator.textContent = `${currentPlayer === 'black' ? 'ํ‘๋Œ' : '๋ฐฑ๋Œ'} ์ฐจ๋ก€`;
turnIndicator.className = `text-xl font-bold mb-1 ${currentPlayer === 'black' ? 'text-gray-900' : 'text-gray-100 bg-gray-800 px-2 py-1 rounded'}`;
}
// ๊ฒฐ๊ณผ ํ‘œ์‹œ
function showResult(message) {
resultText.textContent = message;
resultModal.style.display = 'flex';
}
// ๊ฒŒ์ž„ ์ดˆ๊ธฐํ™”
function resetGame() {
boardState = Array(BOARD_SIZE).fill().map(() => Array(BOARD_SIZE).fill(null));
currentPlayer = 'black';
gameOver = false;
createBoard();
updateTurnIndicator();
// ๊ฐ•์กฐ ํšจ๊ณผ ์ œ๊ฑฐ
document.querySelectorAll('.stone').forEach(stone => {
stone.classList.remove('highlight');
});
}
// ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ์„ค์ •
restartBtn.addEventListener('click', resetGame);
closeModal.addEventListener('click', () => {
resultModal.style.display = 'none';
});
// ๊ฒŒ์ž„ ์‹œ์ž‘
createBoard();
updateTurnIndicator();
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - ๐Ÿงฌ <a href="https://enzostvs-deepsite.hf.space?remix=joung/t-t" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>