HTML网页游戏五子棋

在这里插入图片描述

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>五子棋大师(修复版)</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">   
    <style>
        :root {
            --primary-gradient: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);
            --panel-bg: rgba(25, 25, 35, 0.85);
            --accent-color: #ffd700;
            --board-bg: #dcb35c;
            --board-border: #5d4037;
            --board-line: #8b4513;
            --black-stone: radial-gradient(circle at 30% 30%, #555, #000);
            --white-stone: radial-gradient(circle at 30% 30%, #fff, #ddd);
            --shadow-lg: 0 10px 30px rgba(0, 0, 0, 0.4);
            --shadow-md: 0 5px 15px rgba(0, 0, 0, 0.3);
            --transition-default: all 0.3s ease;
        }
        
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            min-height: 100vh;
            background: var(--primary-gradient);
            background-attachment: fixed;
            color: #fff;
            padding: 20px;
            line-height: 1.6;
        }
        
        .header {
            text-align: center;
            margin: 20px 0 30px;
            width: 100%;
            max-width: 800px;
        }
        
        .header h1 {
            font-size: clamp(2.4rem, 5vw, 3.2rem);
            margin-bottom: 8px;
            text-shadow: 0 2px 8px rgba(0, 0, 0, 0.6);
            letter-spacing: 1.5px;
            background: linear-gradient(to right, var(--accent-color), #ffffff);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
        }
        
        .header p {
            font-size: 1.1rem;
            opacity: 0.9;
            max-width: 600px;
            margin: 0 auto;
        }
        
        .game-container {
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
            gap: 30px;
            width: 100%;
            max-width: 1200px;
            margin-bottom: 30px;
        }
        
        .board-section {
            display: flex;
            flex-direction: column;
            align-items: center;
            background: var(--panel-bg);
            border-radius: 16px;
            padding: 25px;
            box-shadow: var(--shadow-lg);
            backdrop-filter: blur(10px);
            transition: var(--transition-default);
        }
        
        .info-section {
            flex: 1;
            min-width: 300px;
            display: flex;
            flex-direction: column;
            gap: 20px;
        }
        
        .info-card {
            background: var(--panel-bg);
            border-radius: 16px;
            padding: 25px;
            box-shadow: var(--shadow-md);
            backdrop-filter: blur(10px);
            transition: var(--transition-default);
        }
        
        .info-card:hover {
            transform: translateY(-5px);
            box-shadow: var(--shadow-lg);
        }
        
        .info-card h2 {
            display: flex;
            align-items: center;
            gap: 10px;
            margin-bottom: 18px;
            color: var(--accent-color);
            font-size: 1.8rem;
        }
        
        .board {
            display: grid;
            grid-template-columns: repeat(15, minmax(24px, 36px));
            grid-template-rows: repeat(15, minmax(24px, 36px));
            background-color: var(--board-bg);
            border: 3px solid var(--board-border);
            box-shadow: inset 0 0 15px rgba(0, 0, 0, 0.3), 0 0 20px rgba(0, 0, 0, 0.5);
            position: relative;
            background-image: 
                linear-gradient(to right, var(--board-line) 1px, transparent 1px),
                linear-gradient(to bottom, var(--board-line) 1px, transparent 1px);
            background-size: 100% 100%;
        }
        
        /* 棋盘上的五个圆点 */
        .board::before {
            content: '';
            position: absolute;
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background-color: #000;
            left: calc(3 * 100% / 14);
            top: calc(3 * 100% / 14);
        }
        
        .board::after {
            content: '';
            position: absolute;
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background-color: #000;
            left: calc(11 * 100% / 14);
            top: calc(3 * 100% / 14);
        }
        
        .board .center-dot-1 {
            position: absolute;
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background-color: #000;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
        }
        
        .board .center-dot-2 {
            position: absolute;
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background-color: #000;
            left: calc(3 * 100% / 14);
            top: calc(11 * 100% / 14);
        }
        
        .board .center-dot-3 {
            position: absolute;
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background-color: #000;
            left: calc(11 * 100% / 14);
            top: calc(11 * 100% / 14);
        }
        
        .cell {
            width: 100%;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            cursor: pointer;
            position: relative;
            z-index: 2;
            transition: var(--transition-default);
            pointer-events: auto;
        }
        
        .cell:hover::after {
            content: '';
            position: absolute;
            width: 80%;
            height: 80%;
            border-radius: 50%;
            background-color: rgba(255, 255, 255, 0.2);
            z-index: 1;
        }
        
        .stone {
            width: 85%;
            height: 85%;
            border-radius: 50%;
            position: relative;
            z-index: 3;
            box-shadow: 0 3px 6px rgba(0, 0, 0, 0.5);
            transition: transform 0.2s ease;
        }
        
        .stone.animate  {
            animation: stoneDrop 0.4s ease;
        }
        
        @keyframes stoneDrop {
            0% { transform: scale(0.1); opacity: 0; }
            70% { transform: scale(1.1); opacity: 1; }
            100% { transform: scale(1); }
        }
        
        .stone.black {
            background: var(--black-stone);
            border: 1px solid #333;
        }
        
        .stone.white {
            background: var(--white-stone);
            border: 1px solid #ccc;
        }
        
        .stone.winning {
            animation: winPulse 1.5s infinite;
        }
        
        .last-move::before {
            content: '';
            position: absolute;
            width: 100%;
            height: 100%;
            border-radius: 50%;
            box-shadow: 0 0 0 3px #ff3333;
            z-index: 1;
            animation: pulse 1.5s infinite;
        }
        
        @keyframes pulse {
            0% { box-shadow: 0 0 0 3px rgba(255, 51, 51, 0.7); }
            50% { box-shadow: 0 0 0 6px rgba(255, 51, 51, 0.3); }
            100% { box-shadow: 0 0 0 3px rgba(255, 51, 51, 0.7); }
        }
        
        .hint {
            animation: hintPulse 0.5s infinite alternate;
        }
        
        @keyframes hintPulse {
            from { box-shadow: 0 0 5px #00ff00; }
            to { box-shadow: 0 0 15px #00ff00, 0 0 20px #00ff00; }
        }
        
        .status-area {
            margin: 20px 0;
            text-align: center;
            width: 100%;
        }
        
        .status {
            font-size: 1.8rem;
            font-weight: bold;
            padding: 12px 25px;
            border-radius: 50px;
            display: inline-block;
            background: rgba(0, 0, 0, 0.4);
            text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
            margin-bottom: 15px;
            transition: var(--transition-default);
        }
        
        .status.black-turn  {
            color: var(--accent-color);
            background: rgba(0, 0, 0, 0.6);
        }
        
        .status.white-turn  {
            color: var(--accent-color);
            background: rgba(255, 255, 255, 0.2);
        }
        
        .status.win  {
            color: #4cff00;
            animation: winPulse 2s infinite;
        }
        
        @keyframes winPulse {
            0% { box-shadow: 0 0 10px rgba(76, 255, 0, 0.5); }
            50% { box-shadow: 0 0 25px rgba(76, 255, 0, 0.8); }
            100% { box-shadow: 0 0 10px rgba(76, 255, 0, 0.5); }
        }
        
        .controls {
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
            gap: 15px;
            width: 100%;
            margin-top: 10px;
        }
        
        button {
            padding: 14px 26px;
            font-size: 1.05rem;
            font-weight: 600;
            background: linear-gradient(to right, #3498db, #1a5f9e);
            color: white;
            border: none;
            border-radius: 50px;
            cursor: pointer;
            display: flex;
            align-items: center;
            gap: 8px;
            transition: var(--transition-default);
            box-shadow: var(--shadow-md);
            min-width: 130px;
            justify-content: center;
        }
        
        button:hover {
            transform: translateY(-3px);
            box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
            background: linear-gradient(to right, #3cb0fd, #1a75ca);
        }
        
        button:active {
            transform: translateY(1px);
            box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
        }
        
        button#restart {
            background: linear-gradient(to right, #e74c3c, #c0392b);
        }
        
        button#restart:hover {
            background: linear-gradient(to right, #ff6b6b, #e74c3c);
        }
        
        button#undo {
            background: linear-gradient(to right, #9b59b6, #8e44ad);
        }
        
        button#undo:hover {
            background: linear-gradient(to right, #a66bbe, #9b59b6);
        }
        
        button#save {
            background: linear-gradient(to right, #2ecc71, #27ae60);
        }
        
        button#save:hover {
            background: linear-gradient(to right, #2ecc71, #27ae60);
        }
        
        .stats {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            gap: 15px;
            margin-top: 10px;
        }
        
        .stat-item {
            background: rgba(255, 255, 255, 0.1);
            padding: 15px;
            border-radius: 10px;
            text-align: center;
            transition: var(--transition-default);
        }
        
        .stat-item:hover {
            transform: translateY(-3px);
            background: rgba(255, 255, 255, 0.15);
        }
        
        .stat-value {
            font-size: 2.2rem;
            font-weight: bold;
            color: var(--accent-color);
            margin: 8px 0;
        }
        
        .stat-label {
            font-size: 0.95rem;
            opacity: 0.8;
        }
        
        .footer {
            text-align: center;
            padding: 20px;
            font-size: 1rem;
            opacity: 0.7;
            width: 100%;
            max-width: 800px;
            margin-top: auto;
        }
        
        .settings-panel {
            position: fixed;
            top: 20px;
            right: 20px;
            background: var(--panel-bg);
            border-radius: 10px;
            padding: 15px;
            box-shadow: var(--shadow-md);
            z-index: 100;
            transition: var(--transition-default);
        }
        
        .settings-toggle {
            background: none;
            border: none;
            color: white;
            font-size: 1.5rem;
            cursor: pointer;
            padding: 5px;
            min-width: auto;
        }
        
        .settings-content {
            display: none;
            margin-top: 10px;
            animation: fadeIn 0.3s ease;
        }
        
        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(-10px); }
            to { opacity: 1; transform: translateY(0); }
        }
        
        .settings-content.show  {
            display: block;
        }
        
        .settings-item {
            margin-bottom: 10px;
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 5px 0;
        }
        
        .settings-item label {
            margin-right: 10px;
            cursor: pointer;
        }
        
        /* 复选框美化 */
        .toggle-switch {
            position: relative;
            display: inline-block;
            width: 46px;
            height: 24px;
        }
        
        .toggle-switch input {
            opacity: 0;
            width: 0;
            height: 0;
        }
        
        .toggle-slider {
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: rgba(255, 255, 255, 0.2);
            transition: .4s;
            border-radius: 24px;
        }
        
        .toggle-slider:before {
            position: absolute;
            content: "";
            height: 18px;
            width: 18px;
            left: 3px;
            bottom: 3px;
            background-color: white;
            transition: .4s;
            border-radius: 50%;
        }
        
        input:checked + .toggle-slider {
            background-color: var(--accent-color);
        }
        
        input:checked + .toggle-slider:before {
            transform: translateX(22px);
        }
        
        /* 难度选择器 */
        .difficulty-selector {
            display: flex;
            justify-content: space-between;
            margin: 15px 0;
        }
        
        .difficulty-btn {
            padding: 8px 15px;
            font-size: 0.9rem;
            background: rgba(255, 255, 255, 0.1);
            border: 2px solid transparent;
        }
        
        .difficulty-btn.active {
            background: rgba(255, 215, 0, 0.3);
            border-color: var(--accent-color);
        }
        
        /* 游戏模式选择 */
        .game-mode {
            display: flex;
            gap: 10px;
            margin-bottom: 15px;
        }
        
        .mode-btn {
            flex: 1;
            padding: 10px;
            background: rgba(255, 255, 255, 0.1);
        }
        
        .mode-btn.active {
            background: rgba(52, 152, 219, 0.5);
        }
        
        /* 保存的游戏列表 */
        .saved-games {
            max-height: 200px;
            overflow-y: auto;
            margin-top: 10px;
        }
        
        .saved-game-item {
            background: rgba(255, 255, 255, 0.1);
            padding: 10px;
            border-radius: 8px;
            margin-bottom: 8px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            cursor: pointer;
            transition: var(--transition-default);
        }
        
        .saved-game-item:hover {
            background: rgba(255, 255, 255, 0.2);
        }
        
        .saved-game-info {
            flex: 1;
        }
        
        .saved-game-name {
            font-weight: bold;
            margin-bottom: 3px;
        }
        
        .saved-game-date {
            font-size: 0.8rem;
            opacity: 0.7;
        }
        
        .saved-game-controls button {
            padding: 5px;
            margin-left: 5px;
            min-width: auto;
            background: none;
            box-shadow: none;
        }
        
        /* 保存游戏弹窗 */
        .modal {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.7);
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 2000;
            opacity: 0;
            pointer-events: none;
            transition: opacity 0.3s ease;
        }
        
        .modal.show {
            opacity: 1;
            pointer-events: all;
        }
        
        .modal-content {
            background: var(--panel-bg);
            padding: 25px;
            border-radius: 16px;
            width: 90%;
            max-width: 400px;
            box-shadow: var(--shadow-lg);
            transform: translateY(-20px);
            transition: transform 0.3s ease;
        }
        
        .modal.show .modal-content {
            transform: translateY(0);
        }
        
        .modal h3 {
            margin-bottom: 15px;
            color: var(--accent-color);
            font-size: 1.5rem;
        }
        
        .modal input {
            width: 100%;
            padding: 12px 15px;
            border: 2px solid rgba(255, 255, 255, 0.2);
            background: rgba(255, 255, 255, 0.1);
            color: white;
            border-radius: 8px;
            margin-bottom: 20px;
            font-size: 1rem;
        }
        
        .modal-buttons {
            display: flex;
            gap: 10px;
        }
        
        .modal-buttons button {
            flex: 1;
        }
        
        /* 移动设备上的走棋历史 */
        .move-history {
            max-height: 150px;
            overflow-y: auto;
            margin-top: 10px;
            padding-right: 5px;
        }
        
        .move-item {
            display: flex;
            justify-content: space-between;
            padding: 5px 0;
            border-bottom: 1px solid rgba(255, 255, 255, 0.1);
        }
        
        .move-number {
            color: var(--accent-color);
            font-weight: bold;
            min-width: 30px;
        }
        
        .move-position {
            flex: 1;
            text-align: center;
        }
        
        /* 胜利动画样式 */
        .win-animation {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.85);
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 3000;
            opacity: 0;
            pointer-events: none;
            transition: opacity 0.5s ease;
        }
        
        .win-animation.show {
            opacity: 1;
            pointer-events: all;
        }
        
        .win-content {
            text-align: center;
            padding: 40px;
            background: var(--panel-bg);
            border-radius: 20px;
            box-shadow: 0 0 30px rgba(255, 215, 0, 0.3);
            animation: popIn 0.6s ease;
        }
        
        @keyframes popIn {
            0% { transform: scale(0.5); opacity: 0; }
            70% { transform: scale(1.1); }
            100% { transform: scale(1); opacity: 1; }
        }
        
        .win-content h2 {
            color: var(--accent-color);
            font-size: 2.5rem;
            margin-bottom: 20px;
        }
        
        .win-content p {
            font-size: 1.5rem;
            margin-bottom: 30px;
        }
        
        /* 响应式设计优化 */
        @media (max-width: 768px) {
            .header {
                margin: 10px 0 20px;
            }
            
            .game-container {
                gap: 20px;
            }
            
            .board-section {
                padding: 15px;
                width: 100%;
            }
            
            .info-card {
                padding: 20px;
            }
            
            .controls {
                gap: 10px;
            }
            
            button {
                padding: 12px 18px;
                font-size: 0.9rem;
                min-width: auto;
                flex: 1;
            }
        }
        
        @media (max-width: 480px) {
            .controls {
                flex-direction: column;
            }
            
            button {
                width: 100%;
            }
            
            .stats {
                grid-template-columns: 1fr;
            }
        }
		
    </style>
</head>
<body>
    <div class="header">
        <h1><i class="fas fa-chess-board"></i> 五子棋大师</h1>
        <p>策略与智慧的终极对决!在古老棋盘上展现您的实力,成为五子连珠的冠军</p>
    </div>
    
    <div class="settings-panel">
        <button class="settings-toggle" id="settings-toggle" aria-label="打开设置"><i class="fas fa-cog"></i></button>
        <div class="settings-content" id="settings-content">
            <div class="settings-item">
                <label for="sound-toggle">声音</label>
                <label class="toggle-switch">
                    <input type="checkbox" id="sound-toggle" checked>
                    <span class="toggle-slider"></span>
                </label>
            </div>
            <div class="settings-item">
                <label for="animations-toggle">动画</label>
                <label class="toggle-switch">
                    <input type="checkbox" id="animations-toggle" checked>
                    <span class="toggle-slider"></span>
                </label>
            </div>
            <div class="settings-item">
                <label for="hints-toggle">提示</label>
                <label class="toggle-switch">
                    <input type="checkbox" id="hints-toggle" checked>
                    <span class="toggle-slider"></span>
                </label>
            </div>
            <div class="settings-item">
                <label for="history-toggle">显示走棋历史</label>
                <label class="toggle-switch">
                    <input type="checkbox" id="history-toggle" checked>
                    <span class="toggle-slider"></span>
                </label>
            </div>
        </div>
    </div>
    
    <div class="game-container">
        <div class="board-section">
            <div class="board" id="board" role="grid" aria-label="五子棋棋盘">
                <div class="center-dot-1"></div>
                <div class="center-dot-2"></div>
                <div class="center-dot-3"></div>
            </div>
            <div class="status-area">
                <div class="status black-turn" id="status" role="status">黑方回合</div>
                <div class="controls">
                    <button id="restart" aria-label="重新开始游戏"><i class="fas fa-redo"></i> 重新开始</button>
                    <button id="undo" aria-label="悔棋"><i class="fas fa-undo"></i> 悔棋</button>
                    <button id="hint" aria-label="显示提示"><i class="fas fa-lightbulb"></i> 提示</button>
                    <button id="save" aria-label="保存游戏"><i class="fas fa-save"></i> 保存</button>
                </div>
            </div>
        </div>
        
        <div class="info-section">
            <div class="info-card">
                <h2><i class="fas fa-trophy"></i> 游戏统计</h2>
                <div class="stats">
                    <div class="stat-item">
                        <div class="stat-value" id="black-wins">0</div>
                        <div class="stat-label">黑方胜利</div>
                    </div>
                    <div class="stat-item">
                        <div class="stat-value" id="white-wins">0</div>
                        <div class="stat-label">白方胜利</div>
                    </div>
                    <div class="stat-item">
                        <div class="stat-value" id="black-score">0</div>
                        <div class="stat-label">黑方得分</div>
                    </div>
                    <div class="stat-item">
                        <div class="stat-value" id="white-score">0</div>
                        <div class="stat-label">白方得分</div>
                    </div>
                </div>
            </div>
            
            <div class="info-card">
                <h2><i class="fas fa-history"></i> 走棋历史</h2>
                <div class="move-history" id="move-history">
                    <div class="move-item">
                        <div class="move-number">-</div>
                        <div class="move-position">游戏尚未开始</div>
                    </div>
                </div>
            </div>
            
            <div class="info-card">
                <h2><i class="fas fa-cog"></i> 游戏设置</h2>
                <div class="game-mode">
                    <button class="mode-btn active" data-mode="player-vs-ai">人机对战</button>
                    <button class="mode-btn" data-mode="player-vs-player">人人对战</button>
                </div>
                
                <h3 style="margin: 15px 0 5px; color: var(--accent-color);">难度级别</h3>
                <div class="difficulty-selector">
                    <button class="difficulty-btn active" data-depth="1">简单</button>
                    <button class="difficulty-btn" data-depth="2">中等</button>
                    <button class="difficulty-btn" data-depth="3">困难</button>
                </div>
            </div>
            
            <div class="info-card">
                <h2><i class="fas fa-save"></i> 保存的游戏</h2>
                <div class="saved-games" id="saved-games">
                    <div class="no-saved-games">暂无保存的游戏</div>
                </div>
            </div>
        </div>
    </div>
    
    <!-- 保存游戏弹窗 -->
    <div class="modal" id="save-modal">
        <div class="modal-content">
            <h3><i class="fas fa-save"></i> 保存当前游戏</h3>
            <input type="text" id="game-name" placeholder="输入游戏名称..." value="未命名游戏">
            <div class="modal-buttons">
                <button id="cancel-save"><i class="fas fa-times"></i> 取消</button>
                <button id="confirm-save"><i class="fas fa-check"></i> 保存</button>
            </div>
        </div>
    </div>
    
    <div class="win-animation" id="win-animation">
        <div class="win-content">
            <h2><i class="fas fa-crown"></i> 胜利!</h2>
            <p id="winner-text">黑方获胜</p>
            <button id="new-game-btn"><i class="fas fa-play-circle"></i> 开始新游戏</button>
        </div>
    </div>
    
    <div class="footer">
        <p>© 2025 五子棋大师 | 今日:2025年8月24日 农历七月初二 | 最后更新:14:30</p>
    </div>
 
    <script>
        class GomokuGame {
            constructor() {
                // 初始化默认设置,防止undefined
                this.settings = {
                    sound: true,
                    animations: true,
                    showHints: true,
                    showHistory: true,
                    gameMode: 'player-vs-ai',
                    difficulty: 1
                };

                // 常量定义
                this.BOARD_SIZE = 15;
                this.PLAYERS = {
                    BLACK: 'black',
                    WHITE: 'white',
                    AI: 'white' // AI执白棋
                };
                this.GAME_MODES = {
                    PLAYER_VS_AI: 'player-vs-ai',
                    PLAYER_VS_PLAYER: 'player-vs-player'
                };
                this.DIFFICULTY = {
                    EASY: 1,
                    MEDIUM: 2,
                    HARD: 3
                };
                this.PATTERNS = {
                    FIVE: 100000,
                    OPEN_FOUR: 5000,
                    HALF_FOUR: 1000,
                    OPEN_THREE: 500,
                    HALF_THREE: 100,
                    OPEN_TWO: 50,
                    HALF_TWO: 10,
                    OPEN_ONE: 5
                };
                
                // 初始化统计数据
                try {
                    this.blackWins = localStorage.getItem('gomoku_blackWins') ? parseInt(localStorage.getItem('gomoku_blackWins')) : 0;
                    this.whiteWins = localStorage.getItem('gomoku_whiteWins') ? parseInt(localStorage.getItem('gomoku_whiteWins')) : 0;
                } catch (e) {
                    console.error('加载统计数据失败:', e);
                    this.blackWins = 0;
                    this.whiteWins = 0;
                }
                
                // 游戏设置
                this.currentMode = this.GAME_MODES.PLAYER_VS_AI;
                this.aiDepth = this.DIFFICULTY.EASY;
                this.showHistory = true;
                
                // 初始化元素引用 
                this.initElements(); 
                // 绑定事件 
                this.bindEvents(); 
                // 初始化游戏状态 
                this.resetGame(); 
                // 先初始化设置,再初始化声音
                this.initSettings(); 
                this.initSounds(); 
                // 加载保存的游戏
                this.loadSavedGames();
                // 更新统计显示
                this.updateStatsDisplay();
                
                // 暴露实例到window便于调试
                window.gomokuGame = this;
            }
            
            initElements() {
                this.boardEl  = document.getElementById('board'); 
                this.statusDisplay  = document.getElementById('status'); 
                this.blackWinsEl  = document.getElementById('black-wins'); 
                this.whiteWinsEl  = document.getElementById('white-wins'); 
                this.blackScoreEl  = document.getElementById('black-score'); 
                this.whiteScoreEl  = document.getElementById('white-score'); 
                this.winAnimation  = document.getElementById('win-animation'); 
                this.winnerText  = document.getElementById('winner-text'); 
                this.settingsToggle  = document.getElementById('settings-toggle'); 
                this.settingsContent  = document.getElementById('settings-content'); 
                this.soundToggle  = document.getElementById('sound-toggle'); 
                this.animationsToggle  = document.getElementById('animations-toggle'); 
                this.hintsToggle  = document.getElementById('hints-toggle'); 
                this.historyToggle = document.getElementById('history-toggle');
                this.modeButtons = document.querySelectorAll('.mode-btn');
                this.difficultyButtons = document.querySelectorAll('.difficulty-btn');
                this.moveHistoryEl = document.getElementById('move-history');
                this.savedGamesEl = document.getElementById('saved-games');
                this.noSavedGamesEl = document.querySelector('.no-saved-games');
                this.saveButton = document.getElementById('save');
                this.saveModal = document.getElementById('save-modal');
                this.gameNameInput = document.getElementById('game-name');
                this.confirmSaveButton = document.getElementById('confirm-save');
                this.cancelSaveButton = document.getElementById('cancel-save');
                
                this.lastMoveCell = null;
                this.winningCells = [];
                this.aiThinking = false;
            }
            
            bindEvents() {
                document.getElementById('restart').addEventListener('click',  () => this.resetGame()); 
                document.getElementById('undo').addEventListener('click',  () => this.undoMove()); 
                document.getElementById('hint').addEventListener('click',  () => this.showHint()); 
                document.getElementById('new-game-btn').addEventListener('click',  () => {
                    this.winAnimation.classList.remove('show'); 
                    //this.resetGame(); 
                });
                this.settingsToggle.addEventListener('click',  () => this.toggleSettings()); 
                
                // 保存游戏相关事件
                this.saveButton.addEventListener('click', () => this.openSaveModal());
                this.confirmSaveButton.addEventListener('click', () => this.saveCurrentGame());
                this.cancelSaveButton.addEventListener('click', () => this.closeSaveModal());
                
                // 游戏模式切换
                this.modeButtons.forEach(btn => {
                    btn.addEventListener('click', () => {
                        this.modeButtons.forEach(b => b.classList.remove('active'));
                        btn.classList.add('active');
                        this.currentMode = btn.dataset.mode;
                        this.saveSettings();
                        this.resetGame();
                    });
                });
                
                // 难度切换
                this.difficultyButtons.forEach(btn => {
                    btn.addEventListener('click', () => {
                        this.difficultyButtons.forEach(b => b.classList.remove('active'));
                        btn.classList.add('active');
                        this.aiDepth = parseInt(btn.dataset.depth);
                        this.saveSettings();
                    });
                });
                
                // 走棋历史显示切换
                this.historyToggle.addEventListener('change', (e) => {
                    this.showHistory = e.target.checked;
                    this.saveSettings();
                    if (this.showHistory) {
                        this.moveHistoryEl.style.display = 'block';
                        this.updateMoveHistory();
                    } else {
                        this.moveHistoryEl.style.display = 'none';
                    }
                });
                
                // 键盘支持
                document.addEventListener('keydown', (e) => {
                    if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
                    
                    if (e.key === 'r' && !e.ctrlKey) this.resetGame();
                    if (e.key === 'u' && !e.ctrlKey) this.undoMove();
                    if (e.key === 'h' && !e.ctrlKey) this.showHint();
                    if (e.key === 's' && !e.ctrlKey) this.openSaveModal();
                });
            }
            
            initSounds() {
                // 使用Web Audio API创建音效
                this.audioContext = null;
                this.sounds = {
                    place: { frequency: 330, duration: 0.15, volume: 0.3 },
                    win: { frequency: 660, duration: 0.8, volume: 0.5 },
                    click: { frequency: 440, duration: 0.1, volume: 0.2 },
                    error: { frequency: 220, duration: 0.2, volume: 0.3 }
                };
            }
            
            createSound(frequency, duration, volume) {
                if (!this.audioContext) {
                    try {
                        this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
                    } catch (e) {
                        console.log('Web Audio API 不受支持');
                        return;
                    }
                }
                
                const oscillator = this.audioContext.createOscillator();
                const gainNode = this.audioContext.createGain();
                
                oscillator.type = 'sine';
                oscillator.frequency.setValueAtTime(frequency, this.audioContext.currentTime);
                gainNode.gain.setValueAtTime(volume, this.audioContext.currentTime);
                
                oscillator.connect(gainNode);
                gainNode.connect(this.audioContext.destination);
                
                oscillator.start();
                oscillator.stop(this.audioContext.currentTime + duration);
                gainNode.gain.exponentialRampToValueAtTime(0.001, this.audioContext.currentTime + duration);
            }
            
            playSound(type) {
                // 添加settings存在性检查
                if (!this.settings || !this.settings.sound)  return;
                
                const sound = this.sounds[type];
                if (sound) {
                    this.createSound(sound.frequency, sound.duration, sound.volume);
                }
            }
            
            initSettings() {
                try {
                    // 从本地存储加载设置
                    const savedSettings = localStorage.getItem('gomoku_settings');
                    if (savedSettings) {
                        // 合并保存的设置到现有默认设置
                        this.settings = { ...this.settings, ...JSON.parse(savedSettings) };
                    }
                } catch (e) {
                    console.error('加载设置失败,使用默认设置:', e);
                    // 保留已初始化的默认设置
                }
                
                // 更新UI状态
                this.soundToggle.checked = this.settings.sound;
                this.animationsToggle.checked = this.settings.animations;
                this.hintsToggle.checked = this.settings.showHints;
                this.historyToggle.checked = this.settings.showHistory;
                this.showHistory = this.settings.showHistory;
                
                // 恢复游戏模式和难度
                this.currentMode = this.settings.gameMode || this.GAME_MODES.PLAYER_VS_AI;
                this.aiDepth = this.settings.difficulty || this.DIFFICULTY.EASY;
                
                // 更新按钮状态
                this.modeButtons.forEach(btn => {
                    btn.classList.toggle('active', btn.dataset.mode === this.currentMode);
                });
                
                this.difficultyButtons.forEach(btn => {
                    btn.classList.toggle('active', parseInt(btn.dataset.depth) === this.aiDepth);
                });
                
                // 绑定设置变更事件
                this.soundToggle.addEventListener('change',  (e) => {
                    this.settings.sound  = e.target.checked;
                    this.saveSettings();
                });
                
                this.animationsToggle.addEventListener('change',  (e) => {
                    this.settings.animations  = e.target.checked;
                    this.saveSettings();
                });
                
                this.hintsToggle.addEventListener('change',  (e) => {
                    this.settings.showHints  = e.target.checked;
                    this.saveSettings();
                });
            }
            
            saveSettings() {
                this.settings.gameMode = this.currentMode;
                this.settings.difficulty = this.aiDepth;
                this.settings.showHistory = this.showHistory;
                try {
                    localStorage.setItem('gomoku_settings', JSON.stringify(this.settings));
                } catch (e) {
                    console.error('保存设置失败:', e);
                }
            }
            
            toggleSettings() {
                this.settingsContent.classList.toggle('show'); 
                this.playSound('click'); 
            }
            
            resetGame() {
                this.gameBoard  = Array(this.BOARD_SIZE).fill().map(() => Array(this.BOARD_SIZE).fill(null));
                this.currentPlayer  = this.PLAYERS.BLACK;
                this.gameActive  = true;
                this.lastMove  = null;
                this.moveHistory  = [];
                this.cellElements  = {};
                this.winningCells = [];
                this.aiThinking = false;
                
                if (this.lastMoveCell) {
                    this.lastMoveCell.classList.remove('last-move');
                    this.lastMoveCell = null;
                }
                
                this.renderBoard(); 
                this.updateStatus(); 
                this.updateMoveHistory();
            }
            
            renderBoard() {
                const fragment = document.createDocumentFragment();
                this.boardEl.innerHTML  = '';
                
                // 添加棋盘上的五个圆点
                const dot1 = document.createElement('div');
                dot1.className = 'center-dot-1';
                fragment.appendChild(dot1);
                
                const dot2 = document.createElement('div');
                dot2.className = 'center-dot-2';
                fragment.appendChild(dot2);
                
                const dot3 = document.createElement('div');
                dot3.className = 'center-dot-3';
                fragment.appendChild(dot3);
                
                for (let i = 0; i < this.BOARD_SIZE; i++) {
                    for (let j = 0; j < this.BOARD_SIZE; j++) {
                        const cell = document.createElement('div'); 
                        cell.className  = 'cell';
                        cell.dataset.row  = i;
                        cell.dataset.col  = j;
                        cell.setAttribute('role', 'gridcell');
                        cell.setAttribute('aria-label', `${i+1}${j+1}`);
                        
                        const handleClick = () => this.handleCellClick(i, j);
                        cell.addEventListener('click', handleClick);
                        cell.clickHandler = handleClick;
                        
                        fragment.appendChild(cell); 
                        this.cellElements[`${i}-${j}`]  = cell;
                    }
                }
                
                this.boardEl.appendChild(fragment);
            }
            
            handleCellClick(row, col) {
                if (!this.gameActive || this.aiThinking) {
                    this.playSound('error');
                    return;
                }
                
                if (this.currentPlayer === this.PLAYERS.AI && this.currentMode === this.GAME_MODES.PLAYER_VS_AI) {
                    this.playSound('error');
                    return;
                }
                
                if (this.gameBoard[row][col]  !== null) {
                    this.playSound('error');
                    return;
                }
                
                this.playSound('place'); 
                this.placeStone(row,  col, this.currentPlayer); 
                
                if (this.currentMode === this.GAME_MODES.PLAYER_VS_AI && this.gameActive) {
                    this.aiMove();
                }
            }
            
            placeStone(row, col, player) {
                this.gameBoard[row][col]  = player;
                this.moveHistory.push({row,  col, player});
                this.lastMove  = {row, col};
                
                this.updateBoard(); 
                this.updateMoveHistory();
                
                if (this.checkWin(row,  col)) {
                    this.showWinningStones();
                    this.showWinAnimation(player); 
                    if (player === this.PLAYERS.BLACK) {
                        this.blackWins++; 
                    } else {
                        this.whiteWins++; 
                    }
                    this.saveStats();
                    this.updateStatsDisplay();
                    this.updateScore(); 
                    this.gameActive  = false;
                    this.playSound('win'); 
                    return;
                }
                
                if (this.checkDraw())  {
                    this.statusDisplay.textContent  = '平局!';
                    this.statusDisplay.className  = 'status';
                    this.gameActive  = false;
                    return;
                }
                
                this.switchPlayer(); 
            }
            
            updateBoard() {
                this.winningCells.forEach(({row, col}) => {
                    const stone = this.cellElements[`${row}-${col}`].querySelector('.stone');
                    if (stone) stone.classList.remove('winning');
                });
                this.winningCells = [];
                
                if (this.lastMove)  {
                    const {row, col} = this.lastMove; 
                    const cell = this.cellElements[`${row}-${col}`]; 
                    
                    cell.innerHTML  = '';
                    if (this.gameBoard[row][col])  {
                        const stone = document.createElement('div'); 
                        stone.className  = `stone ${this.gameBoard[row][col]}`; 
                        if (this.settings.animations)  {
                            stone.classList.add('animate'); 
                        }
                        cell.appendChild(stone); 
                        
                        if (this.settings.animations)  {
                            setTimeout(() => stone.classList.remove('animate'),  400);
                        }
                    }
                    
                    if (this.lastMoveCell)  this.lastMoveCell.classList.remove('last-move'); 
                    cell.classList.add('last-move'); 
                    this.lastMoveCell  = cell;
                }
                
                this.updateScore(); 
            }
            
            showWinningStones() {
                if (!this.lastMove) return;
                
                const {row, col} = this.lastMove;
                const player = this.gameBoard[row][col];
                const directions = [[0, 1], [1, 0], [1, 1], [1, -1]];
                
                for (const [dx, dy] of directions) {
                    const winningSequence = [{row, col}];
                    
                    // 正向检查
                    for (let i = 1; i <= 4; i++) {
                        const r = row + i * dx;
                        const c = col + i * dy;
                        if (r < 0 || r >= this.BOARD_SIZE || c < 0 || c >= this.BOARD_SIZE || 
                            this.gameBoard[r][c] !== player) break;
                        winningSequence.push({row: r, col: c});
                    }
                    
                    // 反向检查
                    for (let i = 1; i <= 4; i++) {
                        const r = row - i * dx;
                        const c = col - i * dy;
                        if (r < 0 || r >= this.BOARD_SIZE || c < 0 || c >= this.BOARD_SIZE || 
                            this.gameBoard[r][c] !== player) break;
                        winningSequence.push({row: r, col: c});
                    }
                    
                    if (winningSequence.length >= 5) {
                        this.winningCells = winningSequence;
                        winningSequence.forEach(({row, col}) => {
                            const stone = this.cellElements[`${row}-${col}`].querySelector('.stone');
                            if (stone) stone.classList.add('winning');
                        });
                        break;
                    }
                }
            }
            
            checkWin(row, col) {
                const directions = [[0, 1], [1, 0], [1, 1], [1, -1]];
                const player = this.gameBoard[row][col]; 
                
                return directions.some(([dx,  dy]) => {
                    const count = 1 + 
                        this.countDirection(row,  col, dx, dy, player) + 
                        this.countDirection(row,  col, -dx, -dy, player);
                    return count >= 5;
                });
            }
            
            countDirection(row, col, dx, dy, player) {
                let count = 0;
                for (let i = 1; i <= 4; i++) {
                    const r = row + i * dx;
                    const c = col + i * dy;
                    if (r < 0 || r >= this.BOARD_SIZE || c < 0 || c >= this.BOARD_SIZE || 
                        this.gameBoard[r][c]  !== player) break;
                    count++;
                }
                return count;
            }
            
            checkDraw() {
                return this.moveHistory.length >= this.BOARD_SIZE * this.BOARD_SIZE;
            }
            
            showWinAnimation(player) {
                const playerName = player === this.PLAYERS.BLACK ? '黑方' : 
                                  (player === this.PLAYERS.WHITE && this.currentMode === this.GAME_MODES.PLAYER_VS_AI ? 'AI' : '白方');
                this.winnerText.textContent  = `${playerName}获胜!`;
                this.winAnimation.classList.add('show'); 
            }
            
            switchPlayer() {
                this.currentPlayer  = this.currentPlayer  === this.PLAYERS.BLACK ? this.PLAYERS.WHITE : this.PLAYERS.BLACK;
                this.updateStatus();
            }
            
            updateStatus() {
                let playerName = this.currentPlayer === this.PLAYERS.BLACK ? '黑方' : 
                                (this.currentPlayer === this.PLAYERS.WHITE && this.currentMode === this.GAME_MODES.PLAYER_VS_AI ? 'AI' : '白方');
                
                this.statusDisplay.textContent  = `${playerName}回合`;
                this.statusDisplay.className  = `status ${this.currentPlayer}-turn`; 
                this.statusDisplay.setAttribute('aria-live', 'polite');
            }
            
            undoMove() {
                if (this.moveHistory.length  <= 0 || !this.gameActive || this.aiThinking)  return;
                
                this.winningCells.forEach(({row, col}) => {
                    const stone = this.cellElements[`${row}-${col}`].querySelector('.stone');
                    if (stone) stone.classList.remove('winning');
                });
                this.winningCells = [];
                
                const stepsToUndo = this.currentMode === this.GAME_MODES.PLAYER_VS_AI ? 2 : 1;
                let undone = 0;
                
                while (this.moveHistory.length > 0 && undone < stepsToUndo) {
                    const lastMove = this.moveHistory.pop(); 
                    this.gameBoard[lastMove.row][lastMove.col]  = null;
                    undone++;
                }
                
                if (this.moveHistory.length  > 0) {
                    this.lastMove  = this.moveHistory[this.moveHistory.length  - 1];
                    this.currentPlayer  = this.lastMove.player;
                } else {
                    this.lastMove  = null;
                    this.currentPlayer  = this.PLAYERS.BLACK;
                }
                
                this.updateBoard(); 
                this.updateStatus(); 
                this.updateMoveHistory();
                this.playSound('click'); 
            }
            
            showHint() {
                if (!this.settings.showHints  || !this.gameActive || this.aiThinking)  return;
                
                const bestMove = this.findBestMove(); 
                if (bestMove) {
                    this.playSound('click'); 
                    const cell = this.cellElements[`${bestMove.row}-${bestMove.col}`]; 
                    cell.classList.add('hint'); 
                    setTimeout(() => cell.classList.remove('hint'),  2000);
                }
            }
            
            aiMove() {
                if (!this.gameActive || this.currentPlayer !== this.PLAYERS.WHITE) return;
                
                this.aiThinking = true;
                this.statusDisplay.textContent = 'AI思考中...';
                
                setTimeout(() => {
                    if (!this.gameActive) {
                        this.aiThinking = false;
                        return;
                    }
                    
                    const bestMove = this.minimax(this.aiDepth, -Infinity, Infinity, true);
                    
                    if (bestMove && this.gameActive) {
                        this.playSound('place');
                        this.placeStone(bestMove.row, bestMove.col, this.PLAYERS.AI);
                    }
                    
                    this.aiThinking = false;
                }, this.aiDepth * 300);
            }
            
            minimax(depth, alpha, beta, isMaximizingPlayer) {
                if (depth === 0) {
                    return { score: this.evaluateBoard() };
                }
                
                const possibleMoves = this.getPossibleMoves();
                if (possibleMoves.length === 0) {
                    return { score: 0 };
                }
                
                let bestMove = null;
                
                if (isMaximizingPlayer) {
                    let maxScore = -Infinity;
                    
                    for (const move of possibleMoves) {
                        this.gameBoard[move.row][move.col] = this.PLAYERS.AI;
                        
                        if (this.checkWin(move.row, move.col)) {
                            const score = this.PATTERNS.FIVE * (depth + 1);
                            this.gameBoard[move.row][move.col] = null;
                            return { ...move, score };
                        }
                        
                        const result = this.minimax(depth - 1, alpha, beta, false);
                        const currentScore = result.score;
                        
                        this.gameBoard[move.row][move.col] = null;
                        
                        if (currentScore > maxScore) {
                            maxScore = currentScore;
                            bestMove = move;
                        }
                        
                        alpha = Math.max(alpha, currentScore);
                        if (beta <= alpha) break;
                    }
                    
                    return { ...bestMove, score: maxScore };
                } else {
                    let minScore = Infinity;
                    
                    for (const move of possibleMoves) {
                        this.gameBoard[move.row][move.col] = this.PLAYERS.BLACK;
                        
                        if (this.checkWin(move.row, move.col)) {
                            const score = -this.PATTERNS.FIVE * (depth + 1);
                            this.gameBoard[move.row][move.col] = null;
                            return { ...move, score };
                        }
                        
                        const result = this.minimax(depth - 1, alpha, beta, true);
                        const currentScore = result.score;
                        
                        this.gameBoard[move.row][move.col] = null;
                        
                        if (currentScore < minScore) {
                            minScore = currentScore;
                            bestMove = move;
                        }
                        
                        beta = Math.min(beta, currentScore);
                        if (beta <= alpha) break;
                    }
                    
                    return { ...bestMove, score: minScore };
                }
            }
            
            getPossibleMoves() {
                const moves = [];
                
                for (let i = 0; i < this.BOARD_SIZE; i++) {
                    for (let j = 0; j < this.BOARD_SIZE; j++) {
                        if (this.gameBoard[i][j] === null && this.hasNearbyStones(i, j)) {
                            const score = this.evaluatePosition(i, j, this.PLAYERS.AI);
                            moves.push({ row: i, col: j, score });
                        }
                    }
                }
                
                if (moves.length === 0) {
                    const center = Math.floor(this.BOARD_SIZE / 2);
                    for (let i = center - 2; i <= center + 2; i++) {
                        for (let j = center - 2; j <= center + 2; j++) {
                            if (i >= 0 && i < this.BOARD_SIZE && j >= 0 && j < this.BOARD_SIZE && this.gameBoard[i][j] === null) {
                                moves.push({ row: i, col: j, score: 1 });
                            }
                        }
                    }
                }
                
                return moves.sort((a, b) => b.score - a.score);
            }
            
            hasNearbyStones(row, col, distance = 2) {
                for (let i = Math.max(0, row - distance); i <= Math.min(this.BOARD_SIZE - 1, row + distance); i++) {
                    for (let j = Math.max(0, col - distance); j <= Math.min(this.BOARD_SIZE - 1, col + distance); j++) {
                        if (this.gameBoard[i][j] !== null) {
                            return true;
                        }
                    }
                }
                return false;
            }
            
            evaluateBoard() {
                let score = 0;
                
                for (let i = 0; i < this.BOARD_SIZE; i++) {
                    for (let j = 0; j < this.BOARD_SIZE; j++) {
                        if (this.gameBoard[i][j] === this.PLAYERS.AI) {
                            score += this.evaluatePosition(i, j, this.PLAYERS.AI);
                        } else if (this.gameBoard[i][j] === this.PLAYERS.BLACK) {
                            score -= this.evaluatePosition(i, j, this.PLAYERS.BLACK) * 0.9;
                        }
                    }
                }
                
                return score;
            }
            
            findBestMove() {
                const possibleMoves = this.getPossibleMoves();
                if (possibleMoves.length === 0) return null;
                
                let bestScore = -Infinity;
                let bestMove = null;
                
                for (const move of possibleMoves) {
                    this.gameBoard[move.row][move.col] = this.currentPlayer;
                    const isWinningMove = this.checkWin(move.row, move.col);
                    this.gameBoard[move.row][move.col] = null;
                    
                    if (isWinningMove) {
                        return move;
                    }
                }
                
                for (const move of possibleMoves) {
                    const score = this.evaluatePosition(move.row, move.col, this.currentPlayer); 
                    if (score > bestScore) {
                        bestScore = score;
                        bestMove = move;
                    }
                }
                
                return bestMove;
            }
            
            evaluatePosition(row, col, player) {
                const opponent = player === this.PLAYERS.BLACK ? this.PLAYERS.WHITE : this.PLAYERS.BLACK;
                let score = 0;
                
                score += this.evaluatePattern(row, col, player);
                score += this.evaluatePattern(row, col, opponent) * 0.8;
                
                const center = (this.BOARD_SIZE - 1) / 2;
                const distanceToCenter = Math.sqrt(Math.pow(row - center, 2) + Math.pow(col - center, 2));
                score += (this.BOARD_SIZE - distanceToCenter) * 2;
                
                return score;
            }
            
            evaluatePattern(row, col, player) {
                let totalScore = 0;
                const directions = [[0, 1], [1, 0], [1, 1], [1, -1]];
                
                directions.forEach(([dx, dy]) => {
                    const {type} = this.checkPattern(row, col, dx, dy, player);
                    totalScore += this.PATTERNS[type] || 0;
                });
                
                return totalScore;
            }
            
            checkPattern(row, col, dx, dy, player) {
                let count = 1;
                let openEnds = 0;
                
                for (const [multiplier, isReverse] of [[1, false], [-1, true]]) {
                    let blocked = false;
                    for (let i = 1; i <= 4; i++) {
                        const r = row + i * dx * multiplier;
                        const c = col + i * dy * multiplier;
                        
                        if (r < 0 || r >= this.BOARD_SIZE || c < 0 || c >= this.BOARD_SIZE) {
                            blocked = true;
                            break;
                        }
                        
                        if (this.gameBoard[r][c] === player) {
                            count++;
                        } else if (this.gameBoard[r][c] === null) {
                            if (!isReverse) openEnds++;
                            break;
                        } else {
                            blocked = true;
                            break;
                        }
                    }
                    if (!blocked && isReverse) openEnds++;
                }
                
                let type = '';
                if (count >= 5) type = 'FIVE';
                else if (count === 4) {
                    type = openEnds >= 1 ? (openEnds === 2 ? 'OPEN_FOUR' : 'HALF_FOUR') : '';
                } else if (count === 3) {
                    type = openEnds >= 1 ? (openEnds === 2 ? 'OPEN_THREE' : 'HALF_THREE') : '';
                } else if (count === 2) {
                    type = openEnds >= 1 ? (openEnds === 2 ? 'OPEN_TWO' : 'HALF_TWO') : '';
                } else if (count === 1) {
                    type = openEnds === 2 ? 'OPEN_ONE' : '';
                }
                
                return {type, count, openEnds};
            }
            
            updateScore() {
                let blackCount = 0;
                let whiteCount = 0;
                
                for (let i = 0; i < this.BOARD_SIZE; i++) {
                    for (let j = 0; j < this.BOARD_SIZE; j++) {
                        if (this.gameBoard[i][j] === this.PLAYERS.BLACK) blackCount++;
                        else if (this.gameBoard[i][j] === this.PLAYERS.WHITE || this.gameBoard[i][j] === this.PLAYERS.AI) whiteCount++;
                    }
                }
                
                this.blackScore  = blackCount;
                this.whiteScore  = whiteCount;
                this.blackScoreEl.textContent  = this.blackScore; 
                this.whiteScoreEl.textContent  = this.whiteScore; 
            }
            
            updateStatsDisplay() {
                this.blackWinsEl.textContent = this.blackWins;
                this.whiteWinsEl.textContent = this.whiteWins;
            }
            
            saveStats() {
                try {
                    localStorage.setItem('gomoku_blackWins', this.blackWins.toString());
                    localStorage.setItem('gomoku_whiteWins', this.whiteWins.toString());
                } catch (e) {
                    console.error('保存统计数据失败:', e);
                }
            }
            
            updateMoveHistory() {
                if (!this.showHistory) return;
                
                this.moveHistoryEl.innerHTML = '';
                
                if (this.moveHistory.length === 0) {
                    const emptyItem = document.createElement('div');
                    emptyItem.className = 'move-item';
                    emptyItem.innerHTML = `
                        <div class="move-number">-</div>
                        <div class="move-position">游戏尚未开始</div>
                    `;
                    this.moveHistoryEl.appendChild(emptyItem);
                    return;
                }
                
                this.moveHistory.forEach((move, index) => {
                    const moveNumber = Math.floor(index / 2) + 1;
                    const isBlackMove = move.player === this.PLAYERS.BLACK;
                    
                    let moveItem;
                    if (index % 2 === 0) {
                        moveItem = document.createElement('div');
                        moveItem.className = 'move-item';
                        moveItem.innerHTML = `
                            <div class="move-number">${moveNumber}</div>
                            <div class="move-position ${isBlackMove ? 'black' : 'white'}">
                                ${String.fromCharCode(65 + move.col)}${move.row + 1}
                            </div>
                            <div class="move-position white"></div>
                        `;
                        this.moveHistoryEl.appendChild(moveItem);
                    } else {
                        const lastItem = this.moveHistoryEl.lastChild;
                        if (lastItem) {
                            const whitePos = lastItem.querySelector('.move-position.white');
                            whitePos.textContent = `${String.fromCharCode(65 + move.col)}${move.row + 1}`;
                        }
                    }
                });
                
                this.moveHistoryEl.scrollTop = this.moveHistoryEl.scrollHeight;
            }
            
            openSaveModal() {
                if (!this.gameActive) {
                    this.playSound('error');
                    return;
                }
                
                this.saveModal.classList.add('show');
                this.gameNameInput.focus();
                this.playSound('click');
            }
            
            closeSaveModal() {
                this.saveModal.classList.remove('show');
                this.playSound('click');
            }
            
            saveCurrentGame() {
                const gameName = this.gameNameInput.value.trim() || '未命名游戏';
                const timestamp = new Date().toISOString();
                const formattedDate = new Date().toLocaleString();
                
                const gameData = {
                    id: Date.now().toString(),
                    name: gameName,
                    date: formattedDate,
                    timestamp: timestamp,
                    board: JSON.parse(JSON.stringify(this.gameBoard)),
                    currentPlayer: this.currentPlayer,
                    moveHistory: JSON.parse(JSON.stringify(this.moveHistory)),
                    gameMode: this.currentMode,
                    difficulty: this.aiDepth
                };
                
                try {
                    let savedGames = JSON.parse(localStorage.getItem('gomoku_saved_games') || '[]');
                    savedGames.push(gameData);
                    localStorage.setItem('gomoku_saved_games', JSON.stringify(savedGames));
                } catch (e) {
                    console.error('保存游戏失败:', e);
                    alert('保存游戏失败,请重试');
                    return;
                }
                
                this.closeSaveModal();
                this.loadSavedGames();
                this.playSound('click');
            }
            
            loadSavedGames() {
                try {
                    const savedGames = JSON.parse(localStorage.getItem('gomoku_saved_games') || '[]');
                    this.savedGamesEl.innerHTML = '';
                    
                    if (savedGames.length === 0) {
                        const noGamesEl = document.createElement('div');
                        noGamesEl.className = 'no-saved-games';
                        noGamesEl.textContent = '暂无保存的游戏';
                        this.savedGamesEl.appendChild(noGamesEl);
                        return;
                    }
                    
                    savedGames.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));
                    
                    savedGames.forEach(game => {
                        const gameItem = document.createElement('div');
                        gameItem.className = 'saved-game-item';
                        gameItem.innerHTML = `
                            <div class="saved-game-info">
                                <div class="saved-game-name">${game.name}</div>
                                <div class="saved-game-date">${game.date}</div>
                            </div>
                            <div class="saved-game-controls">
                                <button class="load-game" data-id="${game.id}" title="加载游戏"><i class="fas fa-play"></i></button>
                                <button class="delete-game" data-id="${game.id}" title="删除游戏"><i class="fas fa-trash"></i></button>
                            </div>
                        `;
                        this.savedGamesEl.appendChild(gameItem);
                    });
                    
                    document.querySelectorAll('.load-game').forEach(btn => {
                        btn.addEventListener('click', (e) => {
                            e.stopPropagation();
                            this.loadGame(e.target.closest('.load-game').dataset.id);
                        });
                    });
                    
                    document.querySelectorAll('.delete-game').forEach(btn => {
                        btn.addEventListener('click', (e) => {
                            e.stopPropagation();
                            this.deleteGame(e.target.closest('.delete-game').dataset.id);
                        });
                    });
                } catch (e) {
                    console.error('加载保存的游戏失败:', e);
                    const errorEl = document.createElement('div');
                    errorEl.className = 'error-message';
                    errorEl.textContent = '加载保存的游戏失败';
                    this.savedGamesEl.appendChild(errorEl);
                }
            }
            
            // 加载指定游戏 - 修复了此处的代码不完整问题
            loadGame(gameId) {
                try {
                    const savedGames = JSON.parse(localStorage.getItem('gomoku_saved_games') || '[]');
                    const gameData = savedGames.find(game => game.id === gameId);
                    
                    if (!gameData) return;
                    
                    // 恢复游戏状态
                    this.gameBoard = JSON.parse(JSON.stringify(gameData.board));
                    this.currentPlayer = gameData.currentPlayer;
                    this.moveHistory = JSON.parse(JSON.stringify(gameData.moveHistory));
                    this.currentMode = gameData.gameMode;
                    this.aiDepth = gameData.difficulty;
                    this.gameActive = true;
                    this.aiThinking = false;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                    // 更新UI
                    this.renderBoard();
                    this.updateBoard();
                    this.updateStatus();
                    this.updateMoveHistory();
                    
                    // 更新模式和难度按钮
                    this.modeButtons.forEach(btn => {
                        if (btn.dataset.mode === this.currentMode) {
                            btn.classList.add('active');
                        } else {
                            btn.classList.remove('active');
                        }
                    });
                    
                    this.difficultyButtons.forEach(btn => {
                        if (parseInt(btn.dataset.depth) === this.aiDepth) {
                            btn.classList.add('active');
                        } else {
                            btn.classList.remove('active');
                        }
                    });
                    
                    this.playSound('click');
                } catch (e) {
                    console.error('加载游戏失败:', e);
                    alert('加载游戏失败,请重试');
                }
            }
            
            // 删除指定游戏
            deleteGame(gameId) {
                if (!confirm('确定要删除这个保存的游戏吗?')) return;
                
                try {
                    let savedGames = JSON.parse(localStorage.getItem('gomoku_saved_games') || '[]');
                    savedGames = savedGames.filter(game => game.id !== gameId);
                    
                    localStorage.setItem('gomoku_saved_games', JSON.stringify(savedGames));
                    this.loadSavedGames();
                    this.playSound('click');
                } catch (e) {
                    console.error('删除游戏失败:', e);
                    alert('删除游戏失败,请重试');
                }
            }
        }
 
        document.addEventListener('DOMContentLoaded',  () => {
            // 确保DOM完全加载后初始化游戏
            try {
                new GomokuGame();
            } catch (e) {
                console.error('初始化游戏失败:', e);
                alert('游戏初始化失败,请刷新页面重试');
            }
        });
    </script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值