Game

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Traversal Logic Test Game</title>
  <style>
    body {
      font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
      background: #f5f5f5;
      margin: 0;
      padding: 20px;
    }

    h1 {
      margin-top: 0;
    }

    .controls {
      margin-bottom: 20px;
      padding: 10px;
      background: #ffffff;
      border-radius: 8px;
      box-shadow: 0 1px 3px rgba(0,0,0,0.1);
    }

    label {
      font-weight: 600;
      margin-right: 8px;
    }

    input[type="text"] {
      padding: 6px 8px;
      border-radius: 4px;
      border: 1px solid #ccc;
      min-width: 120px;
    }

    button {
      padding: 6px 12px;
      border-radius: 4px;
      border: none;
      cursor: pointer;
      margin-left: 8px;
    }

    button#new-game {
      background: #666;
      color: #fff;
    }

    button#run-program {
      background: #007acc;
      color: #fff;
    }

    button:hover {
      opacity: 0.9;
    }

    #status {
      margin-top: 10px;
      font-size: 0.95rem;
    }

    #status span.label {
      font-weight: 600;
    }

    #grids-container {
      display: flex;
      gap: 20px;
      flex-wrap: wrap;
    }

    .grid {
      background: #ffffff;
      padding: 10px;
      border-radius: 8px;
      box-shadow: 0 1px 3px rgba(0,0,0,0.1);
    }

    .grid-title {
      font-weight: 700;
      text-align: center;
      margin-bottom: 6px;
    }

    .grid-cells {
      display: grid;
      grid-template-columns: repeat(9, 22px);
      grid-template-rows: repeat(9, 22px);
      gap: 2px;
    }

    .cell {
      width: 22px;
      height: 22px;
      border-radius: 3px;
      border: 1px solid #ddd;
      box-sizing: border-box;
      font-size: 10px;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .cell.empty {
      background: #fafafa;
    }

    .cell.occupied {
      background: #cfd8dc;
    }

    .cell.path {
      background: #4caf50;
      color: #fff;
      font-weight: 700;
      border-color: #2e7d32;
    }

    .legend {
      margin-top: 10px;
      font-size: 0.85rem;
    }

    .legend span.box {
      display: inline-block;
      width: 14px;
      height: 14px;
      border-radius: 3px;
      border: 1px solid #ccc;
      margin-right: 4px;
      vertical-align: middle;
    }

    .legend .box-empty { background: #fafafa; }
    .legend .box-occupied { background: #cfd8dc; }
    .legend .box-path { background: #4caf50; border-color: #2e7d32; }

  </style>
</head>
<body>

  <h1>Traversal Logic Test – 3 Grids</h1>

  <div class="controls">
    <div>
      <label for="coord-input">Start coordinate:</label>
      <input id="coord-input" type="text" placeholder="e.g. X4Y9" />
      <button id="run-program">Run Program</button>
      <button id="new-game">New Game (randomise grids)</button>
    </div>
    <div id="status"></div>

    <div class="legend">
      <span class="box box-empty"></span> Empty &nbsp;&nbsp;
      <span class="box box-occupied"></span> Occupied &nbsp;&nbsp;
      <span class="box box-path"></span> Path chosen on each grid
    </div>
  </div>

  <div id="grids-container"></div>

  <script>
    const GRID_SIZE = 9;
    const NUM_GRIDS = 3;
    const GRID_NAMES = ["A", "B", "C"];

    let grids = [];

    // Utility: set status message
    function setStatus(message, isError = false) {
      const statusEl = document.getElementById("status");
      statusEl.innerHTML = `<span class="label">${isError ? "Status (error):" : "Status:"}</span> ${message}`;
      statusEl.style.color = isError ? "#c62828" : "#333";
    }

    // Create 3 grids, each with 50% random occupancy
    function generateGrids() {
      grids = [];
      for (let g = 0; g < NUM_GRIDS; g++) {
        const grid = [];
        for (let y = 0; y < GRID_SIZE; y++) {
          const row = [];
          for (let x = 0; x < GRID_SIZE; x++) {
            // 50% chance of being occupied
            row.push(Math.random() < 0.5);
          }
          grid.push(row);
        }
        grids.push(grid);
      }
      renderGrids(); // initial render without any path
      setStatus("New game created. Enter a start coordinate like X4Y9 and click Run Program.");
    }

    // Render the grids, optionally highlighting a path per grid
    function renderGrids(pathCoords = []) {
      const container = document.getElementById("grids-container");
      container.innerHTML = "";

      grids.forEach((grid, gridIndex) => {
        const gridDiv = document.createElement("div");
        gridDiv.className = "grid";

        const title = document.createElement("div");
        title.className = "grid-title";
        title.textContent = `Grid ${GRID_NAMES[gridIndex]}`;
        gridDiv.appendChild(title);

        const cellsWrapper = document.createElement("div");
        cellsWrapper.className = "grid-cells";

        for (let y = 1; y <= GRID_SIZE; y++) {
          for (let x = 1; x <= GRID_SIZE; x++) {
            const cell = document.createElement("div");
            cell.className = "cell";

            const occupied = grid[y - 1][x - 1];
            if (occupied) {
              cell.classList.add("occupied");
            } else {
              cell.classList.add("empty");
            }

            // Highlight path cell if present
            const inPath = pathCoords.some(
              (p) => p.gridIndex === gridIndex && p.x === x && p.y === y
            );
            if (inPath) {
              cell.classList.add("path");
              cell.textContent = "●";
            }

            cellsWrapper.appendChild(cell);
          }
        }

        gridDiv.appendChild(cellsWrapper);
        container.appendChild(gridDiv);
      });
    }

    // Traverse a single grid according to your search order:
    // 1. (X, Y)
    // 2. scan +X
    // 3. scan -X
    // 4. scan +Y
    // 5. scan -Y
    function traverseGrid(grid, startX, startY) {
      const isOccupied = (x, y) => grid[y - 1][x - 1];

      // 1. Check (X, Y)
      if (isOccupied(startX, startY)) {
        return { found: true, x: startX, y: startY };
      }

      // 2. Scan to the right (X+1 to 9)
      for (let x = startX + 1; x <= GRID_SIZE; x++) {
        if (isOccupied(x, startY)) {
          return { found: true, x, y: startY };
        }
      }

      // 3. Scan to the left (X-1 down to 1)
      for (let x = startX - 1; x >= 1; x--) {
        if (isOccupied(x, startY)) {
          return { found: true, x, y: startY };
        }
      }

      // 4. Scan down (Y+1 to 9) at fixed X
      for (let y = startY + 1; y <= GRID_SIZE; y++) {
        if (isOccupied(startX, y)) {
          return { found: true, x: startX, y };
        }
      }

      // 5. Scan up (Y-1 down to 1) at fixed X
      for (let y = startY - 1; y >= 1; y--) {
        if (isOccupied(startX, y)) {
          return { found: true, x: startX, y };
        }
      }

      // Nothing found
      return { found: false };
    }

    // Parse user input like "X4Y9"
    function parseCoordinate(input) {
      const trimmed = input.trim().toUpperCase();
      const match = trimmed.match(/^X(\d)Y(\d)$/);
      if (!match) {
        return null;
      }
      const x = parseInt(match[1], 10);
      const y = parseInt(match[2], 10);
      if (
        Number.isNaN(x) ||
        Number.isNaN(y) ||
        x < 1 ||
        x > GRID_SIZE ||
        y < 1 ||
        y > GRID_SIZE
      ) {
        return null;
      }
      return { x, y };
    }

    // Run the full 3-grid traversal
    function runProgram() {
      const inputEl = document.getElementById("coord-input");
      const coord = parseCoordinate(inputEl.value);

      if (!coord) {
        setStatus('Invalid coordinate. Use format like "X4Y9" with X and Y between 1 and 9.', true);
        return;
      }

      let { x, y } = coord;
      const path = [];

      for (let g = 0; g < NUM_GRIDS; g++) {
        const result = traverseGrid(grids[g], x, y);
        if (!result.found) {
          setStatus(
            `Traversal failed on Grid ${GRID_NAMES[g]}. No occupied cell found from start X${x}Y${y} using the search order (X,Y → +X → -X → +Y →_

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Traversal Logic Test Game</title>
  <style>
    body {
      font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
      background: #f5f5f5;
      margin: 0;
      padding: 20px;
    }

    h1 {
      margin-top: 0;
    }

    .controls {
      margin-bottom: 20px;
      padding: 10px;
      background: #ffffff;
      border-radius: 8px;
      box-shadow: 0 1px 3px rgba(0,0,0,0.1);
    }

    label {
      font-weight: 600;
      margin-right: 8px;
    }

    input[type="text"] {
      padding: 6px 8px;
      border-radius: 4px;
      border: 1px solid #ccc;
      min-width: 120px;
    }

    button {
      padding: 6px 12px;
      border-radius: 4px;
      border: none;
      cursor: pointer;
      margin-left: 8px;
    }

    button#new-game {
      background: #666;
      color: #fff;
    }

    button#run-program {
      background: #007acc;
      color: #fff;
    }

    button:hover {
      opacity: 0.9;
    }

    #status {
      margin-top: 10px;
      font-size: 0.95rem;
    }

    #status span.label {
      font-weight: 600;
    }

    #grids-container {
      display: flex;
      gap: 20px;
      flex-wrap: wrap;
    }

    .grid {
      background: #ffffff;
      padding: 10px;
      border-radius: 8px;
      box-shadow: 0 1px 3px rgba(0,0,0,0.1);
    }

    .grid-title {
      font-weight: 700;
      text-align: center;
      margin-bottom: 6px;
    }

    .grid-cells {
      display: grid;
      grid-template-columns: repeat(9, 22px);
      grid-template-rows: repeat(9, 22px);
      gap: 2px;
    }

    .cell {
      width: 22px;
      height: 22px;
      border-radius: 3px;
      border: 1px solid #ddd;
      box-sizing: border-box;
      font-size: 10px;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .cell.empty {
      background: #fafafa;
    }

    .cell.occupied {
      background: #cfd8dc;
    }

    .cell.path {
      background: #4caf50;
      color: #fff;
      font-weight: 700;
      border-color: #2e7d32;
    }

    .legend {
      margin-top: 10px;
      font-size: 0.85rem;
    }

    .legend span.box {
      display: inline-block;
      width: 14px;
      height: 14px;
      border-radius: 3px;
      border: 1px solid #ccc;
      margin-right: 4px;
      vertical-align: middle;
    }

    .legend .box-empty { background: #fafafa; }
    .legend .box-occupied { background: #cfd8dc; }
    .legend .box-path { background: #4caf50; border-color: #2e7d32; }

  </style>
</head>
<body>

  <h1>Traversal Logic Test – 3 Grids</h1>

  <div class="controls">
    <div>
      <label for="coord-input">Start coordinate:</label>
      <input id="coord-input" type="text" placeholder="e.g. X4Y9" />
      <button id="run-program">Run Program</button>
      <button id="new-game">New Game (randomise grids)</button>
    </div>
    <div id="status"></div>

    <div class="legend">
      <span class="box box-empty"></span> Empty &nbsp;&nbsp;
      <span class="box box-occupied"></span> Occupied &nbsp;&nbsp;
      <span class="box box-path"></span> Path chosen on each grid
    </div>
  </div>

  <div id="grids-container"></div>

  <script>
    const GRID_SIZE = 9;
    const NUM_GRIDS = 3;
    const GRID_NAMES = ["A", "B", "C"];

    let grids = [];

    // Utility: set status message
    function setStatus(message, isError = false) {
      const statusEl = document.getElementById("status");
      statusEl.innerHTML = `<span class="label">${isError ? "Status (error):" : "Status:"}</span> ${message}`;
      statusEl.style.color = isError ? "#c62828" : "#333";
    }

    // Create 3 grids, each with 50% random occupancy
    function generateGrids() {
      grids = [];
      for (let g = 0; g < NUM_GRIDS; g++) {
        const grid = [];
        for (let y = 0; y < GRID_SIZE; y++) {
          const row = [];
          for (let x = 0; x < GRID_SIZE; x++) {
            // 50% chance of being occupied
            row.push(Math.random() < 0.5);
          }
          grid.push(row);
        }
        grids.push(grid);
      }
      renderGrids(); // initial render without any path
      setStatus("New game created. Enter a start coordinate like X4Y9 and click Run Program.");
    }

    // Render the grids, optionally highlighting a path per grid
    function renderGrids(pathCoords = []) {
      const container = document.getElementById("grids-container");
      container.innerHTML = "";

      grids.forEach((grid, gridIndex) => {
        const gridDiv = document.createElement("div");
        gridDiv.className = "grid";

        const title = document.createElement("div");
        title.className = "grid-title";
        title.textContent = `Grid ${GRID_NAMES[gridIndex]}`;
        gridDiv.appendChild(title);

        const cellsWrapper = document.createElement("div");
        cellsWrapper.className = "grid-cells";

        for (let y = 1; y <= GRID_SIZE; y++) {
          for (let x = 1; x <= GRID_SIZE; x++) {
            const cell = document.createElement("div");
            cell.className = "cell";

            const occupied = grid[y - 1][x - 1];
            if (occupied) {
              cell.classList.add("occupied");
            } else {
              cell.classList.add("empty");
            }

            // Highlight path cell if present
            const inPath = pathCoords.some(
              (p) => p.gridIndex === gridIndex && p.x === x && p.y === y
            );
            if (inPath) {
              cell.classList.add("path");
              cell.textContent = "●";
            }

            cellsWrapper.appendChild(cell);
          }
        }

        gridDiv.appendChild(cellsWrapper);
        container.appendChild(gridDiv);
      });
    }

    // Traverse a single grid according to your search order:
    // 1. (X, Y)
    // 2. scan +X
    // 3. scan -X
    // 4. scan +Y
    // 5. scan -Y
    function traverseGrid(grid, startX, startY) {
      const isOccupied = (x, y) => grid[y - 1][x - 1];

      // 1. Check (X, Y)
      if (isOccupied(startX, startY)) {
        return { found: true, x: startX, y: startY };
      }

      // 2. Scan to the right (X+1 to 9)
      for (let x = startX + 1; x <= GRID_SIZE; x++) {
        if (isOccupied(x, startY)) {
          return { found: true, x, y: startY };
        }
      }

      // 3. Scan to the left (X-1 down to 1)
      for (let x = startX - 1; x >= 1; x--) {
        if (isOccupied(x, startY)) {
          return { found: true, x, y: startY };
        }
      }

      // 4. Scan down (Y+1 to 9) at fixed X
      for (let y = startY + 1; y <= GRID_SIZE; y++) {
        if (isOccupied(startX, y)) {
          return { found: true, x: startX, y };
        }
      }

      // 5. Scan up (Y-1 down to 1) at fixed X
      for (let y = startY - 1; y >= 1; y--) {
        if (isOccupied(startX, y)) {
          return { found: true, x: startX, y };
        }
      }

      // Nothing found
      return { found: false };
    }

    // Parse user input like "X4Y9"
    function parseCoordinate(input) {
      const trimmed = input.trim().toUpperCase();
      const match = trimmed.match(/^X(\d)Y(\d)$/);
      if (!match) {
        return null;
      }
      const x = parseInt(match[1], 10);
      const y = parseInt(match[2], 10);
      if (
        Number.isNaN(x) ||
        Number.isNaN(y) ||
        x < 1 ||
        x > GRID_SIZE ||
        y < 1 ||
        y > GRID_SIZE
      ) {
        return null;
      }
      return { x, y };
    }

    // Run the full 3-grid traversal
    function runProgram() {
      const inputEl = document.getElementById("coord-input");
      const coord = parseCoordinate(inputEl.value);

      if (!coord) {
        setStatus('Invalid coordinate. Use format like "X4Y9" with X and Y between 1 and 9.', true);
        return;
      }

      let { x, y } = coord;
      const path = [];

      for (let g = 0; g < NUM_GRIDS; g++) {
        const result = traverseGrid(grids[g], x, y);
        if (!result.found) {
          setStatus(
            `Traversal failed on Grid ${GRID_NAMES[g]}. No occupied cell found from start X${x}Y${y} using the search order (X,Y → +X → -X → +Y →_

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Traversal Logic Test Game</title>
  <style>
    body {
      font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
      background: #f5f5f5;
      margin: 0;
      padding: 20px;
    }

    h1 {
      margin-top: 0;
    }

    .controls {
      margin-bottom: 20px;
      padding: 10px;
      background: #ffffff;
      border-radius: 8px;
      box-shadow: 0 1px 3px rgba(0,0,0,0.1);
    }

    label {
      font-weight: 600;
      margin-right: 8px;
    }

    input[type="text"] {
      padding: 6px 8px;
      border-radius: 4px;
      border: 1px solid #ccc;
      min-width: 120px;
    }

    button {
      padding: 6px 12px;
      border-radius: 4px;
      border: none;
      cursor: pointer;
      margin-left: 8px;
    }

    button#new-game {
      background: #666;
      color: #fff;
    }

    button#run-program {
      background: #007acc;
      color: #fff;
    }

    button:hover {
      opacity: 0.9;
    }

    #status {
      margin-top: 10px;
      font-size: 0.95rem;
    }

    #status span.label {
      font-weight: 600;
    }

    #grids-container {
      display: flex;
      gap: 20px;
      flex-wrap: wrap;
    }

    .grid {
      background: #ffffff;
      padding: 10px;
      border-radius: 8px;
      box-shadow: 0 1px 3px rgba(0,0,0,0.1);
    }

    .grid-title {
      font-weight: 700;
      text-align: center;
      margin-bottom: 6px;
    }

    .grid-cells {
      display: grid;
      grid-template-columns: repeat(9, 22px);
      grid-template-rows: repeat(9, 22px);
      gap: 2px;
    }

    .cell {
      width: 22px;
      height: 22px;
      border-radius: 3px;
      border: 1px solid #ddd;
      box-sizing: border-box;
      font-size: 10px;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .cell.empty {
      background: #fafafa;
    }

    .cell.occupied {
      background: #cfd8dc;
    }

    .cell.path {
      background: #4caf50;
      color: #fff;
      font-weight: 700;
      border-color: #2e7d32;
    }

    .legend {
      margin-top: 10px;
      font-size: 0.85rem;
    }

    .legend span.box {
      display: inline-block;
      width: 14px;
      height: 14px;
      border-radius: 3px;
      border: 1px solid #ccc;
      margin-right: 4px;
      vertical-align: middle;
    }

    .legend .box-empty { background: #fafafa; }
    .legend .box-occupied { background: #cfd8dc; }
    .legend .box-path { background: #4caf50; border-color: #2e7d32; }

  </style>
</head>
<body>

  <h1>Traversal Logic Test – 3 Grids</h1>

  <div class="controls">
    <div>
      <label for="coord-input">Start coordinate:</label>
      <input id="coord-input" type="text" placeholder="e.g. X4Y9" />
      <button id="run-program">Run Program</button>
      <button id="new-game">New Game (randomise grids)</button>
    </div>
    <div id="status"></div>

    <div class="legend">
      <span class="box box-empty"></span> Empty &nbsp;&nbsp;
      <span class="box box-occupied"></span> Occupied &nbsp;&nbsp;
      <span class="box box-path"></span> Path chosen on each grid
    </div>
  </div>

  <div id="grids-container"></div>

  <script>
    const GRID_SIZE = 9;
    const NUM_GRIDS = 3;
    const GRID_NAMES = ["A", "B", "C"];

    let grids = [];

    // Utility: set status message
    function setStatus(message, isError = false) {
      const statusEl = document.getElementById("status");
      statusEl.innerHTML = `<span class="label">${isError ? "Status (error):" : "Status:"}</span> ${message}`;
      statusEl.style.color = isError ? "#c62828" : "#333";
    }

    // Create 3 grids, each with 50% random occupancy
    function generateGrids() {
      grids = [];
      for (let g = 0; g < NUM_GRIDS; g++) {
        const grid = [];
        for (let y = 0; y < GRID_SIZE; y++) {
          const row = [];
          for (let x = 0; x < GRID_SIZE; x++) {
            // 50% chance of being occupied
            row.push(Math.random() < 0.5);
          }
          grid.push(row);
        }
        grids.push(grid);
      }
      renderGrids(); // initial render without any path
      setStatus("New game created. Enter a start coordinate like X4Y9 and click Run Program.");
    }

    // Render the grids, optionally highlighting a path per grid
    function renderGrids(pathCoords = []) {
      const container = document.getElementById("grids-container");
      container.innerHTML = "";

      grids.forEach((grid, gridIndex) => {
        const gridDiv = document.createElement("div");
        gridDiv.className = "grid";

        const title = document.createElement("div");
        title.className = "grid-title";
        title.textContent = `Grid ${GRID_NAMES[gridIndex]}`;
        gridDiv.appendChild(title);

        const cellsWrapper = document.createElement("div");
        cellsWrapper.className = "grid-cells";

        for (let y = 1; y <= GRID_SIZE; y++) {
          for (let x = 1; x <= GRID_SIZE; x++) {
            const cell = document.createElement("div");
            cell.className = "cell";

            const occupied = grid[y - 1][x - 1];
            if (occupied) {
              cell.classList.add("occupied");
            } else {
              cell.classList.add("empty");
            }

            // Highlight path cell if present
            const inPath = pathCoords.some(
              (p) => p.gridIndex === gridIndex && p.x === x && p.y === y
            );
            if (inPath) {
              cell.classList.add("path");
              cell.textContent = "●";
            }

            cellsWrapper.appendChild(cell);
          }
        }

        gridDiv.appendChild(cellsWrapper);
        container.appendChild(gridDiv);
      });
    }

    // Traverse a single grid according to your search order:
    // 1. (X, Y)
    // 2. scan +X
    // 3. scan -X
    // 4. scan +Y
    // 5. scan -Y
    function traverseGrid(grid, startX, startY) {
      const isOccupied = (x, y) => grid[y - 1][x - 1];

      // 1. Check (X, Y)
      if (isOccupied(startX, startY)) {
        return { found: true, x: startX, y: startY };
      }

      // 2. Scan to the right (X+1 to 9)
      for (let x = startX + 1; x <= GRID_SIZE; x++) {
        if (isOccupied(x, startY)) {
          return { found: true, x, y: startY };
        }
      }

      // 3. Scan to the left (X-1 down to 1)
      for (let x = startX - 1; x >= 1; x--) {
        if (isOccupied(x, startY)) {
          return { found: true, x, y: startY };
        }
      }

      // 4. Scan down (Y+1 to 9) at fixed X
      for (let y = startY + 1; y <= GRID_SIZE; y++) {
        if (isOccupied(startX, y)) {
          return { found: true, x: startX, y };
        }
      }

      // 5. Scan up (Y-1 down to 1) at fixed X
      for (let y = startY - 1; y >= 1; y--) {
        if (isOccupied(startX, y)) {
          return { found: true, x: startX, y };
        }
      }

      // Nothing found
      return { found: false };
    }

    // Parse user input like "X4Y9"
    function parseCoordinate(input) {
      const trimmed = input.trim().toUpperCase();
      const match = trimmed.match(/^X(\d)Y(\d)$/);
      if (!match) {
        return null;
      }
      const x = parseInt(match[1], 10);
      const y = parseInt(match[2], 10);
      if (
        Number.isNaN(x) ||
        Number.isNaN(y) ||
        x < 1 ||
        x > GRID_SIZE ||
        y < 1 ||
        y > GRID_SIZE
      ) {
        return null;
      }
      return { x, y };
    }

    // Run the full 3-grid traversal
    function runProgram() {
      const inputEl = document.getElementById("coord-input");
      const coord = parseCoordinate(inputEl.value);

      if (!coord) {
        setStatus('Invalid coordinate. Use format like "X4Y9" with X and Y between 1 and 9.', true);
        return;
      }

      let { x, y } = coord;
      const path = [];

      for (let g = 0; g < NUM_GRIDS; g++) {
        const result = traverseGrid(grids[g], x, y);
        if (!result.found) {
          setStatus(
            `Traversal failed on Grid ${GRID_NAMES[g]}. No occupied cell found from start X${x}Y${y} using the search order (X,Y → +X → -X → +Y →_