Claude 4 Sonnetのコーディング能力を試す 3


Claude 4 が話題を呼んでいる.今回はClaude 3.7との比較でランダムウォークのシミュレーションを行ってみた.

また今回は一つプロンプトに文言を追加した.こうすることで性能が上がるとのこと.

結果,以前よりもリッチなものが出てきた.

ランダムウォークのシミュレーションを行うコードを書いて. 
	Reactで動的に処理できるようにして. 
	エラーが出ないように自己点検して.
一切の遠慮は不要です!!最高品質を追い求めて.
import React, { useState, useEffect, useRef, useCallback } from 'react';
import { Play, Pause, RotateCcw, Settings, TrendingUp } from 'lucide-react';

const RandomWalkSimulation = () => {
  // 状態管理
  const [isRunning, setIsRunning] = useState(false);
  const [paths, setPaths] = useState([]);
  const [currentPositions, setCurrentPositions] = useState([]);
  const [stepCount, setStepCount] = useState(0);
  const [statistics, setStatistics] = useState({ maxDistance: 0, avgDistance: 0 });
  
  // パラメータ設定
  const [numWalkers, setNumWalkers] = useState(5);
  const [stepSize, setStepSize] = useState(2);
  const [speed, setSpeed] = useState(100);
  const [dimension, setDimension] = useState('2D');
  const [maxSteps, setMaxSteps] = useState(1000);
  const [showTrails, setShowTrails] = useState(true);
  
  const animationRef = useRef();
  const canvasRef = useRef();
  
  // カラーパレット
  const colors = [
    '#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7',
    '#DDA0DD', '#98D8C8', '#F7DC6F', '#BB8FCE', '#85C1E9'
  ];

  // 初期化
  const initializeWalkers = useCallback(() => {
    const centerX = 400;
    const centerY = 300;
    
    const newPaths = Array.from({ length: numWalkers }, (_, i) => ({
      id: i,
      points: [{ x: centerX, y: centerY, z: dimension === '3D' ? 0 : undefined }],
      color: colors[i % colors.length]
    }));
    
    const newPositions = Array.from({ length: numWalkers }, () => ({
      x: centerX,
      y: centerY,
      z: dimension === '3D' ? 0 : undefined
    }));
    
    setPaths(newPaths);
    setCurrentPositions(newPositions);
    setStepCount(0);
    setStatistics({ maxDistance: 0, avgDistance: 0 });
  }, [numWalkers, dimension]);

  // ランダムステップ生成
  const generateRandomStep = () => {
    if (dimension === '2D') {
      const angle = Math.random() * 2 * Math.PI;
      return {
        dx: Math.cos(angle) * stepSize,
        dy: Math.sin(angle) * stepSize
      };
    } else {
      // 3D
      const phi = Math.random() * 2 * Math.PI;
      const theta = Math.random() * Math.PI;
      return {
        dx: Math.sin(theta) * Math.cos(phi) * stepSize,
        dy: Math.sin(theta) * Math.sin(phi) * stepSize,
        dz: Math.cos(theta) * stepSize
      };
    }
  };

  // 距離計算
  const calculateDistance = (pos) => {
    const centerX = 400, centerY = 300;
    if (dimension === '2D') {
      return Math.sqrt((pos.x - centerX) ** 2 + (pos.y - centerY) ** 2);
    } else {
      return Math.sqrt((pos.x - centerX) ** 2 + (pos.y - centerY) ** 2 + pos.z ** 2);
    }
  };

  // シミュレーションステップ
  const performStep = useCallback(() => {
    if (stepCount >= maxSteps) {
      setIsRunning(false);
      return;
    }

    setPaths(prevPaths => 
      prevPaths.map(path => {
        const step = generateRandomStep();
        const lastPoint = path.points[path.points.length - 1];
        const newPoint = {
          x: Math.max(50, Math.min(750, lastPoint.x + step.dx)),
          y: Math.max(50, Math.min(550, lastPoint.y + step.dy)),
          z: dimension === '3D' ? lastPoint.z + step.dz : undefined
        };
        
        const newPoints = showTrails 
          ? [...path.points, newPoint]
          : [newPoint];
        
        return { ...path, points: newPoints };
      })
    );

    setCurrentPositions(prevPositions =>
      prevPositions.map(pos => {
        const step = generateRandomStep();
        return {
          x: Math.max(50, Math.min(750, pos.x + step.dx)),
          y: Math.max(50, Math.min(550, pos.y + step.dy)),
          z: dimension === '3D' ? pos.z + step.dz : undefined
        };
      })
    );

    setStepCount(prev => prev + 1);
  }, [stepCount, maxSteps, stepSize, dimension, showTrails]);

  // 統計更新
  useEffect(() => {
    if (currentPositions.length > 0) {
      const distances = currentPositions.map(calculateDistance);
      const maxDist = Math.max(...distances);
      const avgDist = distances.reduce((a, b) => a + b, 0) / distances.length;
      
      setStatistics({
        maxDistance: maxDist,
        avgDistance: avgDist
      });
    }
  }, [currentPositions, dimension]);

  // アニメーションループ
  useEffect(() => {
    if (isRunning) {
      animationRef.current = setInterval(performStep, speed);
    } else {
      clearInterval(animationRef.current);
    }
    
    return () => clearInterval(animationRef.current);
  }, [isRunning, performStep, speed]);

  // 初期化処理
  useEffect(() => {
    initializeWalkers();
  }, [initializeWalkers]);

  // 3D投影(簡易)
  const project3DTo2D = (point) => {
    if (dimension === '2D' || !point.z) return point;
    const scale = 200 / (200 + point.z);
    return {
      x: point.x * scale + (1 - scale) * 400,
      y: point.y * scale + (1 - scale) * 300
    };
  };

  return (
    <div className="w-full max-w-6xl mx-auto p-6 bg-gradient-to-br from-slate-900 via-purple-900 to-slate-900 min-h-screen text-white">
      {/* ヘッダー */}
      <div className="text-center mb-8">
        <h1 className="text-4xl font-bold bg-gradient-to-r from-blue-400 to-purple-400 bg-clip-text text-transparent mb-2">
          ランダムウォーク シミュレーション
        </h1>
        <p className="text-slate-300">多次元ランダムウォークの動的可視化</p>
      </div>

      {/* コントロールパネル */}
      <div className="bg-slate-800/50 backdrop-blur-sm rounded-lg p-6 mb-6 border border-slate-700">
        <div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-4">
          <div>
            <label className="block text-sm font-medium mb-2 text-slate-300">
              <Settings className="inline w-4 h-4 mr-1" />
              ウォーカー数
            </label>
            <input
              type="range"
              min="1"
              max="20"
              value={numWalkers}
              onChange={(e) => setNumWalkers(parseInt(e.target.value))}
              className="w-full accent-blue-500"
              disabled={isRunning}
            />
            <div className="text-center text-sm text-slate-400">{numWalkers}</div>
          </div>
          
          <div>
            <label className="block text-sm font-medium mb-2 text-slate-300">
              ステップサイズ
            </label>
            <input
              type="range"
              min="0.5"
              max="10"
              step="0.5"
              value={stepSize}
              onChange={(e) => setStepSize(parseFloat(e.target.value))}
              className="w-full accent-green-500"
            />
            <div className="text-center text-sm text-slate-400">{stepSize}</div>
          </div>
          
          <div>
            <label className="block text-sm font-medium mb-2 text-slate-300">
              速度 (ms)
            </label>
            <input
              type="range"
              min="10"
              max="500"
              value={speed}
              onChange={(e) => setSpeed(parseInt(e.target.value))}
              className="w-full accent-purple-500"
            />
            <div className="text-center text-sm text-slate-400">{speed}</div>
          </div>
          
          <div>
            <label className="block text-sm font-medium mb-2 text-slate-300">
              最大ステップ数
            </label>
            <input
              type="range"
              min="100"
              max="5000"
              step="100"
              value={maxSteps}
              onChange={(e) => setMaxSteps(parseInt(e.target.value))}
              className="w-full accent-orange-500"
            />
            <div className="text-center text-sm text-slate-400">{maxSteps}</div>
          </div>
        </div>

        <div className="flex flex-wrap gap-4 items-center">
          <div className="flex gap-2">
            <button
              onClick={() => setIsRunning(!isRunning)}
              className="flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 rounded-lg transition-colors"
            >
              {isRunning ? <Pause className="w-4 h-4" /> : <Play className="w-4 h-4" />}
              {isRunning ? '停止' : '開始'}
            </button>
            
            <button
              onClick={initializeWalkers}
              className="flex items-center gap-2 px-4 py-2 bg-slate-600 hover:bg-slate-700 rounded-lg transition-colors"
              disabled={isRunning}
            >
              <RotateCcw className="w-4 h-4" />
              リセット
            </button>
          </div>
          
          <div className="flex gap-4">
            <label className="flex items-center gap-2">
              <input
                type="radio"
                name="dimension"
                value="2D"
                checked={dimension === '2D'}
                onChange={(e) => setDimension(e.target.value)}
                disabled={isRunning}
                className="accent-blue-500"
              />
              2D
            </label>
            <label className="flex items-center gap-2">
              <input
                type="radio"
                name="dimension"
                value="3D"
                checked={dimension === '3D'}
                onChange={(e) => setDimension(e.target.value)}
                disabled={isRunning}
                className="accent-blue-500"
              />
              3D
            </label>
          </div>
          
          <label className="flex items-center gap-2">
            <input
              type="checkbox"
              checked={showTrails}
              onChange={(e) => setShowTrails(e.target.checked)}
              className="accent-green-500"
            />
            軌跡表示
          </label>
        </div>
      </div>

      {/* 統計情報 */}
      <div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
        <div className="bg-slate-800/50 backdrop-blur-sm rounded-lg p-4 border border-slate-700">
          <div className="flex items-center gap-2 text-blue-400 mb-1">
            <TrendingUp className="w-4 h-4" />
            ステップ数
          </div>
          <div className="text-2xl font-bold">{stepCount.toLocaleString()}</div>
        </div>
        
        <div className="bg-slate-800/50 backdrop-blur-sm rounded-lg p-4 border border-slate-700">
          <div className="text-green-400 mb-1">最大距離</div>
          <div className="text-2xl font-bold">{statistics.maxDistance.toFixed(1)}</div>
        </div>
        
        <div className="bg-slate-800/50 backdrop-blur-sm rounded-lg p-4 border border-slate-700">
          <div className="text-purple-400 mb-1">平均距離</div>
          <div className="text-2xl font-bold">{statistics.avgDistance.toFixed(1)}</div>
        </div>
      </div>

      {/* シミュレーション画面 */}
      <div className="relative bg-slate-900/50 backdrop-blur-sm rounded-lg overflow-hidden border border-slate-700">
        <svg
          width="800"
          height="600"
          className="w-full h-auto"
          viewBox="0 0 800 600"
        >
          {/* グリッド */}
          <defs>
            <pattern id="grid" width="50" height="50" patternUnits="userSpaceOnUse">
              <path d="M 50 0 L 0 0 0 50" fill="none" stroke="#374151" strokeWidth="0.5" opacity="0.3"/>
            </pattern>
            <radialGradient id="centerGlow" cx="50%" cy="50%" r="50%">
              <stop offset="0%" stopColor="#3B82F6" stopOpacity="0.3"/>
              <stop offset="100%" stopColor="#3B82F6" stopOpacity="0"/>
            </radialGradient>
          </defs>
          
          <rect width="800" height="600" fill="url(#grid)"/>
          <circle cx="400" cy="300" r="100" fill="url(#centerGlow)"/>
          
          {/* 中心点 */}
          <circle cx="400" cy="300" r="4" fill="#3B82F6" opacity="0.8"/>
          <text x="410" y="305" fill="#3B82F6" fontSize="12" opacity="0.8">原点</text>
          
          {/* パス描画 */}
          {paths.map((path, index) => {
            if (path.points.length < 2) return null;
            
            const projectedPoints = path.points.map(project3DTo2D);
            const pathData = projectedPoints.reduce((acc, point, i) => {
              return i === 0 ? `M ${point.x} ${point.y}` : `${acc} L ${point.x} ${point.y}`;
            }, '');
            
            return (
              <g key={path.id}>
                {showTrails && (
                  <path
                    d={pathData}
                    stroke={path.color}
                    strokeWidth="1.5"
                    fill="none"
                    opacity="0.7"
                    style={{
                      filter: 'drop-shadow(0 0 2px rgba(255,255,255,0.1))'
                    }}
                  />
                )}
                
                {/* 現在位置 */}
                {projectedPoints.length > 0 && (
                  <circle
                    cx={projectedPoints[projectedPoints.length - 1].x}
                    cy={projectedPoints[projectedPoints.length - 1].y}
                    r="4"
                    fill={path.color}
                    stroke="white"
                    strokeWidth="1"
                    style={{
                      filter: 'drop-shadow(0 0 4px rgba(255,255,255,0.3))'
                    }}
                  />
                )}
              </g>
            );
          })}
          
          {/* 距離圏表示 */}
          <circle cx="400" cy="300" r="50" fill="none" stroke="#64748B" strokeWidth="1" opacity="0.3" strokeDasharray="5,5"/>
          <circle cx="400" cy="300" r="100" fill="none" stroke="#64748B" strokeWidth="1" opacity="0.3" strokeDasharray="5,5"/>
          <circle cx="400" cy="300" r="150" fill="none" stroke="#64748B" strokeWidth="1" opacity="0.3" strokeDasharray="5,5"/>
        </svg>
        
        {/* 3D表示インジケーター */}
        {dimension === '3D' && (
          <div className="absolute top-4 right-4 bg-slate-800/80 backdrop-blur-sm rounded-lg p-2 text-sm">
            3D モード (Z軸投影)
          </div>
        )}
      </div>
      
      {/* 説明 */}
      <div className="mt-6 bg-slate-800/30 backdrop-blur-sm rounded-lg p-4 border border-slate-700">
        <h3 className="font-semibold mb-2 text-slate-200">使い方</h3>
        <ul className="text-sm text-slate-400 space-y-1">
          <li>• スライダーでパラメータを調整し、開始ボタンでシミュレーション開始</li>
          <li>• 2D/3Dモードを選択可能(3Dは簡易投影で表示)</li>
          <li>• 軌跡表示のオン/オフで表示方法を変更</li>
          <li>• 各ウォーカーは異なる色で表示され、統計情報をリアルタイム更新</li>
        </ul>
      </div>
    </div>
  );
};

export default RandomWalkSimulation;

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です