<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Merge Game</title>
  <style>
    body {
      font-family: sans-serif;
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 100vh;
      margin: 0;
      background-color: #f0f0f0;
    }

    #game-container {
      text-align: center;
    }

    .scoreboard {
      margin-bottom: 20px;
    }

    .scoreboard div {
      margin-bottom: 5px;
    }

    .grid-container {
      display: flex;
      gap: 20px;
    }

    .game-section {
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    .game-board {
      display: grid;
      grid-template-columns: repeat(5, 60px);
      grid-gap: 5px;
      background-color: #bbada0;
      padding: 10px;
      border-radius: 5px;
      margin-bottom: 10px;
    }

    .cell {
      width: 60px;
      height: 60px;
      background-color: #ccc0b3;
      border-radius: 5px;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 20px;
      font-weight: bold;
      cursor: pointer;
      transition: background-color 0.3s;
      user-select: none; /* Prevent text selection */
    }

    .cell:hover {
      background-color: #ede0c8;
    }

    .slots {
      display: flex;
      justify-content: center;
      gap: 5px;
    }

    .slot {
      width: 60px;
      height: 60px;
      background-color: #eee;
      border-radius: 5px;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 20px;
      cursor: pointer;
      border: 2px solid #ddd; /* Added border for better visibility */
      user-select: none; /* Prevent text selection */
    }

    .slot:hover {
      border-color: #aaa;
    }

    #game-over {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background-color: rgba(0, 0, 0, 0.8);
      color: white;
      padding: 20px;
      border-radius: 10px;
      font-size: 2em;
      z-index: 10; /* Ensure it's on top */
    }
  </style>
