Vanilla JS Robot
pure Javascript version
by Allen N.
HTML
<button id="turnLeftButton">Turn left</button>
<button id="moveForwardButton">Move forward</button>
<button id="turnRightButton">Turn right</button>
<button id="flipDirectionButton">Flip direction</button>
<div class="grid">
<div class="column">
<div class="cell"><span class="robot">U</span></div>
<div class="cell"><span class="obstacle">X</span></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
</div>
<div class="column">
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"><span class="obstacle">X</span></div>
<div class="cell"></div>
</div>
<div class="column">
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"><span class="obstacle">X</span></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
</div>
<div class="column">
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"><span class="obstacle">X</span></div>
<div class="cell"></div>
<div class="cell"></div>
</div>
<div class="column">
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"><span class="obstacle">X</span></div>
<div class="cell"></div>
<div class="cell"></div>
<div...
SCSS
.grid {
border: 2px solid black;
height: 400px;
width: 400px;
display: flex;
flex-direction: row;
.column {
display: flex;
flex-direction: column;
flex: 1;
.cell {
position: relative;
flex: 1;
border: 1px solid black;
text-align: center;
font-size: 2em;
span {
position: absolute;
left: 50%;
top: 50%;
&.robot {
transform: translate(-50%, -48%) scale(1.2);
}
&.obstacle {
transform: translate(-50%, -50%) scale(1.9);
}
}
}
}
}
JavaScript
class Robot {
constructor() {
this.x = 0; // x position in the grid
this.y = 0; // y position in the grid
this.direction = 1; // direction index (0: up, 1: right, 2: down, 3: left)
}
turnRight() {
this.direction = (this.direction + 1) % 4; // cycle through direction indices
}
turnLeft() {
this.direction = (this.direction + 3) % 4; // cycle through direction indices in reverse order
}
moveForward() {
const movements = [
[-1, 0], // up
[0, 1], // right
[1, 0], // down
[0, -1], // left
];
const [dx, dy] = movements[this.direction];
const newY = this.y + dy;
const newX = this.x + dx;
const isWithinGrid = (x, y) => x >= 0 && x < 10 && y >= 0 && y < 10;
const isNotObstacle = (x, y) => !grid[y * 10 + x].innerHTML.includes("obstacle");
if (isWithinGrid(newX, newY) && isNotObstacle(newX, newY)) {
this.x = newX;
this.y = newY;
} else {
// Temporarily turn right and check the next position in that direction
this.turnRight();
const [nextDx, nextDy] = movements[this.direction];
const nextNewY = this.y + nextDy;
const nextNewX = this.x + nextDx;
// If there's a wall or obstacle in the next position after turning right, turn left instead
if (!isWithinGrid(nextNewX, nextNewY) || !isNotObstacle(nextNewX, nextNewY)) {
this.turnLeft();
this.turnLeft();
}
}
}
flipDirection() {
this.direction = (this.direction + 2) % 4;
}
}
const robot = new Robot();
const grid = document.querySelectorAll(".grid .column .cell");
function updateGrid() {
// clear robot icon in all cells except for obstacles
grid.forEach((cell) => {
if (!cell.innerHTML.includes("obstacle")) {
cell.innerHTML = "";
}
});
// place robot icon in the current cell with the correct arrow icon
const robotCell = grid[robot.y * 10 + robot.x];
const arrowIcons = ["🔼", "▶️", "🔽", "◀️"];
robotCell.innerHTML =...