井字棋-深红色风格edit icon

创建者:
用户fkxIv10d
Fork(复制)
下载
嵌入
BUG反馈
index.html
md
README.md
index.html
            
            <!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>深红色井字棋</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 100vh;
      background: linear-gradient(135deg, #1a0000 0%, #330000 30%, #4d0000 60%, #2a0000 100%);
      font-family: 'Georgia', 'Times New Roman', serif;
      color: #f5e6e6;
      overflow: hidden;
    }

    .container {
      text-align: center;
      position: relative;
    }

    h1 {
      font-size: 2.8em;
      margin-bottom: 10px;
      color: #ff4444;
      text-shadow: 0 0 20px rgba(255, 50, 50, 0.5), 0 0 40px rgba(255, 30, 30, 0.3);
      letter-spacing: 4px;
    }

    .status {
      font-size: 1.3em;
      margin-bottom: 25px;
      color: #ffcccc;
      min-height: 40px;
      display: flex;
      align-items: center;
      justify-content: center;
      text-shadow: 0 0 10px rgba(255, 100, 100, 0.4);
    }

    .status.winner {
      color: #ff6666;
      font-weight: bold;
      animation: pulse 1s ease-in-out infinite;
    }

    @keyframes pulse {
      0%, 100% { transform: scale(1); }
      50% { transform: scale(1.05); }
    }

    .board {
      display: grid;
      grid-template-columns: repeat(3, 120px);
      grid-template-rows: repeat(3, 120px);
      gap: 8px;
      margin: 0 auto 30px;
      padding: 15px;
      background: rgba(100, 0, 0, 0.3);
      border-radius: 15px;
      box-shadow: 0 0 30px rgba(150, 0, 0, 0.4), inset 0 0 20px rgba(80, 0, 0, 0.3);
      border: 2px solid rgba(200, 50, 50, 0.3);
    }

    .cell {
      width: 120px;
      height: 120px;
      background: rgba(60, 0, 0, 0.6);
      border: 2px solid rgba(180, 40, 40, 0.4);
      border-radius: 12px;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 3em;
      font-weight: bold;
      cursor: pointer;
      transition: all 0.3s ease;
      position: relative;
      overflow: hidden;
    }

    .cell::before {
      content: '';
      position: absolute;
      top: 0;
      left: -100%;
      width: 100%;
      height: 100%;
      background: linear-gradient(90deg, transparent, rgba(255, 100, 100, 0.1), transparent);
      transition: left 0.5s;
    }

    .cell:hover::before {
      left: 100%;
    }

    .cell:hover:not(.taken) {
      background: rgba(120, 0, 0, 0.7);
      border-color: rgba(220, 60, 60, 0.6);
      box-shadow: 0 0 15px rgba(200, 50, 50, 0.3);
      transform: scale(1.03);
    }

    .cell.taken {
      cursor: not-allowed;
    }

    .cell.x {
      color: #ff6b6b;
      text-shadow: 0 0 15px rgba(255, 100, 100, 0.6), 0 0 30px rgba(255, 60, 60, 0.3);
      animation: appear 0.3s ease-out;
    }

    .cell.o {
      color: #ffaa7f;
      text-shadow: 0 0 15px rgba(255, 170, 127, 0.6), 0 0 30px rgba(255, 140, 100, 0.3);
      animation: appear 0.3s ease-out;
    }

    @keyframes appear {
      0% {
        transform: scale(0) rotate(180deg);
        opacity: 0;
      }
      50% {
        transform: scale(1.2) rotate(-10deg);
      }
      100% {
        transform: scale(1) rotate(0deg);
        opacity: 1;
      }
    }

    .cell.win {
      background: rgba(180, 30, 30, 0.8);
      border-color: #ff4444;
      animation: winGlow 0.8s ease-in-out infinite alternate;
    }

    @keyframes winGlow {
      0% {
        box-shadow: 0 0 10px rgba(255, 50, 50, 0.5);
      }
      100% {
        box-shadow: 0 0 30px rgba(255, 50, 50, 0.9), 0 0 60px rgba(255, 30, 30, 0.5);
      }
    }

    .scoreboard {
      display: flex;
      justify-content: center;
      gap: 40px;
      margin-bottom: 25px;
      font-size: 1.1em;
    }

    .score {
      padding: 8px 20px;
      background: rgba(80, 0, 0, 0.5);
      border-radius: 8px;
      border: 1px solid rgba(180, 40, 40, 0.3);
    }

    .score span {
      font-weight: bold;
      color: #ff8888;
    }

    .restart-btn {
      padding: 12px 35px;
      font-size: 1.1em;
      font-family: 'Georgia', serif;
      background: linear-gradient(135deg, #8b0000, #a52a2a);
      color: #ffe0e0;
      border: 2px solid #cc3333;
      border-radius: 10px;
      cursor: pointer;
      transition: all 0.3s ease;
      text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
      box-shadow: 0 4px 15px rgba(139, 0, 0, 0.4);
      letter-spacing: 1px;
    }

    .restart-btn:hover {
      background: linear-gradient(135deg, #a52a2a, #cc3333);
      transform: translateY(-2px);
      box-shadow: 0 6px 20px rgba(180, 30, 30, 0.6);
      border-color: #ff4444;
    }

    .restart-btn:active {
      transform: translateY(0);
      box-shadow: 0 2px 10px rgba(139, 0, 0, 0.4);
    }

    .particles {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      pointer-events: none;
      z-index: -1;
    }

    .particle {
      position: absolute;
      width: 4px;
      height: 4px;
      background: rgba(255, 80, 80, 0.4);
      border-radius: 50%;
      animation: float linear infinite;
    }

    @keyframes float {
      0% {
        transform: translateY(100vh) rotate(0deg);
        opacity: 0;
      }
      10% {
        opacity: 1;
      }
      90% {
        opacity: 1;
      }
      100% {
        transform: translateY(-10vh) rotate(720deg);
        opacity: 0;
      }
    }
  </style>
</head>

<body>
  <div class="particles" id="particles"></div>
  <div class="container">
    <h1>⚔ 井 字 棋 ⚔</h1>
    <div class="scoreboard">
      <div class="score">玩家 X: <span id="scoreX">0</span></div>
      <div class="score">平局: <span id="scoreDraw">0</span></div>
      <div class="score">玩家 O: <span id="scoreO">0</span></div>
    </div>
    <div class="status" id="status">轮到玩家 X</div>
    <div class="board" id="board">
      <div class="cell" data-index="0"></div>
      <div class="cell" data-index="1"></div>
      <div class="cell" data-index="2"></div>
      <div class="cell" data-index="3"></div>
      <div class="cell" data-index="4"></div>
      <div class="cell" data-index="5"></div>
      <div class="cell" data-index="6"></div>
      <div class="cell" data-index="7"></div>
      <div class="cell" data-index="8"></div>
    </div>
    <button class="restart-btn" id="restartBtn">重新开始</button>
  </div>

  <script>
    const cells = document.querySelectorAll('.cell');
    const statusEl = document.getElementById('status');
    const restartBtn = document.getElementById('restartBtn');
    const scoreXEl = document.getElementById('scoreX');
    const scoreOEl = document.getElementById('scoreO');
    const scoreDrawEl = document.getElementById('scoreDraw');

    let board = ['', '', '', '', '', '', '', '', ''];
    let currentPlayer = 'X';
    let gameActive = true;
    let scores = { X: 0, O: 0, draw: 0 };

    const winConditions = [
      [0, 1, 2], [3, 4, 5], [6, 7, 8],
      [0, 3, 6], [1, 4, 7], [2, 5, 8],
      [0, 4, 8], [2, 4, 6]
    ];

    function checkWinner() {
      for (let condition of winConditions) {
        const [a, b, c] = condition;
        if (board[a] && board[a] === board[b] && board[a] === board[c]) {
          return { winner: board[a], line: condition };
        }
      }
      if (!board.includes('')) {
        return { winner: 'draw', line: [] };
      }
      return null;
    }

    function updateDisplay() {
      cells.forEach((cell, index) => {
        cell.textContent = board[index];
        if (board[index]) {
          cell.classList.add('taken', board[index].toLowerCase());
        }
      });
    }

    function handleCellClick(e) {
      const index = parseInt(e.target.dataset.index);
      if (board[index] || !gameActive) return;

      board[index] = currentPlayer;
      updateDisplay();

      const result = checkWinner();
      if (result) {
        gameActive = false;
        if (result.winner === 'draw') {
          statusEl.textContent = '平局!';
          statusEl.classList.add('winner');
          scores.draw++;
          scoreDrawEl.textContent = scores.draw;
        } else {
          statusEl.textContent = `🎉 玩家 ${result.winner} 获胜!🎉`;
          statusEl.classList.add('winner');
          scores[result.winner]++;
          if (result.winner === 'X') scoreXEl.textContent = scores.X;
          else scoreOEl.textContent = scores.O;

          result.line.forEach(i => {
            cells[i].classList.add('win');
          });
        }
      } else {
        currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
        statusEl.textContent = `轮到玩家 ${currentPlayer}`;
      }
    }

    function restartGame() {
      board = ['', '', '', '', '', '', '', '', ''];
      gameActive = true;
      currentPlayer = 'X';
      statusEl.textContent = '轮到玩家 X';
      statusEl.classList.remove('winner');

      cells.forEach(cell => {
        cell.className = 'cell';
        cell.textContent = '';
      });
    }

    cells.forEach(cell => cell.addEventListener('click', handleCellClick));
    restartBtn.addEventListener('click', restartGame);

    // Create floating particles
    const particlesContainer = document.getElementById('particles');
    for (let i = 0; i < 20; i++) {
      const particle = document.createElement('div');
      particle.className = 'particle';
      particle.style.left = Math.random() * 100 + '%';
      particle.style.animationDuration = (Math.random() * 10 + 8) + 's';
      particle.style.animationDelay = Math.random() * 10 + 's';
      particle.style.width = (Math.random() * 4 + 2) + 'px';
      particle.style.height = particle.style.width;
      particlesContainer.appendChild(particle);
    }
  </script>
</body>

</html>
        
编辑器加载中
预览
控制台