Game
<!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
<span class="box box-occupied"></span> Occupied
<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
<span class="box box-occupied"></span> Occupied
<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
<span class="box box-occupied"></span> Occupied
<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 →_