Download index.html from Daddy-one/a: direct link, hf CLI and curl.
- Browser
- Download file 20 kB
-
https://huggingface.co/spaces/Daddy-one/a/resolve/main/index.html
- Command line
-
hf download hf://spaces/Daddy-one/a/index.html
-
curl -L -o index.html https://huggingface.co/spaces/Daddy-one/a/resolve/main/index.html
20 kB
| <html lang="zh-CN"> | |
| <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> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| .board { | |
| background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30"><line x1="15" y1="0" x2="15" y2="30" stroke="%23a78bfa" stroke-width="1"/><line x1="0" y1="15" x2="30" y2="15" stroke="%23a78bfa" stroke-width="1"/></svg>'); | |
| background-size: 30px 30px; | |
| position: relative; | |
| } | |
| .piece { | |
| position: absolute; | |
| width: 26px; | |
| height: 26px; | |
| border-radius: 50%; | |
| transform: translate(-50%, -50%); | |
| box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); | |
| transition: all 0.3s ease; | |
| } | |
| .piece.black { | |
| background: radial-gradient(circle at 30% 30%, #555, #000); | |
| } | |
| .piece.white { | |
| background: radial-gradient(circle at 30% 30%, #fff, #ddd); | |
| } | |
| .piece.last-move { | |
| box-shadow: 0 0 0 3px rgba(255, 215, 0, 0.7); | |
| } | |
| .win-line { | |
| position: absolute; | |
| background-color: rgba(255, 0, 0, 0.7); | |
| transform-origin: 0 0; | |
| z-index: 10; | |
| } | |
| @keyframes pulse { | |
| 0% { transform: scale(1); } | |
| 50% { transform: scale(1.1); } | |
| 100% { transform: scale(1); } | |
| } | |
| .current-player { | |
| animation: pulse 1.5s infinite; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-100 min-h-screen flex flex-col items-center justify-center p-4"> | |
| <div class="max-w-4xl w-full bg-white rounded-xl shadow-xl overflow-hidden"> | |
| <div class="bg-purple-600 text-white p-4"> | |
| <h1 class="text-2xl font-bold text-center">五子棋双人游戏</h1> | |
| </div> | |
| <div class="p-6 flex flex-col md:flex-row gap-6"> | |
| <div class="flex-1"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <div id="black-player" class="flex items-center gap-2 p-3 rounded-lg bg-gray-100"> | |
| <div class="w-8 h-8 rounded-full bg-gradient-to-br from-gray-500 to-black shadow"></div> | |
| <span class="font-medium">黑方</span> | |
| </div> | |
| <div id="white-player" class="flex items-center gap-2 p-3 rounded-lg bg-gray-100"> | |
| <div class="w-8 h-8 rounded-full bg-gradient-to-br from-white to-gray-300 shadow"></div> | |
| <span class="font-medium">白方</span> | |
| </div> | |
| </div> | |
| <div class="relative mx-auto"> | |
| <div id="board" class="board w-full max-w-lg h-auto border-2 border-purple-400 bg-amber-50"></div> | |
| </div> | |
| <div class="mt-4 text-center"> | |
| <p id="status" class="text-lg font-semibold text-purple-700">游戏开始,黑方先行</p> | |
| </div> | |
| </div> | |
| <div class="md:w-64 flex flex-col gap-4"> | |
| <div class="bg-gray-50 p-4 rounded-lg shadow-inner"> | |
| <h3 class="font-bold text-purple-700 border-b pb-2 mb-2">游戏规则</h3> | |
| <ul class="text-sm space-y-2 text-gray-700"> | |
| <li class="flex items-start gap-2"> | |
| <i class="fas fa-circle text-xs mt-1 text-purple-500"></i> | |
| <span>黑方先手,白方后手</span> | |
| </li> | |
| <li class="flex items-start gap-2"> | |
| <i class="fas fa-circle text-xs mt-1 text-purple-500"></i> | |
| <span>横、竖、斜连成五子获胜</span> | |
| </li> | |
| <li class="flex items-start gap-2"> | |
| <i class="fas fa-circle text-xs mt-1 text-purple-500"></i> | |
| <span>棋盘大小:15×15</span> | |
| </li> | |
| </ul> | |
| </div> | |
| <div class="bg-gray-50 p-4 rounded-lg shadow-inner"> | |
| <h3 class="font-bold text-purple-700 border-b pb-2 mb-2">游戏控制</h3> | |
| <div class="flex flex-col gap-2"> | |
| <button id="restart-btn" class="bg-purple-600 hover:bg-purple-700 text-white py-2 px-4 rounded-lg transition flex items-center justify-center gap-2"> | |
| <i class="fas fa-redo"></i> | |
| <span>重新开始</span> | |
| </button> | |
| <button id="undo-btn" class="bg-gray-200 hover:bg-gray-300 text-gray-800 py-2 px-4 rounded-lg transition flex items-center justify-center gap-2"> | |
| <i class="fas fa-undo"></i> | |
| <span>悔棋</span> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="bg-gray-50 p-4 rounded-lg shadow-inner"> | |
| <h3 class="font-bold text-purple-700 border-b pb-2 mb-2">游戏记录</h3> | |
| <div id="move-history" class="text-sm space-y-1 max-h-40 overflow-y-auto"> | |
| <!-- 走棋记录将在这里显示 --> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- 胜利弹窗 --> | |
| <div id="win-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50"> | |
| <div class="bg-white rounded-xl p-6 max-w-sm w-full mx-4 shadow-2xl"> | |
| <div class="text-center"> | |
| <div id="win-icon" class="text-6xl mb-4"> | |
| <i class="fas fa-trophy text-yellow-500"></i> | |
| </div> | |
| <h2 id="win-message" class="text-2xl font-bold mb-2">黑方获胜!</h2> | |
| <p class="text-gray-600 mb-6">五子连珠,精彩对局!</p> | |
| <button id="close-win-modal" class="bg-purple-600 hover:bg-purple-700 text-white py-2 px-6 rounded-lg transition"> | |
| 再来一局 | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // 游戏常量 | |
| const BOARD_SIZE = 15; | |
| const CELL_SIZE = 30; | |
| const PIECE_RADIUS = 13; | |
| // 游戏状态 | |
| let board = Array(BOARD_SIZE).fill().map(() => Array(BOARD_SIZE).fill(null)); | |
| let currentPlayer = 'black'; | |
| let gameOver = false; | |
| let moveHistory = []; | |
| let lastMove = null; | |
| // DOM 元素 | |
| const boardElement = document.getElementById('board'); | |
| const statusElement = document.getElementById('status'); | |
| const blackPlayerElement = document.getElementById('black-player'); | |
| const whitePlayerElement = document.getElementById('white-player'); | |
| const restartBtn = document.getElementById('restart-btn'); | |
| const undoBtn = document.getElementById('undo-btn'); | |
| const moveHistoryElement = document.getElementById('move-history'); | |
| const winModal = document.getElementById('win-modal'); | |
| const winMessage = document.getElementById('win-message'); | |
| const closeWinModal = document.getElementById('close-win-modal'); | |
| // 初始化棋盘 | |
| function initBoard() { | |
| boardElement.innerHTML = ''; | |
| boardElement.style.width = `${BOARD_SIZE * CELL_SIZE}px`; | |
| boardElement.style.height = `${BOARD_SIZE * CELL_SIZE}px`; | |
| // 添加星位标记 | |
| const starPoints = [ | |
| [3, 3], [3, 11], [7, 7], [11, 3], [11, 11] | |
| ]; | |
| starPoints.forEach(([x, y]) => { | |
| const star = document.createElement('div'); | |
| star.className = 'absolute w-2 h-2 bg-black rounded-full'; | |
| star.style.left = `${x * CELL_SIZE}px`; | |
| star.style.top = `${y * CELL_SIZE}px`; | |
| star.style.transform = 'translate(-50%, -50%)'; | |
| boardElement.appendChild(star); | |
| }); | |
| } | |
| // 重置游戏 | |
| function resetGame() { | |
| board = Array(BOARD_SIZE).fill().map(() => Array(BOARD_SIZE).fill(null)); | |
| currentPlayer = 'black'; | |
| gameOver = false; | |
| moveHistory = []; | |
| lastMove = null; | |
| initBoard(); | |
| updateStatus(); | |
| updatePlayerIndicators(); | |
| clearWinLine(); | |
| moveHistoryElement.innerHTML = ''; | |
| // 隐藏胜利弹窗 | |
| winModal.classList.add('hidden'); | |
| } | |
| // 更新状态显示 | |
| function updateStatus() { | |
| if (gameOver) { | |
| return; | |
| } | |
| statusElement.textContent = currentPlayer === 'black' | |
| ? '轮到黑方落子' | |
| : '轮到白方落子'; | |
| } | |
| // 更新玩家指示器 | |
| function updatePlayerIndicators() { | |
| if (currentPlayer === 'black') { | |
| blackPlayerElement.classList.add('current-player', 'ring-2', 'ring-purple-500'); | |
| whitePlayerElement.classList.remove('current-player', 'ring-2', 'ring-purple-500'); | |
| } else { | |
| whitePlayerElement.classList.add('current-player', 'ring-2', 'ring-purple-500'); | |
| blackPlayerElement.classList.remove('current-player', 'ring-2', 'ring-purple-500'); | |
| } | |
| } | |
| // 放置棋子 | |
| function placePiece(x, y) { | |
| if (gameOver || board[x][y] !== null) { | |
| return false; | |
| } | |
| // 记录走棋历史 | |
| moveHistory.push({ | |
| x, y, | |
| player: currentPlayer, | |
| board: JSON.parse(JSON.stringify(board)) | |
| }); | |
| // 更新棋盘状态 | |
| board[x][y] = currentPlayer; | |
| lastMove = { x, y }; | |
| // 创建棋子元素 | |
| const piece = document.createElement('div'); | |
| piece.className = `piece ${currentPlayer}`; | |
| piece.style.left = `${(x + 0.5) * CELL_SIZE}px`; | |
| piece.style.top = `${(y + 0.5) * CELL_SIZE}px`; | |
| // 如果是最后一步,添加高亮 | |
| piece.classList.add('last-move'); | |
| boardElement.appendChild(piece); | |
| // 添加到走棋记录 | |
| addToMoveHistory(x, y); | |
| // 检查胜利条件 | |
| if (checkWin(x, y)) { | |
| gameOver = true; | |
| showWin(currentPlayer); | |
| return true; | |
| } | |
| // 切换玩家 | |
| currentPlayer = currentPlayer === 'black' ? 'white' : 'black'; | |
| updateStatus(); | |
| updatePlayerIndicators(); | |
| return true; | |
| } | |
| // 检查胜利条件 | |
| function checkWin(x, y) { | |
| const directions = [ | |
| [1, 0], // 水平 | |
| [0, 1], // 垂直 | |
| [1, 1], // 对角线 | |
| [1, -1] // 反对角线 | |
| ]; | |
| for (const [dx, dy] of directions) { | |
| let count = 1; | |
| // 正向检查 | |
| for (let i = 1; i < 5; i++) { | |
| const nx = x + i * dx; | |
| const ny = y + i * dy; | |
| if (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE && board[nx][ny] === currentPlayer) { | |
| count++; | |
| } else { | |
| break; | |
| } | |
| } | |
| // 反向检查 | |
| for (let i = 1; i < 5; i++) { | |
| const nx = x - i * dx; | |
| const ny = y - i * dy; | |
| if (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE && board[nx][ny] === currentPlayer) { | |
| count++; | |
| } else { | |
| break; | |
| } | |
| } | |
| if (count >= 5) { | |
| drawWinLine(x, y, dx, dy); | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| // 绘制胜利线 | |
| function drawWinLine(x, y, dx, dy) { | |
| // 找到线的起点和终点 | |
| let startX = x, startY = y; | |
| let endX = x, endY = y; | |
| // 向一个方向延伸 | |
| for (let i = 1; i < 5; i++) { | |
| const nx = x + i * dx; | |
| const ny = y + i * dy; | |
| if (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE && board[nx][ny] === currentPlayer) { | |
| endX = nx; | |
| endY = ny; | |
| } else { | |
| break; | |
| } | |
| } | |
| // 向另一个方向延伸 | |
| for (let i = 1; i < 5; i++) { | |
| const nx = x - i * dx; | |
| const ny = y - i * dy; | |
| if (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE && board[nx][ny] === currentPlayer) { | |
| startX = nx; | |
| startY = ny; | |
| } else { | |
| break; | |
| } | |
| } | |
| // 创建线元素 | |
| const line = document.createElement('div'); | |
| line.className = 'win-line'; | |
| // 计算线的位置和角度 | |
| const startPixelX = (startX + 0.5) * CELL_SIZE; | |
| const startPixelY = (startY + 0.5) * CELL_SIZE; | |
| const endPixelX = (endX + 0.5) * CELL_SIZE; | |
| const endPixelY = (endY + 0.5) * CELL_SIZE; | |
| const length = Math.sqrt(Math.pow(endPixelX - startPixelX, 2) + Math.pow(endPixelY - startPixelY, 2)); | |
| const angle = Math.atan2(endPixelY - startPixelY, endPixelX - startPixelX); | |
| line.style.width = `${length}px`; | |
| line.style.height = '4px'; | |
| line.style.left = `${startPixelX}px`; | |
| line.style.top = `${startPixelY}px`; | |
| line.style.transform = `rotate(${angle}rad)`; | |
| boardElement.appendChild(line); | |
| } | |
| // 清除胜利线 | |
| function clearWinLine() { | |
| const lines = document.querySelectorAll('.win-line'); | |
| lines.forEach(line => line.remove()); | |
| } | |
| // 显示胜利弹窗 | |
| function showWin(winner) { | |
| winMessage.textContent = winner === 'black' ? '黑方获胜!' : '白方获胜!'; | |
| statusElement.textContent = winner === 'black' ? '游戏结束,黑方获胜!' : '游戏结束,白方获胜!'; | |
| winModal.classList.remove('hidden'); | |
| } | |
| // 添加到走棋记录 | |
| function addToMoveHistory(x, y) { | |
| const moveNumber = moveHistory.length; | |
| const moveItem = document.createElement('div'); | |
| moveItem.className = 'flex items-center justify-between py-1 px-2 hover:bg-gray-100 rounded'; | |
| const moveText = document.createElement('span'); | |
| moveText.className = 'text-gray-700'; | |
| moveText.textContent = `${moveNumber}. ${currentPlayer === 'black' ? '黑' : '白'} (${x+1}, ${y+1})`; | |
| moveItem.appendChild(moveText); | |
| moveHistoryElement.appendChild(moveItem); | |
| // 滚动到底部 | |
| moveHistoryElement.scrollTop = moveHistoryElement.scrollHeight; | |
| } | |
| // 悔棋 | |
| function undoMove() { | |
| if (gameOver || moveHistory.length === 0) { | |
| return; | |
| } | |
| const lastMove = moveHistory.pop(); | |
| board = lastMove.board; | |
| currentPlayer = lastMove.player; | |
| // 重新渲染棋盘 | |
| initBoard(); | |
| for (const move of moveHistory) { | |
| const piece = document.createElement('div'); | |
| piece.className = `piece ${move.player}`; | |
| piece.style.left = `${(move.x + 0.5) * CELL_SIZE}px`; | |
| piece.style.top = `${(move.y + 0.5) * CELL_SIZE}px`; | |
| boardElement.appendChild(piece); | |
| } | |
| // 更新状态 | |
| updateStatus(); | |
| updatePlayerIndicators(); | |
| clearWinLine(); | |
| // 更新走棋记录 | |
| moveHistoryElement.removeChild(moveHistoryElement.lastChild); | |
| } | |
| // 事件监听 | |
| boardElement.addEventListener('click', function(e) { | |
| const rect = boardElement.getBoundingClientRect(); | |
| const x = Math.floor((e.clientX - rect.left) / CELL_SIZE); | |
| const y = Math.floor((e.clientY - rect.top) / CELL_SIZE); | |
| if (x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE) { | |
| placePiece(x, y); | |
| } | |
| }); | |
| restartBtn.addEventListener('click', resetGame); | |
| undoBtn.addEventListener('click', undoMove); | |
| closeWinModal.addEventListener('click', resetGame); | |
| // 初始化游戏 | |
| resetGame(); | |
| }); | |
| </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=Daddy-one/a" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |