<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Mobile Chess Game</title>
  <style>
    body {
      margin: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      background: #f0f0f0;
    }
    #board {
      display: grid;
      grid-template-columns: repeat(8, 12.5vw);
      grid-template-rows: repeat(8, 12.5vw);
      width: 100vw;
      max-width: 100vh;
      aspect-ratio: 1 / 1;
      border: 2px solid #333;
    }
    .cell {
      width: 100%;
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 6vw;
      user-select: none;
    }
    .white { background: #eee; }
    .black { background: #444; color: white; }
    .selected { outline: 3px solid yellow; }
  </style>
</head>
<body>
  <div id="board"></div>

  <script>
    const board = document.getElementById("board");
    const pieces = {
      r: "♜", n: "♞", b: "♝", q: "♛", k: "♚", p: "♟",
      R: "♖", N: "♘", B: "♗", Q: "♕", K: "♔", P: "♙"
    };

    let game = [
      "rnbqkbnr",
      "pppppppp",
      "........",
      "........",
      "........",
      "........",
      "PPPPPPPP",
      "RNBQKBNR"
    ].map(row => row.split(""));

    let selected = null;
    let turn = "white";

    function draw() {
      board.innerHTML = "";
      for (let r = 0; r < 8; r++) {
        for (let c = 0; c < 8; c++) {
          const cell = document.createElement("div");
          cell.className = `cell ${(r + c) % 2 === 0 ? "white" : "black"}`;
          cell.dataset.row = r;
          cell.dataset.col = c;
          const piece = game[r][c];
          if (pieces[piece]) cell.textContent = pieces[piece];
          if (selected && selected[0] === r && selected[1] === c)
            cell.classList.add("selected");
          cell.onclick = () => handleClick(r, c);
          board.appendChild(cell);
        }
      }
    }

    function handleClick(r, c) {
      const piece = game[r][c];

      if (!selected) {
        if ((turn === "white" && piece === piece.toUpperCase() && piece !== ".") ||
            (turn === "black" && piece === piece.toLowerCase() && piece !== ".")) {
          selected = [r, c];
        }
      } else {
        const [sr, sc] = selected;
        if (sr === r && sc === c) {
          selected = null; // Deselect if tapped again
        } else if (isValidMove(sr, sc, r, c)) {
          const target = game[r][c];
          if (target === "k" || target === "K") {
            alert(`${turn} wins!`);
            location.reload();
          }
          game[r][c] = game[sr][sc];
          game[sr][sc] = ".";
          turn = turn === "white" ? "black" : "white";
          selected = null;
        } else {
          selected = null;
        }
      }
      draw();
    }

    function isValidMove(sr, sc, r, c) {
      const piece = game[sr][sc];
      const target = game[r][c];
      if (piece === ".") return false;
      if (piece === target) return false;

      const isWhite = piece === piece.toUpperCase();
      const dr = r - sr;
      const dc = c - sc;

      switch (piece.toLowerCase()) {
        case "p":
          let dir = isWhite ? -1 : 1;
          if (dc === 0 && target === "." && dr === dir) return true;
          if (dc === 0 && target === "." && dr === 2 * dir && (isWhite ? sr === 6 : sr === 1)) return true;
          if (Math.abs(dc) === 1 && dr === dir && target !== "." && (isWhite !== (target === target.toUpperCase()))) return true;
          break;
        case "r":
          if (sr === r || sc === c) return clearPath(sr, sc, r, c);
          break;
        case "n":
          if ((Math.abs(dr) === 2 && Math.abs(dc) === 1) || (Math.abs(dr) === 1 && Math.abs(dc) === 2)) return true;
          break;
        case "b":
          if (Math.abs(dr) === Math.abs(dc)) return clearPath(sr, sc, r, c);
          break;
        case "q":
          if (sr === r || sc === c || Math.abs(dr) === Math.abs(dc)) return clearPath(sr, sc, r, c);
          break;
        case "k":
          if (Math.abs(dr) <= 1 && Math.abs(dc) <= 1) return true;
          break;
      }
      return false;
    }

    function clearPath(sr, sc, r, c) {
      const dRow = Math.sign(r - sr);
      const dCol = Math.sign(c - sc);
      let i = sr + dRow, j = sc + dCol;
      while (i !== r || j !== c) {
        if (game[i][j] !== ".") return false;
        i += dRow;
        j += dCol;
      }
      return true;
    }

    draw();
  </script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Mobile Chess Game</title>
  <style>
    body {
      margin: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      background: #f0f0f0;
    }
    #board {
      display: grid;
      grid-template-columns: repeat(8, 12.5vw);
      grid-template-rows: repeat(8, 12.5vw);
      width: 100vw;
      max-width: 100vh;
      aspect-ratio: 1 / 1;
      border: 2px solid #333;
    }
    .cell {
      width: 100%;
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 6vw;
      user-select: none;
    }
    .white { background: #eee; }
    .black { background: #444; color: white; }
    .selected { outline: 3px solid yellow; }
  </style>
</head>
<body>
  <div id="board"></div>

  <script>
    const board = document.getElementById("board");
    const pieces = {
      r: "♜", n: "♞", b: "♝", q: "♛", k: "♚", p: "♟",
      R: "♖", N: "♘", B: "♗", Q: "♕", K: "♔", P: "♙"
    };

    let game = [
      "rnbqkbnr",
      "pppppppp",
      "........",
      "........",
      "........",
      "........",
      "PPPPPPPP",
      "RNBQKBNR"
    ].map(row => row.split(""));

    let selected = null;
    let turn = "white";

    function draw() {
      board.innerHTML = "";
      for (let r = 0; r < 8; r++) {
        for (let c = 0; c < 8; c++) {
          const cell = document.createElement("div");
          cell.className = `cell ${(r + c) % 2 === 0 ? "white" : "black"}`;
          cell.dataset.row = r;
          cell.dataset.col = c;
          const piece = game[r][c];
          if (pieces[piece]) cell.textContent = pieces[piece];
          if (selected && selected[0] === r && selected[1] === c)
            cell.classList.add("selected");
          cell.onclick = () => handleClick(r, c);
          board.appendChild(cell);
        }
      }
    }

    function handleClick(r, c) {
      const piece = game[r][c];

      if (!selected) {
        if ((turn === "white" && piece === piece.toUpperCase() && piece !== ".") ||
            (turn === "black" && piece === piece.toLowerCase() && piece !== ".")) {
          selected = [r, c];
        }
      } else {
        const [sr, sc] = selected;
        if (sr === r && sc === c) {
          selected = null; // Deselect if tapped again
        } else if (isValidMove(sr, sc, r, c)) {
          const target = game[r][c];
          if (target === "k" || target === "K") {
            alert(`${turn} wins!`);
            location.reload();
          }
          game[r][c] = game[sr][sc];
          game[sr][sc] = ".";
          turn = turn === "white" ? "black" : "white";
          selected = null;
        } else {
          selected = null;
        }
      }
      draw();
    }

    function isValidMove(sr, sc, r, c) {
      const piece = game[sr][sc];
      const target = game[r][c];
      if (piece === ".") return false;
      if (piece === target) return false;

      const isWhite = piece === piece.toUpperCase();
      const dr = r - sr;
      const dc = c - sc;

      switch (piece.toLowerCase()) {
        case "p":
          let dir = isWhite ? -1 : 1;
          if (dc === 0 && target === "." && dr === dir) return true;
          if (dc === 0 && target === "." && dr === 2 * dir && (isWhite ? sr === 6 : sr === 1)) return true;
          if (Math.abs(dc) === 1 && dr === dir && target !== "." && (isWhite !== (target === target.toUpperCase()))) return true;
          break;
        case "r":
          if (sr === r || sc === c) return clearPath(sr, sc, r, c);
          break;
        case "n":
          if ((Math.abs(dr) === 2 && Math.abs(dc) === 1) || (Math.abs(dr) === 1 && Math.abs(dc) === 2)) return true;
          break;
        case "b":
          if (Math.abs(dr) === Math.abs(dc)) return clearPath(sr, sc, r, c);
          break;
        case "q":
          if (sr === r || sc === c || Math.abs(dr) === Math.abs(dc)) return clearPath(sr, sc, r, c);
          break;
        case "k":
          if (Math.abs(dr) <= 1 && Math.abs(dc) <= 1) return true;
          break;
      }
      return false;
    }

    function clearPath(sr, sc, r, c) {
      const dRow = Math.sign(r - sr);
      const dCol = Math.sign(c - sc);
      let i = sr + dRow, j = sc + dCol;
      while (i !== r || j !== c) {
        if (game[i][j] !== ".") return false;
        i += dRow;
        j += dCol;
      }
      return true;
    }

    draw();
  </script>
</body>
</html>

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.