hero

Claude 4 vs DeepSeek R1 vs Qwen 3

May 26, 2025

8 min read

On May 22nd, Anthropic released Claude's Sonnet 4 and Opus 4. These next-generation Claude models set new standards for coding, advanced reasoning, and AI agents. This time, Claude offers the best coding and problem-solving standards.

Claude 4 Launch

With this significant update in the world of AI, it's a perfect time to compare this new model with the ones already doing great in this space, Deepseek R1 and Qwen 3.

Deepseek has been gaining attention for its ability to handle problem-solving and show its work step by step, while Qwen 3 stands out for its strong multilingual understanding and detailed, accurate reasoning. In this blog, we'll take a closer look at what each model is good at, how they differ, and which one might be better for your needs.

TL;DR

Claude 4 and Deepseek R1 are both strong coding models, but they have different strengths. Claude 4 is great for creating realistic, production-ready code that integrates well with real-world tools. On the other hand, Deepseek R1 is excellent for open-source projects and has strong math and coding skills, but it seems more academic and less refined for practical UI or full-stack development.

  • Claude 4: Best for professional apps, realistic UIs, and full-stack workflows with smooth code and a deeper understanding.
  • Deepseek R1: Best for quick, benchmark-focused tasks and algorithmic coding, but its outputs sometimes feel basic for production apps.
  • Qwen 3: Ideal for general coding tasks, turning rough ideas into working code, and maintaining a balance between creativity and practicality.

Brief on Claude 4

Anthropic recently released Claude 4, which includes two models: Opus 4 and Sonnet 4. Both have made a strong impression on developers and AI enthusiasts.

Claude Opus 4 is their most advanced model so far, known for handling long, complex coding tasks with accuracy and precision.

Claude 4 Benchmarks

In testing, it outperformed all other models on real-world software engineering benchmarks, including SWE-bench, where it scored an impressive 72.7%. Claude Sonnet 4 also showed major improvements over the previous Sonnet 3.7, offering faster, more precise responses and better understanding of developer instructions.

But what makes Claude 4 stand out isn't just the benchmarks. It's the way both models handle real codebases. From solving multi-file issues to fixing deep architectural problems without shortcuts, Claude 4 feels like a step closer to having a true coding partner.

Here's what makes Claude 4 a true coding partner:

  • Seamless IDE integrations – Works natively with VS Code, JetBrains, and GitHub to suggest, edit, and debug code directly in your files.
  • Extended thinking with tools – Can reason for hours using web search or custom tools, executing deeper workflows without losing context.
  • Agent-ready memory system – Maintains and references long-term memory files for better continuity in multi-step agent tasks.
  • Parallel tool use – Can execute multiple tools simultaneously, improving speed and efficiency during complex operations.
  • Automated CI/CD improvements – Integrates with GitHub Actions to perform background tasks, fix CI errors, and respond to reviews.

If you're looking for an AI that truly understands code and doesn't just patch things at the surface, Claude 4 is worth a try.

Brief on DeepSeek R1

DeepSeek R1 is a standout open-source AI model from China, gaining global attention for its impressive performance and affordability. Built with a unique Mixture-of-Experts (MoE) architecture, it activates only 37 billion of its 671 billion parameters per task, ensuring efficient computation without compromising capability.

DeepSeek R1

In benchmark tests, DeepSeek R1 excels: it achieved a 97.3% accuracy on the MATH-500 benchmark, surpassing many competitors, and scored 96.3% on Codeforces, demonstrating strong coding proficiency. Its reasoning abilities are also notable, with a 90.8% score on the MMLU benchmark, closely rivaling leading models.

What sets DeepSeek R1 apart is its accessibility. Released under an open-source MIT license, it's freely available for use and modification. Additionally, its API is cost-effective, priced at approximately $0.55 per million input tokens and $2.19 per million output tokens, making advanced AI more accessible to developers and businesses alike.

DeepSeek Pricing

DeepSeek R1 is a big step in making AI more accessible, providing strong performance without the usual high costs of these models.

Brief on Qwen3

Qwen 3 is the latest generation of open-weight large language models from Alibaba, designed to deliver high performance across a wide range of tasks, including coding, math, multilingual reasoning, and agentic workflows. The flagship MoE model, Qwen3-235B-A22B, with 22B activated parameters, performs competitively with top-tier models like DeepSeek-R1, o1, o3-mini, Grok-3, and Gemini 2.5 Pro. Even its smaller variants, like Qwen3-4B, rival much larger models such as Qwen2.5-72 B.

Qwen3 Performance

Qwen 3 comes in both dense and MoE variants, all open-weighted under the Apache 2.0 license. With support for 128K context length, 119 languages and dialects, and a flexible hybrid thinking mode (step-by-step reasoning or fast response), Qwen 3 is built to be adaptable, efficient, and powerful.

Key features:

  • Expanded pretraining data: Trained on 36 trillion tokens with rich math, code, and multilingual datasets.
  • Hybrid Thinking Modes: Let users choose between deliberate reasoning and fast inference.
  • Improved Agentic Capabilities: Strengthened interaction skills and task completion logic.
  • Efficient MoE Architecture: Comparable performance to much larger dense models while using fewer active parameters.
Qwen3 Architecture

Qwen 3 is available on major platforms like Hugging Face, ModelScope, and Kaggle. It integrates smoothly with tools like Ollama, vLLM, SGLang, and LM Studio, making it easy to use in local or cloud environments.

Comparison Claude 4 vs Deepseek R1 vs Qwen3

We briefly looked at the capabilities of the Deepseek R1 and Claude Sonnet 4. Now it's time to test both of them. We'll give the same type of coding prompt to each and see how they perform.

So, let's start with the first task.

Create a Solar System using Three.js

Deepseek R1

Let's start with Deepseek R1. I am going to give this prompt:

Prompt: Create a 3D simulation of the solar system. Planets should revolve around the sun and rotate on their axes. Bonus if each planet's speed and size are somewhat realistic. In HTML, CSS, JS, and with Three JS

And, it came with this result.

Yes, it's good, but a lot of improvement is needed. Because currently it's not looking that attractive and real.

Code:

<!DOCTYPE html>
<html>
<head>
    <title>3D Solar System</title>
    <style>
        body { margin: 0; overflow: hidden; }
        canvas { display: block; }
    </style>
