oneshotlm
Compare all models on this prompt →

Boids flocking · qwen3-coder-flash

Create a full-screen flocking simulation of boids using separation, alignment, and cohesion, drawn as oriented triangles that steer smoothly and flee from the mouse cursor.

⚠ no runnable output

This one-shot run produced no runnable artifact.

agent produced no index.html

The transcript below shows what the model did — read it to see why the one shot fell short.

transcript · 2 messages
user

Create a full-screen flocking simulation of boids using separation, alignment, and cohesion, drawn as oriented triangles that steer smoothly and flee from the mouse cursor.

assistant

```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Boids Flocking Simulation</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { background-color: #000; overflow: hidden; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; display: flex; flex-direction: column; height: 100vh; } #canvas-container { flex: 1; position: relative; } canvas { display: block; width: 100%; height: 100%; } .info-panel { position: absolute; top: 20px; left: 20px; background-color: rgba(0, 0, 0, 0.7); color: white; padding: 15px; border-radius: 10px; max-width: 300px; backdrop-filter: blur(5px); border: 1px solid rgba(255, 255, 255, 0.1); } .info-panel h1 { font-size: 1.5rem; margin-bottom: 10px; color: #4fc3f7; } .info-panel p { font-size: 0.9rem; line-height: 1.5; margin-bottom: 10px; } .controls { position: absolute; bottom: 20px; left: 20px; background-color: rgba(0, 0, 0, 0.7); color: white; padding: 15px; border-radius: 10px; backdrop-filter: blur(5px); border: 1px solid rgba(255, 255, 255, 0.1); } .controls button { background: linear-gradient(to right, #2196F3, #21CBF3); border: none; color: white; padding: 8px 15px; margin: 5px; border-radius: 5px; cursor: pointer; font-weight: bold; transition: all 0.3s ease; } .controls button:hover { transform: translateY(-2px); box-shadow: 0 4px 8px rgba(33, 150, 243, 0.3); } .stats { position: absolute; top: 20px; right: 20px; background-color: rgba(0, 0, 0, 0.7); color: white; padding: 15px; border-radius: 10px; backdrop-filter: blur(5px); border: 1px solid rgba(255, 255, 255, 0.1); } .stats div { margin: 5px 0; font-size: 0.9rem; } .highlight { color: #4fc3f7; font-weight: bold; } </style> </head> <body> <div id="canvas-container"> <canvas id="boidCanvas"></canvas> <div class="info-panel"> <h1>Boids Flocking Simulation</h1> <p>This simulation demonstrates emergent flocking behavior based on three rules:</p> <p><span class="highlight">Separation:</span> Avoid crowding neighbors</p> <p><span class="highlight">Alignment:</span> Steer towards average heading of neighbors</p> <p><span class="highlight">Cohesion:</span> Move toward average position of neighbors</p> <p><span class="highlight">Mouse Flee:</span> Boids avoid your cursor</p> </div> <div class="stats"> <div>Boids: <span id="boidCount" class="highlight">100</span></div> <div>FPS: <span id="fpsCounter" class="highlight">0</span></div> <div>Speed: <span id="speedValue" class="highlight">1.0</span>x</div> </div> <div class="controls"> <button id="resetBtn">Reset Simulation</button> <button id="addBoidsBtn">Add 50 Boids</button> <button id="speedUpBtn">Speed Up</button> <button id="slowDownBtn">Slow Down</button> </div> </div> <script> // Canvas setup const canvas = document.getElementById('boidCanvas'); const ctx = canvas.getContext('2d'); // Set canvas to full window size function resizeCanvas() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; } window.addEventListener('resize', resizeCanvas); resizeCanvas(); // Simulation parameters const params = { numBoids: 100, maxSpeed: 3, maxForce: 0.05, perceptionRadius: 100, separationDistance: 25, separationWeight: 2.5, alignmentWeight: 1.0, cohesionWeight: 1.0, mouseFleeWeight: 3.0, mouseFleeRadius: 100, speedMultiplier: 1.0 }; // Mouse position tracking const mouse = { x: canvas.width / 2, y: canvas.height / 2, radius: 100 }; // Track FPS let frameCount = 0; let lastTime = performance.now(); let fps = 0; // Boid class class Boid { constructor() { this.position = { x: Math.random() * canvas.width, y: Math.random() * canvas.height }; // Random velocity const angle = Math.random() * Math.PI * 2; const speed = Math.random() * params.maxSpeed; this.velocity = { x: Math.cos(angle) * speed, y: Math.sin(angle) * speed }; // Store previous velocity for smooth rotation this.prevVelocity = {...this.velocity}; // Boid size and rotation this.size = 6; this.rotation = angle; } // Update boid position and velocity update(boids) { // Apply flocking behaviors const sep = this.separate(boids); const ali = this.align(boids); const coh = this.cohere(boids); const mouseFlee = this.fleeMouse(); // Weight each behavior sep.x *= params.separationWeight; sep.y *= params.separationWeight; ali.x *= params.alignmentWeight; ali.y *= params.alignmentWeight; coh.x *= params.cohesionWeight; coh.y *= params.cohesionWeight; mouseFlee.x *= params.mouseFleeWeight; mouseFlee.y *= params.mouseFleeWeight; // Apply forces this.applyForce(sep); this.applyForce(ali); this.applyForce(coh); this.applyForce(mouseFlee); // Update velocity and position this.velocity.x += (Math.random() - 0.5) * 0.1; // Small random noise this.velocity.y += (Math.random() - 0.5) * 0.1; // Limit speed const speed = Math.sqrt(this.velocity.x * this.velocity.x + this.velocity.y * this.velocity.y); if (speed > params.maxSpeed) { this.velocity.x = (this.velocity.x / speed) * params.maxSpeed; this.velocity.y = (this.velocity.y / speed) * params.maxSpeed; } // Update position this.position.x += this.velocity.x * params.speedMultiplier; this.position.y += this.velocity.y * params.speedMultiplier; // Wrap around edges if (this.position.x < 0) this.position.x = canvas.width; if (this.position.x > canvas.width) this.position.x = 0; if (this.position.y < 0) this.position.y = canvas.height; if (this.position.y > canvas.height) this.position.y = 0; // Update rotation based on velocity this.rotation = Math.atan2(this.velocity.y, this.velocity.x); // Store previous velocity for smooth animation this.prevVelocity = {...this.velocity}; } // Apply force to velocity applyForce(force) { this.velocity.x += force.x; this.velocity.y += force.y; } // Separation: steer to avoid crowding local flockmates separate(boids) { const steer = {x: 0, y: 0}; let count = 0; for (const other of boids) { const distance = this.distanceTo(other); if (distance > 0 && distance < params.separationDistance) { // Calculate vector away from neighbor const diff = { x: this.position.x - other.position.x, y: this.position.y - other.position.y }; // Normalize and weight by distance const mag = Math.sqrt(diff.x * diff.x + diff.y * diff.y); diff.x /= mag; diff.y /= mag; diff.x /= distance; // Weight by distance diff.y /= distance; steer.x += diff.x; steer.y += diff.y; count++; } } // Average and normalize if (count > 0) { steer.x /= count; steer.y /= count; const mag = Math.sqrt(steer.x * steer.x + steer.y * steer.y); if (mag > 0) { steer.x = (steer.x / mag) * params.maxSpeed; steer.y = (steer.y / mag) * params.maxSpeed; // Subtract current velocity to get steering force steer.x -= this.velocity.x; steer.y -= this.velocity.y; // Limit steering force const steerMag = Math.sqrt(steer.x * steer.x + steer.y * steer.y); if (steerMag > params.maxForce) { steer.x = (steer.x / steerMag) * params.maxForce; steer.y = (steer.y / steerMag) * params.maxForce; } } } return steer; } // Alignment: steer towards average heading of local flockmates align(boids) { const sum = {x: 0, y: 0}; let count = 0; for (const other of boids) { const distance = this.distanceTo(other); if (distance > 0 && distance < params.perceptionRadius) { sum.x += other.velocity.x; sum.y += other.velocity.y; count++; } } // Average and normalize if (count > 0) { sum.x /= count; sum.y /= count; const mag = Math.sqrt(sum.x * sum.x + sum.y * sum.y); if (mag > 0) { sum.x = (sum.x / mag) * params.maxSpeed; sum.y = (sum.y / mag) * params.maxSpeed; // Subtract current velocity to get steering force sum.x -= this.velocity.x; sum.y -= this.velocity.y; // Limit steering force const sumMag = Math.sqrt(sum.x * sum.x + sum.y * sum.y); if (sumMag > params.maxForce) { sum.x = (sum.x / sumMag) * params.maxForce; sum.y = (sum.y / sumMag) * params.maxForce; } } } return sum; } // Cohesion: steer to move toward average position of local flockmates cohere(boids) { const sum = {x: 0, y: 0}; let count = 0; for (const other of boids) { const distance = this.distanceTo(other); if (distance > 0 && distance < params.perceptionRadius) { sum.x += other.position.x; sum.y += other.position.y; count++; } } // Average position if (count > 0) { sum.x /= count; sum.y /= count; // Seek the average position return this.seek(sum); } return {x: 0, y: 0}; } // Seek a target position seek(target) { const desired = { x: target.x - this.position.x, y: target.y - this.position.y }; const mag = Math.sqrt(desired.x * desired.x + desired.y * desired.y); if (mag > 0) { desired.x = (desired.x / mag) * params.maxSpeed; desired.y = (desired.y / mag) * params.maxSpeed; // Steering force const steer = { x: desired.x - this.velocity.x, y: desired.y - this.velocity.y }; // Limit steering force const steerMag = Math.sqrt(steer.x * steer.x + steer.y * steer.y); if (steerMag > params.maxForce) { steer.x = (steer.x / steerMag) * params.maxForce; steer.y = (steer.y / steerMag) * params.maxForce; } return steer; } return {x: 0, y: 0}; } // Flee from mouse position fleeMouse() { const distance = this.distanceTo(mouse); if (distance > 0 && distance < params.mouseFleeRadius) { const desired = { x: this.position.x - mouse.x, y: this.position.y - mouse.y }; const mag = Math.sqrt(desired.x * desired.x + desired.y * desired.y); if (mag > 0) { desired.x = (desired.x / mag) * params.maxSpeed; desired.y = (desired.y / mag) * params.maxSpeed; // Steering force const steer = { x: desired.x - this.velocity.x, y: desired.y - this.velocity.y }; // Limit steering force const steerMag = Math.sqrt(steer.x * steer.x + steer.y * steer.y); if (steerMag > params.maxForce) { steer.x = (steer.x / steerMag) * params.maxForce; steer.y = (steer.y / steerMag) * params.maxForce; } return steer; } } return {x: 0, y: 0}; } // Distance to another boid distanceTo(other) { const dx = this.position.x - other.position.x; const dy = this.position.y - other.position.y; return Math.sqrt(dx * dx + dy * dy); } // Draw the boid as an oriented triangle draw() { ctx.save(); ctx.translate(this.position.x, this.position.y); ctx.rotate(this.rotation); // Draw triangle ctx.beginPath(); ctx.moveTo(this.size, 0); ctx.lineTo(-this.size, -this.size/2); ctx.lineTo(-this.size, this.size/2); ctx.closePath(); // Fill with gradient for visual appeal const gradient = ctx.createLinearGradient(-this.size, -this.size/2, this.size, 0); gradient.addColorStop(0, '#4fc3f7'); gradient.addColorStop(1, '#0288d1'); ctx.fillStyle = gradient; ctx.fill(); // Add stroke for outline ctx.strokeStyle = '#ffffff'; ctx.lineWidth = 1; ctx.stroke(); ctx.restore(); } } // Create boids let boids = []; function initBoids(count) { boids = []; for (let i = 0; i < count; i++) { boids.push(new Boid()); } document.getElementById('boidCount').textContent = count; } // Handle mouse movement canvas.addEventListener('mousemove', (e) => { const rect = canvas.getBoundingClientRect(); mouse.x = e.clientX - rect.left; mouse.y = e.clientY - rect.top; }); // Handle mouse leaving canvas canvas.addEventListener('mouseleave', () => { mouse.x = canvas.width / 2; mouse.y = canvas.height / 2; }); // Control buttons document.getElementById('resetBtn').addEventListener('click', () => { initBoids(params.numBoids); }); document.getElementById('addBoidsBtn').addEventListener('click', () => { initBoids(boids.length + 50); }); document.getElementById('speedUpBtn').addEventListener('click', () => { params.speedMultiplier = Math.min(params.speedMultiplier + 0.2, 3.0); document.getElementById('speedValue').textContent = params.speedMultiplier.toFixed(1); }); document.getElementById('slowDownBtn').addEventListener('click', () => { params.speedMultiplier = Math.max(params.speedMultiplier - 0.2, 0.2); document.getElementById('speedValue').textContent = params.speedMultiplier.toFixed(1); }); // Animation loop function animate() { // Clear canvas with a semi-transparent black for motion trails ctx.fillStyle = 'rgba(0, 0, 0, 0.1)'; ctx.fillRect(0, 0, canvas.width, canvas.height); // Update and draw boids for (const boid of boids) { boid.update(boids); boid.draw(); } // Update FPS counter frameCount++; const currentTime = performance.now(); if (currentTime - lastTime >= 1000) { fps = Math.round((frameCount * 1000) / (currentTime - lastTime)); document.getElementById('fpsCounter').textContent = fps; frameCount = 0; lastTime = currentTime; } requestAnimationFrame(animate); } // Initialize and start simulation initBoids(params.numBoids); animate(); </script> </body> </html> ```

TAKE IT TO CODE

This run produced no artifact — reuse the prompt with a different model or your own pi-agent run.

RUN

modelqwen3-coder-flash
vendorQwen
harnesspi-agent
generated2026-08-01

METRICS

runtime56.6s
tokens in128
tokens out4.2k
cached1.5k
cost / run$0.0041