ノイマン型コンピューターのアニメーションのゲームです。
コードをメモ帳などのテキストエディタに貼り付け、ファイルを「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>