</head>
<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.js"></script>
    <script>
        let scene, camera, renderer, controls;

        class Planet {
            constructor(radius, distance, orbitalSpeed, rotationSpeed, color) {
                this.radius = radius;
                this.distance = distance;
                this.orbitalSpeed = orbitalSpeed;
                this.rotationSpeed = rotationSpeed;
                this.angle = Math.random() * Math.PI * 2;
                
                this.mesh = new THREE.Mesh(
                    new THREE.SphereGeometry(radius, 32, 32),
                    new THREE.MeshPhongMaterial({ color })
                );
                
                this.mesh.position.x = distance;
                scene.add(this.mesh);
            }

            update() {
                this.angle += this.orbitalSpeed;
                this.mesh.position.x = Math.cos(this.angle) * this.distance;
                this.mesh.position.z = Math.sin(this.angle) * this.distance;
                this.mesh.rotation.y += this.rotationSpeed;
            }
        }

        function init() {
            // Scene setup
            scene = new THREE.Scene();
            camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
            renderer = new THREE.WebGLRenderer();
            renderer.setSize(window.innerWidth, window.innerHeight);
            document.body.appendChild(renderer.domElement);

            // Lighting
            const ambientLight = new THREE.AmbientLight(0x404040);
            scene.add(ambientLight);
            const sunLight = new THREE.PointLight(0xffffff, 1.5);
            scene.add(sunLight);

            // Camera controls
            controls = new THREE.OrbitControls(camera, renderer.domElement);
            camera.position.z = 50;

            // Create Sun (scaled down for visualization)
            const sunGeometry = new THREE.SphereGeometry(4, 32, 32);
            const sunMaterial = new THREE.MeshBasicMaterial({ 
                color: 0xffff00,
                emissive: 0xffff00,
                emissiveIntensity: 0.5
            });
            const sun = new THREE.Mesh(sunGeometry, sunMaterial);
            scene.add(sun);

            // Create planets (relative sizes and speeds)
            // Parameters: radius, distance, orbital speed, rotation speed, color
            const planets = [
                new Planet(0.4, 8, 0.03, 0.02, 0x808080),    // Mercury
                new Planet(0.9, 11, 0.024, 0.015, 0xffd700),  // Venus
                new Planet(1.0, 15, 0.02, 0.01, 0x0000ff),     // Earth
                new Planet(0.5, 18, 0.017, 0.008, 0xff0000),  // Mars
                new Planet(2.2, 25, 0.013, 0.025, 0xffa500),  // Jupiter
                new Planet(1.8, 32, 0.009, 0.02, 0xffd700),   // Saturn
                new Planet(0.8, 37, 0.007, 0.015, 0x00ffff),  // Uranus
                new Planet(0.7, 42, 0.005, 0.015, 0x0000ff)   // Neptune
            ];

            // Animation loop
            function animate() {
                requestAnimationFrame(animate);
                planets.forEach(planet => planet.update());
                controls.update();
                renderer.render(scene, camera);
            }

            // Handle window resize
            window.addEventListener('resize', () => {
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
                renderer.setSize(window.innerWidth, window.innerHeight);
            });

            animate();
        }

        init();
    </script>
</body>
</html>

Claude Sonnet 4

I used the same prompt for Claude as well. And, it came up with this result.

This one is quite strange. It doesn't show orbits, I can't zoom in, and the planets mostly look black and too small to see clearly. So, we might need to give Qwen 3 more detailed instructions to create this 3D Solar System.

Qwen3

I used the same prompt for Qwen3 as well. And, it came up with this result.

This one is quite strange. It doesn't show orbits, I can't zoom in, and the planets mostly look black and too small to see clearly. So, we might need to give Claude 4 more detailed instructions to create this 3D Solar System.

Code:

import React, { useRef, useEffect } from 'react';
            import * as THREE from 'three';
            
            const App = () => {
              const mountRef = useRef(null);
            
              useEffect(() => {
                // Scene Setup
                const scene = new THREE.Scene();
                scene.background = new THREE.Color(0x000000);
            
                const camera = new THREE.PerspectiveCamera(
                  75,
                  window.innerWidth / window.innerHeight,
                  0.1,
                  1000
                );
                camera.position.z = 50;
            
                const renderer = new THREE.WebGLRenderer({ antialias: true });
                renderer.setSize(window.innerWidth, window.innerHeight);
                mountRef.current.appendChild(renderer.domElement);
            
                // Lighting
                const ambientLight = new THREE.AmbientLight(0x404040); // soft white light
                scene.add(ambientLight);
            
                const pointLight = new THREE.PointLight(0xffffff, 2, 100);
                pointLight.position.set(0, 0, 0);
                scene.add(pointLight);
            
                // Sun
                const sunGeometry = new THREE.SphereGeometry(5, 32, 32);
                const sunMaterial = new THREE.MeshBasicMaterial({ color: 0xffcc33 });
                const sun = new THREE.Mesh(sunGeometry, sunMaterial);
                scene.add(sun);
            
                // Planet Data (realistic relative sizes and speeds)
                const planetsData = [
                  { name: "Mercury", size: 0.38, orbit: 8.4, speed: 8.1, color: 0xadadad },
                  { name: "Venus", size: 0.95, orbit: 15.2, speed: 3.2, color: 0xffe699 },
                  { name: "Earth", size: 1.0, orbit: 21.5, speed: 2.6, color: 0x3399ff },
                  { name: "Mars", size: 0.53, orbit: 32.0, speed: 1.5, color: 0xff6600 },
                  { name: "Jupiter", size: 2.7, orbit: 112.0, speed: 0.27, color: 0xffd700 },
                  { name: "Saturn", size: 2.2, orbit: 206.0, speed: 0.09, color: 0xf5deb3 },
                  { name: "Uranus", size: 1.0, orbit: 400.0, speed: 0.03, color: 0xadd8e6 },
                  { name: "Neptune", size: 0.97, orbit: 628.0, speed: 0.015, color: 0x0000cd }
                ];
            
                const planets = [];
            
                planetsData.forEach(data => {
                  const geometry = new THREE.SphereGeometry(data.size, 32, 32);
                  const material = new THREE.MeshStandardMaterial({
                    color: data.color,
                    roughness: 0.6,
                    metalness: 0.4
                  });
                  const mesh = new THREE.Mesh(geometry, material);
                  const orbitGroup = new THREE.Group();
            
                  orbitGroup.add(mesh);
                  scene.add(orbitGroup);
            
                  // Position planet in orbit
                  const angle = Math.random() * Math.PI * 2;
                  mesh.position.x = Math.cos(angle) * data.orbit;
                  mesh.position.z = Math.sin(angle) * data.orbit;
            
                  planets.push({
                    mesh,
                    orbitGroup,
                    orbitSpeed: data.speed / 10,
                    rotationSpeed: 0.05 + Math.random() * 0.05,
                    distance: data.orbit
                  });
            
                  // Orbit ring (optional visual aid)
                  const orbitRingGeometry = new THREE.RingGeometry(data.orbit - 0.05, data.orbit + 0.05, 64);
                  const orbitRingMaterial = new THREE.MeshBasicMaterial({ color: 0xaaaaaa, side: THREE.DoubleSide });
                  const orbitRing = new THREE.Mesh(orbitRingGeometry, orbitRingMaterial);
                  orbitRing.rotation.x = Math.PI / 2;
                  scene.add(orbitRing);
                });
            
                // Animation loop
                const animate = () => {
                  requestAnimationFrame(animate);
            
                  // Rotate sun
                  sun.rotation.y += 0.005;
            
                  // Animate planets
                  planets.forEach(planet => {
                    // Orbit around the sun
                    planet.orbitGroup.rotation.y += planet.orbitSpeed * 0.01;
            
                    // Rotate on axis
                    planet.mesh.rotation.y += planet.rotationSpeed;
                  });
            
                  renderer.render(scene, camera);
                };
            
                animate();
            
                // Handle resizing
                const handleResize = () => {
                  camera.aspect = window.innerWidth / window.innerHeight;
                  camera.updateProjectionMatrix();
                  renderer.setSize(window.innerWidth, window.innerHeight);
                };
            
                window.addEventListener('resize', handleResize);
            
                return () => {
                  window.removeEventListener('resize', handleResize);
                  mountRef.current.removeChild(renderer.domElement);
                };
              }, []);
            
              return <div ref={mountRef} style={{ width: '100%', height: '100vh' }} />;
            };
            
            export default App;