</head>
<body>
  <div id="game-container">
    <h1>Merge Game</h1>
    <div class="scoreboard">
      <div>Player Score: <span id="player-score">0</span></div>
      <div>CPU Score: <span id="cpu-score">0</span></div>
    </div>
    <div class="grid-container">
      <div class="game-section">
        <div id="player-board" class="game-board"></div> <!-- Left for Player -->
        <div class="slots" id="player-slots"></div> <!-- Player slots below player grid -->
      </div>
      <div class="game-section">
        <div id="cpu-board" class="game-board"></div> <!-- Right for CPU -->
        <div class="slots" id="cpu-slots"></div> <!-- CPU slots below CPU grid -->
      </div>
    </div>
    <div id="game-over" style="display:none;">Game Over!</div>
  </div>

  <script>
    const playerBoard = document.getElementById('player-board');
    const cpuBoard = document.getElementById('cpu-board');
    const playerSlots = document.getElementById('player-slots');
    const cpuSlots = document.getElementById('cpu-slots');
    const playerScoreDisplay = document.getElementById('player-score');
    const cpuScoreDisplay = document.getElementById('cpu-score');
    const gameOverScreen = document.getElementById('game-over');

    const gridSize = 5;
    let playerScore = 0;
    let cpuScore = 0;
    let playerGrid = createEmptyGrid();
    let cpuGrid = createEmptyGrid();

    function createEmptyGrid() {
      return Array.from(Array(gridSize), () => Array(gridSize).fill(0));
    }

    function initializeGame() {
      createSlots(playerSlots, 'player');
      createSlots(cpuSlots, 'cpu');
      createGrid(playerBoard, playerGrid, 'player');
      createGrid(cpuBoard, cpuGrid, 'cpu');
    }

    function createSlots(slotsContainer, player) {
      for (let i = 0; i < 5; i++) {
        const slot = document.createElement('div');
        slot.classList.add('slot');
        const value = Math.random() < 0.5 ? 2 : 4;
        slot.textContent = value;
        slot.dataset.value = value;

        if (player === 'player') {
          slot.draggable = true;
          slot.addEventListener('dragstart', dragStart);
        }

        slotsContainer.appendChild(slot);
      }
    }

    function createGrid(gridContainer, gridArray, playerType) {
      gridContainer.innerHTML = ''; // Clear grid before re-rendering
      for (let i = 0; i < gridSize; i++) {
        for (let j = 0; j < gridSize; j++) {
          const cell = document.createElement('div');
          cell.classList.add('cell');
          cell.textContent = gridArray[i][j] === 0 ? '' : gridArray[i][j];
          cell.dataset.row = i;
          cell.dataset.col = j;

          if (gridArray[i][j] > 0) {
            cell.draggable = true;
            cell.addEventListener('dragstart', dragStart);
          }

          cell.addEventListener('drop', (e) => drop(e, gridArray, playerType));
          cell.addEventListener('dragover', allowDrop);
          gridContainer.appendChild(cell);
        }
      }
    }

    function dragStart(event) {
      const source = event.target;
      const value = source.dataset.value;

      event.dataTransfer.setData('text/plain', JSON.stringify({ value }));
    }

    function allowDrop(event) {
      event.preventDefault();
    }

    function drop(event, grid, playerType) {
      event.preventDefault();
      const target = event.target;
      const { value } = JSON.parse(event.dataTransfer.getData('text/plain'));
      
      const targetRow = parseInt(target.dataset.row);
      const targetCol = parseInt(target.dataset.col);

      // Check if the target cell is empty or has the same number
      if (grid[targetRow][targetCol] === 0) {
        grid[targetRow][targetCol] = parseInt(value);
      } else if (grid[targetRow][targetCol] === parseInt(value)) {
        // Merge numbers
        const mergedValue = grid[targetRow][targetCol] * 2;
        grid[targetRow][targetCol] = mergedValue;

        // Affect CPU grid by reducing a random number by half of the merged value
        affectOpponentGrid(cpuGrid, mergedValue / 2);
      }

      updateScore();
      checkGameOver();

      if (playerType === 'player') {
        cpuTurn(); // Trigger CPU turn after player's move
      }

      createGrid(playerBoard, playerGrid, 'player');  // Re-render player grid
      createGrid(cpuBoard, cpuGrid, 'cpu'); // Re-render CPU grid after CPU plays
    }

    function cpuTurn() {
      setTimeout(() => {
        const availableCells = [];
        for (let i = 0; i < gridSize; i++) {
          for (let j = 0; j < gridSize; j++) {
            if (cpuGrid[i][j] === 0) {
              availableCells.push({ row: i, col: j });
            }
          }
        }

        const randomSlots = Array.from(cpuSlots.children);
        if (availableCells.length > 0 && randomSlots.length > 0) {
          const randomSlot = randomSlots[Math.floor(Math.random() * randomSlots.length)];
          const randomCell = availableCells[Math.floor(Math.random() * availableCells.length)];
          
          if (cpuGrid[randomCell.row][randomCell.col] === 0) {
            cpuGrid[randomCell.row][randomCell.col] = parseInt(randomSlot.dataset.value);
          } else if (cpuGrid[randomCell.row][randomCell.col] === parseInt(randomSlot.dataset.value)) {
            // Merge cells for CPU
            const mergedValue = cpuGrid[randomCell.row][randomCell.col] * 2;
            cpuGrid[randomCell.row][randomCell.col] = mergedValue;

            // Affect player grid by reducing a random number by half of the merged value
            affectOpponentGrid(playerGrid, mergedValue / 2);
          }

          // Remove the slot after placing it in the grid
          randomSlot.remove();
        }

        updateScore();
        checkGameOver();

        createGrid(cpuBoard, cpuGrid, 'cpu'); // Re-render CPU grid
      }, 500); // Delay to simulate CPU thinking time
    }

    function affectOpponentGrid(grid, reductionAmount) {
      const filledCells = [];
      for (let i = 0; i < gridSize; i++) {
        for (let j = 0; j < gridSize; j++) {
          if (grid[i][j] > 0) {
            filledCells.push({ row: i, col: j });
          }
        }
      }

      if (filledCells.length > 0) {
        const randomCell = filledCells[Math.floor(Math.random() * filledCells.length)];
        grid[randomCell.row][randomCell.col] = Math.max(0, grid[randomCell.row][randomCell.col] - reductionAmount);
      }
    }

    function updateScore() {
      playerScore = calculateScore(playerGrid);
      cpuScore = calculateScore(cpuGrid);
      playerScoreDisplay.textContent = playerScore;
      cpuScoreDisplay.textContent = cpuScore;
    }

    function calculateScore(grid) {
      return grid.flat().reduce((acc, value) => acc + value, 0);
    }

    function checkGameOver() {
      if (playerScore >= 500 || cpuScore >= 500) {
        gameOverScreen.style.display = 'block';
        gameOverScreen.textContent = playerScore >= 500 ? 'You Win!' : 'CPU Wins!';
      }
    }

    initializeGame();
  </script>
</body>
</html>
the merge between numbers on the grid is not working. After a merge, a random number on the opponent's grid is reduced by half of the merged number. For example, if a player merges two 4s to create an 8, a random number on the opponent's grid would be reduced by 4. The game continues until one player loses, which likely means they can no longer make any moves or their grid is filled. There are two 5x5 grids side by side - one for the CPU and one for the Player. Below each grid, there are 5 slots for randomly generated numbers at the start of the game. When a player merges numbers on their grid, it affects the opponent's grid: The merged number on the player's side increases. A random number on the opponent's grid decreases by half of the merged value.