From c2a44ba7c75c3ab84fd4f64410c15f50d6f920c5 Mon Sep 17 00:00:00 2001 From: icezhb <860435387@qq.com> Date: Sun, 29 Dec 2024 17:44:22 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=A7=E7=BB=AD=E8=90=BD=E5=AD=90=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=EF=BC=9B=E6=96=B0=E5=A2=9E=E6=88=98=E7=BB=A9=EF=BC=9B?= =?UTF-8?q?=E4=BC=98=E5=8C=96UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.vue | 379 ++++++++++++++++++++---------- src/components/GameStatistics.vue | 235 ++++++++---------- 2 files changed, 360 insertions(+), 254 deletions(-) diff --git a/src/App.vue b/src/App.vue index 95161d6..29c3ced 100644 --- a/src/App.vue +++ b/src/App.vue @@ -76,25 +76,57 @@
@@ -197,6 +229,7 @@ export default { winningStreaks: { current: 0, max: 0, + maxLose: 0, player: 0, computer: 0, }, @@ -242,7 +275,15 @@ export default { }, handleClick(row, col) { - if (this.board[row][col].player !== 0) return + if ( + !this.gameStarted || + this.board[row][col].player !== 0 || + this.winner || + this.gameEnded || // 增加游戏结束的检查 + (this.gameMode === 'pve' && this.isComputerTurn) + ) { + return + } this.stopTimer() @@ -313,7 +354,6 @@ export default { handleTimeout(player) { this.stopTimer() - console.log('超时玩家:', player === 1 ? '黑方' : '白方') // 记录当前状态 const isPlayerTurn = @@ -457,7 +497,6 @@ export default { if (!this.isValidPosition(newRow, newCol)) break const nextCell = this.board[newRow][newCol] if (nextCell.player !== playerType) { - console.log('遇到非己方棋子:', newRow, newCol) break } pieces.push([newRow, newCol]) @@ -471,20 +510,16 @@ export default { if (!this.isValidPosition(newRow, newCol)) break const nextCell = this.board[newRow][newCol] if (nextCell.player !== playerType) { - console.log('遇到非己方棋子:', newRow, newCol) break } pieces.unshift([newRow, newCol]) count++ } - console.log('找到的棋子:', pieces) - // 严格检查是否形成五子连珠 const isWin = count === 5 && pieces.length === 5 if (isWin) { - console.log('确认五子连珠!玩家:', playerType, '位置:', pieces) this.playWinningAnimation() return { isWin: true, @@ -520,14 +555,12 @@ export default { // 检查相邻棋子的距离是否严格为1,且方向一致 if (curr[0] - prev[0] !== dx || curr[1] - prev[1] !== dy) { - console.log('棋子不连续或方向不一致:', curr, prev) return false } // 检查是否属于同一玩家 const currPiece = this.board[curr[0]][curr[1]] if (this.isPlayerPiece(currPiece) !== isHuman) { - console.log('棋子属于不同玩家:', curr) return false } } @@ -536,13 +569,11 @@ export default { // 验证获胜棋子 validateWinningPieces(pieces, player) { - console.log('验证获胜棋子:', pieces, '期望玩家:', player) const validation = pieces.map(([row, col]) => ({ position: [row, col], valid: this.isValidPosition(row, col), piece: this.board[row][col], })) - console.log('验证详情:', validation) return pieces.every(([row, col]) => { return this.isValidPosition(row, col) && this.board[row][col].player === player }) @@ -1200,6 +1231,10 @@ export default { if (this.currentPlayer === (this.isPlayerBlack ? 1 : 2)) { stats.computerWins++ stats.winningStreaks.current = Math.min(0, stats.winningStreaks.current) - 1 + stats.winningStreaks.maxLose = Math.max( + stats.winningStreaks.maxLose, + Math.abs(stats.winningStreaks.current), + ) } else { stats.playerWins++ stats.winningStreaks.current = Math.max(0, stats.winningStreaks.current) + 1 @@ -1214,8 +1249,8 @@ export default { } else { stats.computerWins++ stats.winningStreaks.current = Math.min(0, stats.winningStreaks.current) - 1 - stats.winningStreaks.computer = Math.max( - stats.winningStreaks.computer, + stats.winningStreaks.maxLose = Math.max( + stats.winningStreaks.maxLose, Math.abs(stats.winningStreaks.current), ) } @@ -1294,10 +1329,27 @@ export default { .modal-content { background: white; - padding: 40px; + padding: 30px; border-radius: 16px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); animation: modalFadeIn 0.3s ease-out; + max-height: 90vh; + overflow-y: auto; + width: 90%; + max-width: 600px; + position: relative; + border: 1px solid rgba(0, 0, 0, 0.1); +} + +.modal-content::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 4px; + background: linear-gradient(90deg, #4caf50, #45a049); + border-radius: 16px 16px 0 0; } .modal-content h2 { @@ -1655,105 +1707,146 @@ export default { z-index: 1000; } -.victory-modal .modal-content { +.modal-content { background: white; - padding: 40px; + padding: 30px; border-radius: 16px; - text-align: center; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); animation: modalFadeIn 0.3s ease-out; + max-height: 90vh; + overflow-y: auto; + width: 90%; + max-width: 600px; } -.victory-modal h2 { - font-size: 28px; - color: #2c3e50; +.victory-header { + text-align: center; margin-bottom: 20px; + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; + padding-top: 10px; +} + +.victory-emoji { + font-size: 48px; + animation: bounce 1s infinite; +} + +.victory-header h2 { + font-size: 24px; + color: #2c3e50; + margin: 0; + font-weight: 600; +} + +.victory-info { + display: flex; + flex-direction: column; +} + +.victory-result { + background: linear-gradient(145deg, #f8f9fa, #e9ecef); + padding: 15px; + border-radius: 12px; + text-align: center; + font-size: 16px; + color: #2c3e50; + font-weight: 500; + margin-bottom: 20px; + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.05); + border: 1px solid rgba(0, 0, 0, 0.05); +} + +.divider { + height: 1px; + background: linear-gradient(90deg, transparent, #e0e0e0, transparent); + margin: 15px 0; +} + +.victory-stats { + margin: 15px 0; +} + +.taunt-message { + margin: 15px 0; + padding: 12px; + background: linear-gradient(145deg, #e53935, #d32f2f); + color: white; + border-radius: 8px; + font-style: italic; + font-size: 16px; + font-weight: bold; + text-align: center; + box-shadow: 0 4px 12px rgba(229, 57, 53, 0.2); + animation: slideIn 0.3s ease-out; } .modal-buttons { display: flex; - gap: 20px; + gap: 15px; justify-content: center; - margin-top: 30px; + margin-top: 20px; + padding: 10px 0; + border-top: 1px solid rgba(0, 0, 0, 0.1); } .modal-button { - padding: 12px 24px; - font-size: 16px; + padding: 10px 20px; + font-size: 14px; border: none; border-radius: 8px; cursor: pointer; transition: all 0.3s ease; - background-color: #6c757d; color: white; -} - -.modal-button.primary { - background-color: #4caf50; -} - -.start-screen { - text-align: center; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - z-index: 10; - background: rgba(255, 255, 255, 0.95); - padding: 25px 40px; - border-radius: 12px; - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1); - backdrop-filter: blur(4px); - min-width: 240px; -} - -.start-button { - padding: 12px 36px; - font-size: 18px; - background: linear-gradient(145deg, #4caf50, #45a049); - color: white; - border: none; - border-radius: 8px; - cursor: pointer; - transition: all 0.3s ease; - margin-bottom: 12px; - box-shadow: 0 4px 12px rgba(76, 175, 80, 0.2); - width: 100%; -} - -.start-button:hover { - transform: translateY(-2px); - box-shadow: 0 6px 15px rgba(76, 175, 80, 0.3); -} - -.turn-info { - color: #2c3e50; - font-size: 15px; - margin-top: 5px; - opacity: 0.8; + min-width: 100px; + font-weight: 500; + text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1); } .modal-button.secondary { background-color: #6c757d; -} - -.modal-button.secondary:hover { - background-color: #5a6268; - transform: translateY(-2px); + box-shadow: 0 2px 8px rgba(108, 117, 125, 0.2); + background: linear-gradient(145deg, #6c757d, #5a6268); } .modal-button.primary { background-color: #4caf50; + box-shadow: 0 2px 8px rgba(76, 175, 80, 0.2); + background: linear-gradient(145deg, #4caf50, #45a049); } -.modal-button.primary:hover { - background-color: #45a049; - transform: translateY(-2px); +.modal-button.exit { + background: linear-gradient(145deg, #dc3545, #c82333); + box-shadow: 0 2px 8px rgba(220, 53, 69, 0.2); } .modal-button:hover { transform: translateY(-2px); - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); + box-shadow: 0 6px 15px rgba(0, 0, 0, 0.15); + filter: brightness(1.1); +} + +@keyframes bounce { + 0%, + 100% { + transform: translateY(0); + } + 50% { + transform: translateY(-5px); + } +} + +@keyframes slideIn { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } } .view-result { @@ -1780,32 +1873,72 @@ export default { box-shadow: 0 6px 15px rgba(76, 175, 80, 0.3); } -.taunt-message { - margin-top: 15px; - padding: 10px; - background: linear-gradient(145deg, #e53935, #d32f2f); - color: white; - border-radius: 8px; - font-style: italic; - animation: tauntPulse 2s infinite; - font-size: 18px; - font-weight: bold; - text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); - box-shadow: 0 4px 15px rgba(229, 57, 53, 0.4); +.exit { + background-color: #dc3545; } -@keyframes tauntPulse { - from { - transform: scale(1); - box-shadow: 0 4px 15px rgba(229, 57, 53, 0.4); - } - 50% { - transform: scale(1.05); - box-shadow: 0 6px 20px rgba(229, 57, 53, 0.6); - } - 100% { - transform: scale(1); - box-shadow: 0 4px 15px rgba(229, 57, 53, 0.4); - } +.start-screen { + text-align: center; + z-index: 10; + background: rgba(255, 255, 255, 0.95); + /* padding: 25px 40px; */ + /* border-radius: 12px; */ + /* box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1); */ + backdrop-filter: blur(4px); + min-width: 240px; + margin: 20px auto; + width: 80%; + max-width: 300px; + position: relative; + /* border: 1px solid rgba(0, 0, 0, 0.1); */ +} + +.start-button { + padding: 12px 36px; + font-size: 18px; + background: linear-gradient(145deg, #43a047, #2e7d32); + color: white; + border: none; + border-radius: 8px; + cursor: pointer; + transition: all 0.3s ease; + margin-bottom: 12px; + box-shadow: 0 4px 15px rgba(67, 160, 71, 0.3); + width: 100%; + font-weight: 500; + text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1); + position: relative; + overflow: hidden; +} + +.start-button:hover { + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(67, 160, 71, 0.4); + filter: brightness(1.1); +} + +.start-button::after { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(120deg, transparent, rgba(255, 255, 255, 0.2), transparent); + transition: 0.5s; +} + +.start-button:hover::after { + left: 100%; +} + +.turn-info { + color: #2c3e50; + font-size: 15px; + margin-top: 5px; + font-weight: 500; + padding: 8px; + background: rgba(0, 0, 0, 0.03); + border-radius: 4px; } diff --git a/src/components/GameStatistics.vue b/src/components/GameStatistics.vue index 996135b..1c172e6 100644 --- a/src/components/GameStatistics.vue +++ b/src/components/GameStatistics.vue @@ -1,53 +1,49 @@