Create a Fashion Website using GSAP

The first task is complete, so let's move on to the next one. We'll start with Claude 4. I used this prompt:

Prompt: Use html css and js and create a fashion website clothing website. Use creative GSAP Animation and make sure the site must be responsive. There will be a landing page with all functionality of add to card and buy and each and everything must be creatively animated using GSAP. Must have option to search product view product different category and view, moving, and going through one page to another must be a animated using GSAP. Animation must be smooth and silky. Also add smooth like buttery scroll animation.

And, Claude 4 comes up with this result.

It created a website with GSAP animation and features for adding items to the cart and checking out. However, it didn't add the images, but it included all the functionality I mentioned. It added features for checkout, adding to cart, adding to favorites, and a search option. Although the site isn't very responsive and uses emojis instead of icons.

The rest is good.

Qwen 3

I've used the same prompt with Qwen 3 as well, and this is what it came up with:

The site looks pretty decent. It has products, search functionality, and some images. But, it didn't add most of the functionalities like Claude did, and it doesn't include GSAP animations. Overall, it needs a lot of improvements.

Deepseek R1

With the same prompt, I tried Deepseek R1, and this is what it came up with:

This result really amazed me. I wasn't expecting this much, but it turned out to be a fabulous fashion website. It uses proper icons, smooth and buttery GSAP animations, and appropriate images by default. The site is fully responsive, and it added a beautiful logo loading animation. Overall, it won me over completely. It's a clear winner in this case.

The only thing it didn't do was the functionality. It didn't add features for checkout, add to cart, or search. So, while the UI works well, it might need a few more prompts to complete the functionality.

Bullet Dodge Game

Now, let's do one more test with a new prompt. This time, I am going to use this prompt:

Prompt: Make a bullet dodging game (top-down view) using HTML Canvas. The player is a small character that can move in all directions. Bullets shoot from all sides in patterns. The player must avoid being hit for as long as possible. Add increasing difficulty over time.

Qwen 3

Let's submit this prompt for Qwen 3 first. And it came up with this result:

It created the game, but when I played, I couldn't move at all. If you watch the video closely, you'll notice I'm trying to move the green ball, but it stays stuck in a specific circular area. So, it didn't work well. Let's check the next ones.

Code:

import React, { useRef, useEffect, useState } from 'react';

const App = () => {
  const canvasRef = useRef(null);
  const [gameState, setGameState] = useState('menu');
  const [score, setScore] = useState(0);
  const [highScore, setHighScore] = useState(0);
  const [level, setLevel] = useState(1);

  const gameLoopRef = useRef(null);
  const keys = useRef({ up: false, down: false, left: false, right: false });

  // Game constants
  const PLAYER_RADIUS = 10;
  const BULLET_RADIUS = 6;
  const PLAYER_SPEED = 4;
  const INITIAL_BULLET_INTERVAL = 1200; // ms
  const MIN_BULLET_INTERVAL = 300;

  const bullets = useRef([]);
  const lastBulletTime = useRef(0);
  const startTime = useRef(0);
  const lastUpdateTime = useRef(0);

  const resetGame = () => {
    bullets.current = [];
    lastBulletTime.current = 0;
    startTime.current = Date.now();
    lastUpdateTime.current = Date.now();
    setScore(0);
    setLevel(1);
    setGameState('playing');
  };

  const spawnBullet = (canvasWidth, canvasHeight) => {
    const side = Math.floor(Math.random() * 4); // 0: top, 1: right, 2: bottom, 3: left
    let x, y, vx, vy;

    switch (side) {
      case 0: // top
        x = Math.random() * canvasWidth;
        y = -BULLET_RADIUS;
        break;
      case 1: // right
        x = canvasWidth + BULLET_RADIUS;
        y = Math.random() * canvasHeight;
        break;
      case 2: // bottom
        x = Math.random() * canvasWidth;
        y = canvasHeight + BULLET_RADIUS;
        break;
      case 3: // left
        x = -BULLET_RADIUS;
        y = Math.random() * canvasHeight;
        break;
    }

    // Aim toward the center of the canvas
    const angle = Math.atan2(canvasHeight / 2 - y, canvasWidth / 2 - x);
    vx = Math.cos(angle) * 3;
    vy = Math.sin(angle) * 3;

    bullets.current.push({ x, y, vx, vy });
  };

  const checkCollision = (x1, y1, r1, x2, y2, r2) => {
    const dx = x1 - x2;
    const dy = y1 - y2;
    return dx * dx + dy * dy <= (r1 + r2) ** 2;
  };

  const update = (playerX, playerY, canvasWidth, canvasHeight, deltaTime) => {
    // Update bullets
    for (const bullet of bullets.current) {
      bullet.x += bullet.vx;
      bullet.y += bullet.vy;
    }

    // Remove off-screen bullets
    bullets.current = bullets.current.filter(bullet => 
      bullet.x >= -BULLET_RADIUS && 
      bullet.x <= canvasWidth + BULLET_RADIUS &&
      bullet.y >= -BULLET_RADIUS &&
      bullet.y <= canvasHeight + BULLET_RADIUS
    );

    // Check collision with player
    for (const bullet of bullets.current) {
      if (checkCollision(playerX, playerY, PLAYER_RADIUS, bullet.x, bullet.y, BULLET_RADIUS)) {
        endGame();
        return;
      }
    }

    // Update score and level
    const currentElapsedTime = Date.now() - startTime.current;
    const newScore = Math.floor(currentElapsedTime / 1000);
    if (newScore !== score) {
      setScore(newScore);
      
      // Increase difficulty every 10 seconds
      if (newScore % 10 === 0) {
        const newLevel = Math.min(5, Math.floor(newScore / 10) + 1);
        if (newLevel > level) {
          setLevel(newLevel);
        }
      }
    }
  };

  const endGame = () => {
    setGameState('gameOver');
    if (score > highScore) {
      setHighScore(score);
    }
    
    // Reset for next game
    cancelAnimationFrame(gameLoopRef.current);
  };

  const draw = (ctx, canvasWidth, canvasHeight, playerX, playerY) => {
    // Clear canvas
    ctx.fillStyle = '#1a1a1a';
    ctx.fillRect(0, 0, canvasWidth, canvasHeight);

    // Draw player
    ctx.beginPath();
    ctx.arc(playerX, playerY, PLAYER_RADIUS, 0, Math.PI * 2);
    ctx.fillStyle = '#4ade80';
    ctx.fill();

    // Draw bullets
    for (const bullet of bullets.current) {
      ctx.beginPath();
      ctx.arc(bullet.x, bullet.y, BULLET_RADIUS, 0, Math.PI * 2);
      ctx.fillStyle = '#ef4444';
      ctx.fill();
    }

    // Draw HUD
    ctx.fillStyle = '#ffffff';
    ctx.font = '16px sans-serif';
    ctx.fillText(`Score: ${score}`, 10, 25);
    ctx.fillText(`Level: ${level}`, 10, 50);
    ctx.fillText(`High Score: ${highScore}`, 10, 75);
  };

  const gameLoop = () => {
    const canvas = canvasRef.current;
    const ctx = canvas.getContext('2d');
    const canvasWidth = canvas.width;
    const canvasHeight = canvas.height;

    const currentTime = Date.now();
    const deltaTime = currentTime - lastUpdateTime.current;
    lastUpdateTime.current = currentTime;

    // Calculate player position based on keys
    let playerX = canvasWidth / 2;
    let playerY = canvasHeight / 2;

    if (keys.current.up) playerY -= PLAYER_SPEED;
    if (keys.current.down) playerY += PLAYER_SPEED;
    if (keys.current.left) playerX -= PLAYER_SPEED;
    if (keys.current.right) playerX += PLAYER_SPEED;

    // Keep player within bounds
    playerX = Math.max(PLAYER_RADIUS, Math.min(canvasWidth - PLAYER_RADIUS, playerX));
    playerY = Math.max(PLAYER_RADIUS, Math.min(canvasHeight - PLAYER_RADIUS, playerY));

    // Spawn bullets based on level and timing
    const currentInterval = Math.max(MIN_BULLET_INTERVAL, INITIAL_BULLET_INTERVAL - (level - 1) * 200);
    if (currentTime - lastBulletTime.current > currentInterval) {
      spawnBullet(canvasWidth, canvasHeight);
      lastBulletTime.current = currentTime;
    }

    // Update game state
    update(playerX, playerY, canvasWidth, canvasHeight, deltaTime);

    // Draw everything
    draw(ctx, canvasWidth, canvasHeight, playerX, playerY);

    if (gameState === 'playing') {
      gameLoopRef.current = requestAnimationFrame(gameLoop);
    }
  };

  // Event handlers
  useEffect(() => {
    const handleKeyDown = (e) => {
      switch (e.key.toLowerCase()) {
        case 'w':
        case 'arrowup':
          keys.current.up = true;
          break;
        case 's':
        case 'arrowdown':
          keys.current.down = true;
          break;
        case 'a':
        case 'arrowleft':
          keys.current.left = true;
          break;
        case 'd':
        case 'arrowright':
          keys.current.right = true;
          break;
      }
    };

    const handleKeyUp = (e) => {
      switch (e.key.toLowerCase()) {
        case 'w':
        case 'arrowup':
          keys.current.up = false;
          break;
        case 's':
        case 'arrowdown':
          keys.current.down = false;
          break;
        case 'a':
        case 'arrowleft':
          keys.current.left = false;
          break;
        case 'd':
        case 'arrowright':
          keys.current.right = false;
          break;
      }
    };

    window.addEventListener('keydown', handleKeyDown);
    window.addEventListener('keyup', handleKeyUp);

    return () => {
      window.removeEventListener('keydown', handleKeyDown);
      window.removeEventListener('keyup', handleKeyUp);
    };
  }, []);

  // Resize canvas to fit window
  useEffect(() => {
    const resizeCanvas = () => {
      const canvas = canvasRef.current;
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
    };

    resizeCanvas();
    window.addEventListener('resize', resizeCanvas);
    return () => window.removeEventListener('resize', resizeCanvas);
  }, []);

  // Start game loop when playing
  useEffect(() => {
    if (gameState === 'playing') {
      lastUpdateTime.current = Date.now();
      startTime.current = Date.now();
      gameLoopRef.current = requestAnimationFrame(gameLoop);
    }

    return () => {
      if (gameLoopRef.current) {
        cancelAnimationFrame(gameLoopRef.current);
      }
    };
  }, [gameState]);

  return (
    <div className="relative w-full h-full">
      <canvas ref={canvasRef} className="fixed inset-0" tabIndex="0" />

      {/* Menu Screen */}
      {gameState === 'menu' && (
        <div className="absolute inset-0 flex flex-col items-center justify-center bg-black bg-opacity-70 text-white p-4">
          <h1 className="text-4xl md:text-6xl font-bold mb-6 text-center">Bullet Dodger</h1>
          <p className="text-xl md:text-2xl mb-8 text-center max-w-md">
            Avoid the bullets for as long as you can! Use arrow keys or WASD to move.
          </p>
          <button 
            onClick={resetGame}
            className="px-8 py-3 bg-green-500 hover:bg-green-600 rounded-lg text-xl font-semibold transition-colors"
          >
            Start Game
          </button>
        </div>
      )}

      {/* Game Over Screen */}
      {gameState === 'gameOver' && (
        <div className="absolute inset-0 flex flex-col items-center justify-center bg-black bg-opacity-70 text-white p-4">
          <h2 className="text-4xl md:text-6xl font-bold mb-4">Game Over</h2>
          <p className="text-2xl md:text-3xl mb-2">Score: {score}</p>
          <p className="text-xl mb-6">High Score: {highScore}</p>
          <button 
            onClick={resetGame}
            className="px-8 py-3 bg-blue-500 hover:bg-blue-600 rounded-lg text-xl font-semibold transition-colors"
          >
            Play Again
          </button>
        </div>
      )}
    </div>
  );
};

