Skip to content

Instantly share code, notes, and snippets.

@cravelweb
Last active January 26, 2025 06:53
Show Gist options
  • Save cravelweb/60e3cc46b5b38e55c43fb2fd3b427b63 to your computer and use it in GitHub Desktop.
Save cravelweb/60e3cc46b5b38e55c43fb2fd3b427b63 to your computer and use it in GitHub Desktop.
Langton's ant JavaScript - ラングトンのアリ.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Langton's Ant Simulation</title>
<style>
body {
margin: 0;
display: flex;
flex-direction: column;
align-items: center;
background-color: #333;
color: #fff;
font-family: Arial, sans-serif;
}
canvas {
border: 1px solid #fff;
margin-top: 10px;
}
.controls {
display: flex;
gap: 10px;
margin: 10px 0;
}
.controls > * {
font-size: 14px;
}
</style>
</head>
<body>
<div class="controls">
<label for="antCount">Ants:</label>
<input type="number" id="antCount" value="3" min="1" max="50">
<label for="speed">Speed (ms):</label>
<input type="number" id="speed" value="50" min="1" max="1000">
<button id="start">Start</button>
<button id="stop">Stop</button>
<button id="reset">Reset</button>
</div>
<p id="generation">Generation: 0</p>
<canvas id="canvas"></canvas>
<script src="langtons-ant.js"></script>
</body>
</html>
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const generationDisplay = document.getElementById("generation");
// Canvas and grid setup
const gridSize = 201; // Increased grid dimensions for higher resolution
const cellSize = 3; // Smaller cells for higher resolution
canvas.width = gridSize * cellSize;
canvas.height = gridSize * cellSize;
let grid = Array.from({ length: gridSize }, () => Array(gridSize).fill(0));
let ants = []; // Array to store multiple ants
let generation = 0; // Generation counter
let intervalId = null; // For stopping the simulation
// Directions: 0 = up, 1 = right, 2 = down, 3 = left
const directions = [[0, -1], [1, 0], [0, 1], [-1, 0]];
// Ant class
class Ant {
constructor(x, y, direction) {
this.x = x;
this.y = y;
this.direction = direction;
}
move() {
// Toggle cell color
grid[this.y][this.x] = 1 - grid[this.y][this.x];
drawCell(this.x, this.y, grid[this.y][this.x]);
// Turn ant
this.direction = (this.direction + (grid[this.y][this.x] === 1 ? 1 : -1) + 4) % 4;
// Move forward
this.x = (this.x + directions[this.direction][0] + gridSize) % gridSize;
this.y = (this.y + directions[this.direction][1] + gridSize) % gridSize;
}
}
// Draw a single cell
function drawCell(x, y, state) {
ctx.fillStyle = state ? "#fff" : "#000";
ctx.fillRect(x * cellSize, y * cellSize, cellSize, cellSize);
}
// Initialize grid
function initGrid() {
ctx.fillStyle = "#000";
ctx.fillRect(0, 0, canvas.width, canvas.height);
for (let y = 0; y < gridSize; y++) {
for (let x = 0; x < gridSize; x++) {
drawCell(x, y, grid[y][x]);
}
}
}
// Initialize ants
function initAnts(count) {
ants = [];
for (let i = 0; i < count; i++) {
const x = Math.floor(Math.random() * gridSize);
const y = Math.floor(Math.random() * gridSize);
const direction = Math.floor(Math.random() * 4);
ants.push(new Ant(x, y, direction));
}
}
// Update function
function update() {
ants.forEach(ant => ant.move());
generation++;
generationDisplay.textContent = `Generation: ${generation}`;
}
// Start the simulation
function startSimulation() {
const antCount = parseInt(document.getElementById("antCount").value, 10);
const speed = parseInt(document.getElementById("speed").value, 10);
initGrid();
initAnts(antCount);
if (intervalId) clearInterval(intervalId);
intervalId = setInterval(update, speed);
}
// Stop the simulation
function stopSimulation() {
clearInterval(intervalId);
intervalId = null;
}
// Reset the simulation
function resetSimulation() {
stopSimulation();
grid = Array.from({ length: gridSize }, () => Array(gridSize).fill(0));
generation = 0;
generationDisplay.textContent = `Generation: ${generation}`;
initGrid();
}
// Event listeners
document.getElementById("start").addEventListener("click", startSimulation);
document.getElementById("stop").addEventListener("click", stopSimulation);
document.getElementById("reset").addEventListener("click", resetSimulation);
// Initial setup
initGrid();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment