3
3

ノイマン型 ファミリーコンピューター のアニメーションのゲーム。

Last updated at Posted at 2024-08-26

スクリーンショット 2024-08-26 175357.png

ノイマン型コンピューターのアニメーションのゲームです。

コードをメモ帳などのテキストエディタに貼り付け、ファイルを「index.html」などの拡張子が.htmlのファイルとして保存します。その後、保存したファイルをブラウザで開けば、コードが実行されます。

コンポーネントの説明:

メモリー、レジスター、CPUの各コンポーネントの役割をわかりやすく説明しました。

命令の詳細な説明:

実行中の命令について、具体的に何をするのかを説明するためのテキストを追加しました。
ループ命令と加算命令それぞれについて、どのような操作が行われるのかを視覚的に説明しています。

これにより、ノイマン型コンピュータの動作が理解しやすくなります。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ノイマン型コンピューターのアニメーション</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
            height: 100vh;
            margin: 0;
            background-color: #000;
            color: #fff;
            font-family: Arial, sans-serif;
        }
        canvas {
            border: 1px solid #fff;
            margin-bottom: 20px;
        }
        #log {
            width: 800px;
            height: 150px;
            background-color: #111;
            border: 1px solid #fff;
            padding: 10px;
            overflow-y: auto;
            font-size: 14px;
        }
    </style>
</head>
<body>
    <canvas id="computerCanvas" width="800" height="350"></canvas>
    <div id="log"></div>
    <script>
        const canvas = document.getElementById('computerCanvas');
        const ctx = canvas.getContext('2d');
        const logDiv = document.getElementById('log');

        let instructionPointer = 0; // 現在の命令ポインタ
        let memory = new Array(10).fill(0); // メモリー(10個の要素を持つ配列)
        let registers = [0, 0]; // レジスター(2つのレジスター)
        let instructions = [1, 2, 0, 3, 0, 4, 0, 5]; // サンプル命令セット
        let loopCounter = 0; // ループカウンター
        let loopLimit = 3; // ループ回数制限

        function drawComponents() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            // メモリーの描画
            ctx.fillStyle = '#f00';
            ctx.fillRect(50, 50, 200, 200);
            ctx.fillStyle = '#fff';
            ctx.fillText('メモリー (Memory)', 120, 30);
            ctx.fillText('ここには数値が保存されます。', 60, 230);

            // レジスターの描画
            ctx.fillStyle = '#0f0';
            ctx.fillRect(300, 50, 200, 100);
            ctx.fillStyle = '#fff';
            ctx.fillText('レジスター (Registers)', 370, 30);
            ctx.fillText('ここに計算結果が保存されます。', 310, 70);

            // CPUの描画
            ctx.fillStyle = '#00f';
            ctx.fillRect(550, 50, 200, 100);
            ctx.fillStyle = '#fff';
            ctx.fillText('CPU', 620, 30);
            ctx.fillText('CPUが命令を実行します。', 560, 70);

            // 命令ポインタの描画
            ctx.fillStyle = '#ff0';
            ctx.fillRect(50 + instructionPointer * 20, 260, 20, 20);
            ctx.fillStyle = '#fff';
            ctx.fillText(`IP: ${instructionPointer}`, 50, 290);
        }

        function drawMemory() {
            ctx.fillStyle = '#fff';
            memory.forEach((value, index) => {
                ctx.fillText(`M[${index}]: ${value}`, 60, 70 + index * 20);
            });
        }

        function drawRegisters() {
            ctx.fillStyle = '#fff';
            registers.forEach((value, index) => {
                ctx.fillText(`R[${index}]: ${value}`, 310, 70 + index * 20);
            });
        }

        function drawCPU() {
            ctx.fillStyle = '#fff';
            ctx.fillText('実行中の命令:', 560, 110);
            const currentInstruction = instructions[instructionPointer];
            ctx.fillText(`命令: ${currentInstruction}`, 560, 130);
            ctx.fillText(`ループ回数: ${loopCounter}`, 560, 150);
            
            // 命令の詳細を描画
            if (currentInstruction === 0) {
                ctx.fillText('→ ループの開始です。', 560, 170);
                ctx.fillText('   ループ回数を確認します。', 560, 190);
            } else {
                ctx.fillText('→ 加算操作を行います。', 560, 170);
                ctx.fillText(`   レジスター R[${(currentInstruction - 1) % 2}] に ${currentInstruction} を加算します。`, 560, 190);
            }
        }

        function logMessage(message) {
            const newMessage = document.createElement('div');
            newMessage.textContent = message;
            logDiv.appendChild(newMessage);
            logDiv.scrollTop = logDiv.scrollHeight; // 最新のメッセージを表示
        }

        function executeInstruction() {
            if (instructions[instructionPointer] !== undefined) {
                const instruction = instructions[instructionPointer];
                logMessage(`実行中の命令: ${instructionPointer}, 命令: ${instruction}`); // 画面上にログを出力

                if (instruction === 0) {
                    // ループ操作
                    if (loopCounter < loopLimit) {
                        logMessage(`ループ開始: ${loopCounter + 1}`);
                        loopCounter++;
                        instructionPointer = (instructionPointer + 1) % instructions.length;
                    } else {
                        logMessage('ループ終了');
                        loopCounter = 0; // ループカウンターをリセット
                        instructionPointer = (instructionPointer + 1) % instructions.length;
                    }
                } else {
                    // 加算操作
                    let regIndex = (instruction - 1) % 2; // 使用するレジスターを決定
                    logMessage(`加算操作: レジスター R[${regIndex}] に ${instruction} を加算`);
                    registers[regIndex] += instruction;
                    memory[instructionPointer] = registers[regIndex];
                    instructionPointer = (instructionPointer + 1) % instructions.length;
                }
            }
        }

        function animate() {
            drawComponents();
            drawMemory();
            drawRegisters();
            drawCPU();
            executeInstruction();

            setTimeout(animate, 1000); // 1秒ごとに命令を実行
        }

        ctx.font = '16px Arial';
        animate();
    </script>
</body>
</html>


3
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3