export default App;

Deepseek R1

Let's submit this prompt for Deepseek R1. And it came up with this result:

This looks good. The Neon UI is nice, and the movement of the player and enemies is smooth. If you watch the video closely, you can see that when I move the player, it leaves traces behind, so I know where I started and how much area I've covered. The difficulty increases automatically based on how long I survive. Overall, I really liked this one.

Code:

<!DOCTYPE html>
<html>
<head>
    <title>Neon Bullet Dodge</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            background: #0a0a1a;
            color: white;
            font-family: 'Audiowide', cursive;
            overflow: hidden;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 100vh;
        }

        #game-container {
            position: relative;
            box-shadow: 0 0 30px #00f7ff;
            border-radius: 10px;
            overflow: hidden;
        }

        canvas {
            display: block;
            background: #121230;
        }

        #ui {
            position: absolute;
            top: 20px;
            left: 0;
            width: 100%;
            display: flex;
            justify-content: space-between;
            padding: 0 30px;
            box-sizing: border-box;
            pointer-events: none;
        }

        #score, #time {
            font-size: 24px;
            text-shadow: 0 0 10px #00f7ff;
            background: rgba(0, 10, 20, 0.7);
            padding: 5px 15px;
            border-radius: 20px;
            border: 1px solid #00f7ff;
        }

        #game-over {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.8);
            display: none;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            z-index: 10;
        }

        #game-over h1 {
            font-size: 48px;
            color: #ff3366;
            text-shadow: 0 0 15px #ff0066;
            margin-bottom: 20px;
        }

        #final-score {
            font-size: 32px;
            margin-bottom: 30px;
            color: #00f7ff;
        }

        button {
            background: linear-gradient(45deg, #0066ff, #00f7ff);
            border: none;
            color: white;
            padding: 15px 40px;
            font-size: 18px;
            border-radius: 30px;
            cursor: pointer;
            font-family: 'Audiowide', cursive;
            transition: all 0.3s;
            box-shadow: 0 0 15px #00f7ff;
        }

        button:hover {
            transform: scale(1.05);
            box-shadow: 0 0 25px #00f7ff;
        }

        #controls {
            position: absolute;
            bottom: 30px;
            color: rgba(255, 255, 255, 0.7);
            font-size: 14px;
        }

        .particle {
            position: absolute;
            border-radius: 50%;
            pointer-events: none;
        }
    </style>
    <link href="https://fonts.googleapis.com/css2?family=Audiowide&display=swap" rel="stylesheet">
</head>
<body>
    <div id="game-container">
        <canvas id="gameCanvas" width="800" height="600"></canvas>
        
        <div id="ui">
            <div id="score">Score: 0</div>
            <div id="time">Time: 0s</div>
        </div>
        
        <div id="game-over">
            <h1>GAME OVER</h1>
            <div id="final-score">Score: 0</div>
            <button id="restart">PLAY AGAIN</button>
        </div>
        
        <div id="controls">WASD or Arrow Keys to Move</div>
    </div>

    <script>
        // Game Configuration
        const config = {
            player: {
                radius: 12,
                speed: 6,
                color: '#00f7ff',
                trailLength: 15
            },
            bullets: {
                baseSpeed: 2,
                speedIncrease: 0.002,
                maxSpeed: 8,
                spawnRate: 60, // frames
                spawnRateDecrease: 0.5,
                minSpawnRate: 20,
                colors: ['#ff3366', '#ff9900', '#ff00ff', '#00ff99']
            },
            difficulty: {
                increaseInterval: 300, // frames
                bulletCountIncrease: 0.2,
                maxBulletCount: 5
            }
        };

        // Game Elements
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const scoreElement = document.getElementById('score');
        const timeElement = document.getElementById('time');
        const gameOverScreen = document.getElementById('game-over');
        const finalScoreElement = document.getElementById('final-score');
        const restartButton = document.getElementById('restart');

        // Game State
        let player = {
            x: 400,
            y: 300,
            trail: []
        };
        let bullets = [];
        let keys = {};
        let score = 0;
        let gameTime = 0;
        let isGameActive = false;
        let animationFrameId;
        let spawnCounter = 0;
        let difficultyLevel = 1;

        // Initialize
        function init() {
            // Event Listeners
            document.addEventListener('keydown', e => keys[e.key.toLowerCase()] = true);
            document.addEventListener('keyup', e => keys[e.key.toLowerCase()] = false);
            restartButton.addEventListener('click', startGame);
            
            // Start the game
            startGame();
        }

        function startGame() {
            // Reset game state
            player = {
                x: 400,
                y: 300,
                trail: []
            };
            bullets = [];
            score = 0;
            gameTime = 0;
            spawnCounter = 0;
            difficultyLevel = 1;
            isGameActive = true;
            
            // Update UI
            scoreElement.textContent = `Score: ${score}`;
            timeElement.textContent = `Time: 0s`;
            gameOverScreen.style.display = 'none';
            
            // Start game loop
            if (animationFrameId) cancelAnimationFrame(animationFrameId);
            gameLoop();
        }

        function spawnBullet() {
            const side = Math.floor(Math.random() * 4);
            let x, y, angle;
            
            // Random spawn position on edges
            switch(side) {
                case 0: // Top
                    x = Math.random() * canvas.width;
                    y = -10;
                    angle = Math.PI/2 + (Math.random() - 0.5) * Math.PI/1.5;
                    break;
                case 1: // Right
                    x = canvas.width + 10;
                    y = Math.random() * canvas.height;
                    angle = Math.PI + (Math.random() - 0.5) * Math.PI/1.5;
                    break;
                case 2: // Bottom
                    x = Math.random() * canvas.width;
                    y = canvas.height + 10;
                    angle = -Math.PI/2 + (Math.random() - 0.5) * Math.PI/1.5;
                    break;
                case 3: // Left
                    x = -10;
                    y = Math.random() * canvas.height;
                    angle = 0 + (Math.random() - 0.5) * Math.PI/1.5;
                    break;
            }

            const speed = Math.min(
                config.bullets.baseSpeed + (gameTime * config.bullets.speedIncrease),
                config.bullets.maxSpeed
            );
            
            const color = config.bullets.colors[
                Math.floor(Math.random() * config.bullets.colors.length)
            ];
            
            bullets.push({
                x, y,
                radius: 6,
                speed: speed,
                color: color,
                angle: angle,
                glow: 0
            });
        }

        function updatePlayer() {
            // Movement
            const moveX = (keys.arrowright || keys.d ? 1 : 0) - (keys.arrowleft || keys.a ? 1 : 0);
            const moveY = (keys.arrowdown || keys.s ? 1 : 0) - (keys.arrowup || keys.w ? 1 : 0);
            
            // Normalize diagonal movement
            if (moveX !== 0 && moveY !== 0) {
                player.x += moveX * config.player.speed * 0.707; // 1/sqrt(2)
                player.y += moveY * config.player.speed * 0.707;
            } else {
                player.x += moveX * config.player.speed;
                player.y += moveY * config.player.speed;
            }

            // Keep player in bounds
            player.x = Math.max(config.player.radius, Math.min(canvas.width - config.player.radius, player.x));
            player.y = Math.max(config.player.radius, Math.min(canvas.height - config.player.radius, player.y));
            
            // Update trail
            player.trail.unshift({x: player.x, y: player.y});
            if (player.trail.length > config.player.trailLength) {
                player.trail.pop();
            }
        }

        function updateBullets() {
            bullets.forEach((bullet, index) => {
                // Update position
                bullet.x += Math.cos(bullet.angle) * bullet.speed;
                bullet.y += Math.sin(bullet.angle) * bullet.speed;
                
                // Update glow effect
                bullet.glow = (bullet.glow + 0.05) % (Math.PI * 2);

                // Remove off-screen bullets
                if (bullet.x < -50 || bullet.x > canvas.width + 50 || 
                    bullet.y < -50 || bullet.y > canvas.height + 50) {
                    bullets.splice(index, 1);
                }

                // Collision detection
                const dx = player.x - bullet.x;
                const dy = player.y - bullet.y;
                const distance = Math.sqrt(dx * dx + dy * dy);

                if (distance < config.player.radius + bullet.radius) {
                    gameOver();
                    createExplosion(player.x, player.y, bullet.color);
                }
            });
        }

        function increaseDifficulty() {
            gameTime++;
            
            // Update score and time display
            score = Math.floor(gameTime / 1000);
            level = Math.floor(gameTime / 10000) + 1;
            
            // Increase difficulty periodically
            if (gameTime % config.difficulty.increaseInterval === 0) {
                difficultyLevel += 1;
                const newSpawnRate = Math.max(
                    config.bullets.minSpawnRate,
                    config.bullets.spawnRate - (difficultyLevel * config.bullets.spawnRateDecrease)
                );
                
                // Spawn more bullets
                const bulletsToSpawn = Math.min(
                    Math.floor(difficultyLevel * config.difficulty.bulletCountIncrease),
                    config.difficulty.maxBulletCount
                );
                
                for (let i = 0; i < bulletsToSpawn; i++) {
                    setTimeout(spawnBullet, i * 100);
                }
            }
        }

        function gameOver() {
            isGameActive = false;
            finalScoreElement.textContent = `Score: ${score}`;
            gameOverScreen.style.display = 'flex';
            cancelAnimationFrame(animationFrameId);
        }

        function createExplosion(x, y, color) {
            const particleCount = 30;
            for (let i = 0; i < particleCount; i++) {
                const particle = document.createElement('div');
                particle.className = 'particle';
                
                const size = Math.random() * 10 + 5;
                const angle = Math.random() * Math.PI * 2;
                const speed = Math.random() * 5 + 2;
                const lifetime = Math.random() * 1000 + 500;
                
                particle.style.width = `${size}px`;
                particle.style.height = `${size}px`;
                particle.style.background = color;
                particle.style.left = `${x}px`;
                particle.style.top = `${y}px`;
                
                document.getElementById('game-container').appendChild(particle);
                
                const startTime = Date.now();
                
                function updateParticle() {
                    const elapsed = Date.now() - startTime;
                    const progress = elapsed / lifetime;
                    
                    if (progress >= 1) {
                        particle.remove();
                        return;
                    }
                    
                    const currentX = x + Math.cos(angle) * speed * progress * 100;
                    const currentY = y + Math.sin(angle) * speed * progress * 100;
                    const currentOpacity = 1 - progress;
                    const currentSize = size * (1 - progress);
                    
                    particle.style.transform = `translate(${currentX - x}px, ${currentY - y}px)`;
                    particle.style.opacity = currentOpacity;
                    particle.style.width = `${currentSize}px`;
                    particle.style.height = `${currentSize}px`;
                    
                    requestAnimationFrame(updateParticle);
                }
                
                requestAnimationFrame(updateParticle);
            }
        }

        function drawPlayer() {
            // Draw trail
            ctx.globalAlpha = 0.3;
            player.trail.forEach((pos, i) => {
                const alpha = i / player.trail.length;
                const radius = config.player.radius * alpha;
                
                ctx.beginPath();
                ctx.arc(pos.x, pos.y, radius, 0, Math.PI * 2);
                ctx.fillStyle = config.player.color;
                ctx.fill();
            });
            ctx.globalAlpha = 1;
            
            // Draw player
            ctx.beginPath();
            ctx.arc(player.x, player.y, config.player.radius, 0, Math.PI * 2);
            ctx.fillStyle = config.player.color;
            ctx.shadowBlur = 15;
            ctx.shadowColor = config.player.color;
            ctx.fill();
            ctx.shadowBlur = 0;
            
            // Inner glow
            ctx.beginPath();
            ctx.arc(player.x, player.y, config.player.radius * 0.6, 0, Math.PI * 2);
            ctx.fillStyle = 'white';
            ctx.fill();
        }

        function drawBullets() {
            bullets.forEach(bullet => {
                // Glow effect
                const glowIntensity = Math.abs(Math.sin(bullet.glow)) * 0.5 + 0.5;
                
                ctx.beginPath();
                ctx.arc(bullet.x, bullet.y, bullet.radius * 1.5, 0, Math.PI * 2);
                ctx.fillStyle = `${bullet.color}${Math.floor(glowIntensity * 30).toString(16).padStart(2, '0')}`;
                ctx.fill();
                
                // Bullet core
                ctx.beginPath();
                ctx.arc(bullet.x, bullet.y, bullet.radius, 0, Math.PI * 2);
                ctx.fillStyle = bullet.color;
                ctx.shadowBlur = 10;
                ctx.shadowColor = bullet.color;
                ctx.fill();
                ctx.shadowBlur = 0;
                
                // Bullet center
                ctx.beginPath();
                ctx.arc(bullet.x, bullet.y, bullet.radius * 0.5, 0, Math.PI * 2);
                ctx.fillStyle = 'white';
                ctx.fill();
            });
        }

        function gameLoop() {
            if (!isGameActive) return;
            
            // Clear canvas with fade effect
            ctx.fillStyle = 'rgba(18, 18, 48, 0.2)';
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            
            // Spawn bullets
            spawnCounter++;
            const currentSpawnRate = Math.max(
                config.bullets.minSpawnRate,
                config.bullets.spawnRate - (difficultyLevel * config.bullets.spawnRateDecrease)
            );
            
            if (spawnCounter >= currentSpawnRate) {
                spawnBullet();
                spawnCounter = 0;
            }
            
            // Update game state
            updatePlayer();
            updateBullets();
            increaseDifficulty();
            
            // Draw game elements
            drawBullets();
            drawPlayer();
            
            // Continue game loop
            animationFrameId = requestAnimationFrame(gameLoop);
        }

        // Start the game when page loads
        window.addEventListener('load', init);
    </script>
</body>
</html>

Claude 4

I submitted the same prompt to Claude 4, and it came up with this result.

Now, Claude 4's results are also similar to Deepseek R1. It features a Neon theme, dynamic difficulty, displays the current level, and has a great UI. As for the code, Claude 4 wrote very good and clean code. It properly set the variables and divided the code into separate, easy-to-understand short functions.

In this case, it's too close to decide which one did better between Claude 4 and Deepseek R1 because both did a fantastic job creating this Dodgeball Game. Qwen 3 lagged a bit in this case.

Code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Bullet Dodging Game</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            background: #0a0a0a;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            font-family: 'Courier New', monospace;
            color: #fff;
        }
        
        #gameContainer {
            text-align: center;
            background: #111;
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0 0 30px rgba(0, 255, 255, 0.3);
        }
        
        #gameCanvas {
            border: 2px solid #00ffff;
            background: #000;
            box-shadow: 0 0 20px rgba(0, 255, 255, 0.5);
        }
        
        #gameInfo {
            margin-top: 15px;
            display: flex;
            justify-content: space-between;
            font-size: 18px;
            color: #00ffff;
        }
        
        #instructions {
            margin-top: 10px;
            font-size: 14px;
            color: #aaa;
        }
        
        #gameOver {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: rgba(0, 0, 0, 0.9);
            padding: 30px;
            border-radius: 10px;
            border: 2px solid #ff4444;
            display: none;
            text-align: center;
        }
        
        #restartBtn {
            background: #00ffff;
            color: #000;
            border: none;
            padding: 10px 20px;
            font-size: 16px;
            cursor: pointer;
            border-radius: 5px;
            margin-top: 15px;
            font-family: 'Courier New', monospace;
            font-weight: bold;
        }
        
        #restartBtn:hover {
            background: #44ffff;
        }
    </style>
</head>
<body>
    <div id="gameContainer">
        <canvas id="gameCanvas" width="800" height="600"></canvas>
        <div id="gameInfo">
            <div>Time: <span id="timeDisplay">0.0s</span></div>
            <div>Level: <span id="levelDisplay">1</span></div>
            <div>Score: <span id="scoreDisplay">0</span></div>
        </div>
        <div id="instructions">
            Use WASD or Arrow Keys to move • Avoid all bullets • Survive as long as possible!
        </div>
        
        <div id="gameOver">
            <h2 style="color: #ff4444; margin-top: 0;">GAME OVER</h2>
            <p>Final Time: <span id="finalTime"></span></p>
            <p>Final Score: <span id="finalScore"></span></p>
            <button id="restartBtn">Play Again</button>
        </div>
    </div>

    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const gameOverScreen = document.getElementById('gameOver');
        
        // Game state
        let gameRunning = false;
        let gameTime = 0;
        let score = 0;
        let level = 1;
        let lastTime = 0;
        
        // Player
        const player = {
            x: canvas.width / 2,
            y: canvas.height / 2,
            size: 8,
            speed: 4,
            color: '#00ff00'
        };
        
        // Input handling
        const keys = {};
        
        // Bullets array
        let bullets = [];
        let nextBulletSpawn = 0;
        
        // Event listeners
        document.addEventListener('keydown', (e) => {
            keys[e.code] = true;
        });
        
        document.addEventListener('keyup', (e) => {
            keys[e.code] = false;
        });
        
        document.getElementById('restartBtn').addEventListener('click', startGame);
        
        function startGame() {
            gameRunning = true;
            gameTime = 0;
            score = 0;
            level = 1;
            
            player.x = canvas.width / 2;
            player.y = canvas.height / 2;
            
            bullets = [];
            nextBulletSpawn = 0;
            
            gameOverScreen.style.display = 'none';
            
            gameLoop();
        }
        
        function updatePlayer(deltaTime) {
            // Movement
            let dx = 0, dy = 0;
            
            if (keys['KeyA'] || keys['ArrowLeft']) dx -= player.speed;
            if (keys['KeyD'] || keys['ArrowRight']) dx += player.speed;
            if (keys['KeyW'] || keys['ArrowUp']) dy -= player.speed;
            if (keys['KeyS'] || keys['ArrowDown']) dy += player.speed;
            
            // Normalize diagonal movement
            if (dx !== 0 && dy !== 0) {
                dx *= 0.707;
                dy *= 0.707;
            }
            
            // Update position with bounds checking
            player.x = Math.max(player.size, Math.min(canvas.width - player.size, player.x + dx));
            player.y = Math.max(player.size, Math.min(canvas.height - player.size, player.y + dy));
        }
        
        function spawnBullets(deltaTime) {
            // Decrease spawn interval as difficulty increases
            const baseSpawnInterval = Math.max(200, 800 - level * 80); // milliseconds
            const spawnInterval = baseSpawnInterval + Math.random() * 400; // Add randomness
            
            if (gameTime >= nextBulletSpawn) {
                nextBulletSpawn = gameTime + spawnInterval;
                
                // Number of bullets to spawn (increases with level)
                const bulletsToSpawn = Math.min(1 + Math.floor(level / 3), 5);
                
                for (let i = 0; i < bulletsToSpawn; i++) {
                    // Choose random side of screen
                    const side = Math.floor(Math.random() * 4);
                    let startX, startY, targetX, targetY;
                    
                    switch (side) {
                        case 0: // Top
                            startX = Math.random() * canvas.width;
                            startY = -10;
                            break;
                        case 1: // Right
                            startX = canvas.width + 10;
                            startY = Math.random() * canvas.height;
                            break;
                        case 2: // Bottom
                            startX = Math.random() * canvas.width;
                            startY = canvas.height + 10;
                            break;
                        case 3: // Left
                            startX = -10;
                            startY = Math.random() * canvas.height;
                            break;
                    }
                    
                    // Target can be anywhere on screen, with bias toward player
                    const playerBias = 0.7; // 70% chance to aim toward player area
                    if (Math.random() < playerBias) {
                        // Aim toward player area with some randomness
                        const randomRadius = 150;
                        targetX = player.x + (Math.random() - 0.5) * randomRadius;
                        targetY = player.y + (Math.random() - 0.5) * randomRadius;
                    } else {
                        // Completely random target
                        targetX = Math.random() * canvas.width;
                        targetY = Math.random() * canvas.height;
                    }
                    
                    // Calculate direction
                    const dx = targetX - startX;
                    const dy = targetY - startY;
                    const distance = Math.sqrt(dx * dx + dy * dy);
                    
                    // Random speed with level scaling
                    const speed = 1.5 + Math.random() * 2 + level * 0.2;
                    
                    bullets.push({
                        x: startX,
                        y: startY,
                        vx: (dx / distance) * speed,
                        vy: (dy / distance) * speed,
                        size: 2 + Math.random() * 3, // Random bullet sizes
                        color: `hsl(${Math.random() * 360}, 80%, 60%)`, // Random colors
                        life: 0 // For potential fade effects
                    });
                }
            }
        }
        
        function updateBullets(deltaTime) {
            for (let i = bullets.length - 1; i >= 0; i--) {
                const bullet = bullets[i];
                
                bullet.x += bullet.vx;
                bullet.y += bullet.vy;
                bullet.life += deltaTime;
                
                // Remove bullets that are off screen or too old
                if (bullet.x < -100 || bullet.x > canvas.width + 100 || 
                    bullet.y < -100 || bullet.y > canvas.height + 100 ||
                    bullet.life > 15000) { // Remove after 15 seconds
                    bullets.splice(i, 1);
                }
            }
        }
        
        function checkCollisions() {
            for (const bullet of bullets) {
                const dx = player.x - bullet.x;
                const dy = player.y - bullet.y;
                const distance = Math.sqrt(dx * dx + dy * dy);
                
                if (distance < player.size + bullet.size) {
                    endGame();
                    return;
                }
            }
        }
        
        function updateGameState(deltaTime) {
            gameTime += deltaTime;
            score = Math.floor(gameTime / 10);
            level = Math.floor(gameTime / 10000) + 1;
            
            // Update display
            document.getElementById('timeDisplay').textContent = (gameTime / 1000).toFixed(1) + 's';
            document.getElementById('levelDisplay').textContent = level;
            document.getElementById('scoreDisplay').textContent = score;
        }
        
        function render() {
            // Clear canvas with fade effect
            ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            
            // Draw player
            ctx.fillStyle = player.color;
            ctx.beginPath();
            ctx.arc(player.x, player.y, player.size, 0, Math.PI * 2);
            ctx.fill();
            
            // Draw player glow
            ctx.shadowBlur = 20;
            ctx.shadowColor = player.color;
            ctx.beginPath();
            ctx.arc(player.x, player.y, player.size, 0, Math.PI * 2);
            ctx.fill();
            ctx.shadowBlur = 0;
            
            // Draw bullets
            bullets.forEach(bullet => {
                ctx.fillStyle = bullet.color;
                ctx.beginPath();
                ctx.arc(bullet.x, bullet.y, bullet.size, 0, Math.PI * 2);
                ctx.fill();
                
                // Bullet glow
                ctx.shadowBlur = 10;
                ctx.shadowColor = bullet.color;
                ctx.beginPath();
                ctx.arc(bullet.x, bullet.y, bullet.size, 0, Math.PI * 2);
                ctx.fill();
                ctx.shadowBlur = 0;
            });
        }
        
        function endGame() {
            gameRunning = false;
            
            document.getElementById('finalTime').textContent = (gameTime / 1000).toFixed(1) + 's';
            document.getElementById('finalScore').textContent = score;
            gameOverScreen.style.display = 'block';
        }
        
        function gameLoop(currentTime = 0) {
            if (!gameRunning) return;
            
            const deltaTime = currentTime - lastTime;
            lastTime = currentTime;
            
            updatePlayer(deltaTime);
            spawnBullets(deltaTime);
            updateBullets(deltaTime);
            checkCollisions();
            updateGameState(deltaTime);
            render();
            
            requestAnimationFrame(gameLoop);
        }
        
        // Start the game
        startGame();
    </script>
</body>
</html>

Which One Should You Choose?

Feature / Task
Claude 4 (Sonnet)
DeepSeek R1
Qwen 3
Coding Proficiency
Advanced, excels in complex, real-world software engineering tasks
Strong, particularly good in math/code benchmarks like MATH-500 and Codeforces
Solid and versatile, good at general coding, needs specific guidance for best results
Code Quality (Solar System Project)
More polished, realistic 3D effects, zoom/orbit, UI controls like speed toggle
Functional but less polished and visually rough
Basic implementation, lacks realism and interactivity, but functional
Animation & UX (GSAP Fashion Website)
Decent animations, and responsive design. Great interactive functionality
Great animations, and responsiveness. Good with interactive functionality
Lacks GSAP animations, only basic functionality, needs UX improvements
Reasoning & Problem Solving (Step-by-Step)
Great for architectural thinking and long workflows
Strong in logical step-by-step breakdowns
Accurate reasoning with hybrid thinking mode, best with clear instructions
Benchmark Performance (e.g., SWE-bench, MMLU)
72.7% on SWE-bench, excels in software engineering reasoning
90.8% on MMLU, 97.3% on MATH-500, 96.3% on Codeforces
Competitive performance in reasoning and multilingual tasks, fewer published dev benchmarks
Open Source Availability
Closed-source (Anthropic)
Fully open-source (MIT License)
Fully open-weight (Apache 2.0 License), wide platform support
Best Use Case
Enterprise-grade workflows, dev tools, multi-file projects, deep debugging
Individual developers, education, open projects needing strong logic/maths
General coding, multilingual reasoning, transforming rough ideas into working code

Conclusion

That's it for this blog. Claude 4, Deepseek R1, and Qwen 3 all did a great job, making it hard to choose between them. The best choice depends on what you need and the tasks you want to do. If you prefer detailed explanations and clear reasoning, Deepseek R1 is the way to go. If you want high-quality coding and the latest production-ready code, Claude 4 is a great option. Or if you need a flexible model that can turn incomplete ideas into working code, Qwen 3 is a good choice. It's ideal for solo developers, quick prototyping, and projects that combine logic, UI, and language.

Each model is strong in its own way, so choose the one that suits your needs best. Thanks for reading, and I’ll see you in the next blog!

hero

Streamline your Engineering Team

Get started with a Free Trial or Book A Demo with the founder
footer
logo

Building artificial
engineering intelligence.

Product

Home

Log In

Sign Up

Helpful Links

OSS Explore

PR Arena

Resources

Blog

Changelog

Startups

Contact Us

Careers