
ローカルLLMでコード生成能力をを比較する第1弾 CodeLlama 13B編

まずは、以前の記事で書いた通り、うちでは自給自足を目指した生活をしてます。
森の中で電線のない環境で暮らしています。
水道もなく水も沢水を引いて使用しています。
電力は太陽光発電で自給している関係上、
電力消費の少ないPCが必須でAI環境整えました。
そこで、ベストなPCとしてMacBook Air M1 メモリ16GBを使用して環境を構築していましたが。。。。
Difyで複雑なことをしたり、VSCodeの拡張ClineをローカルLLMで動かしたり、していると、メモリ不足で、Swapが始まり、動作が遅くなってきました。
Swapのために、SSDを酷使するのも嫌。
コード生成のためにも、もっと高性能なLLMを動作させたい欲求が高まりました。
高性能GPUを積んだ機種は、電力をたくさん食べます。
APIやクラウドに頼らず、自給自足でAI開発?学習をしたい。
この高まる欲求に押されて、上位種の
MacBook Pro M1 max
を検討し始めた。
現在のMacbook Airと比べて、
GPU 8→32コア 4倍
メモリ 16→64GB 4倍
メモリ帯域幅 68.25→400GB/s 5.86倍
性能は4倍にはなりそう。
何より、14BクラスのLLMが動くの魅力。
今は、8Bクラスが限界だった。
気になる、お値段ですが、中古市場では。
値段 8→20万円 2.5倍
値段は、4倍にはならない。
自分的には、納得のいく事案だけど、
これを、妻にプレゼンしても、20万円の出費は、通らないのは明らか。
でも、メルカリ、ヤフオクを見ていたら、欲しい欲求は高まるばかり。
ついに、というか、とうとう、出た
裏技の、
「内緒で購入」
に踏み切りました。
喜び勇んで、取り替えて、使用しています。
今のところ、妻にも子供にも、気づかれない。
少し厚くなって、
少し大きくなって、
色はグレーからシルバーに変わっんだけど。
ま、リンゴのマークついてるしね。
ラッキー、気にされない。
とここまで、しょーもない、脱線の雑談でした。
ここからが、本題。
性能アップしたPCに、憧れの14BクラスのLLMを入れました。
以下がそのリスト
% ollama list
NAME ID SIZE
llava:13b 0d0eb4d7f485 8.0 GB
codellama:13b 9f438cb9cd58 7.4 GB
phi4:latest ac896e5b8b34 9.1 GB
qwen2.5-coder:14b 3028237cc8c5 9.0 GB
hf.co/mmnga/cyberagent-DeepSeek-R1-Distill-Qwen-14B-Japanese-gguf:latest 26e5cc1b03cd 9.0 GB
これらのLL Mを使用して、ブロック崩しゲームのコードを生成してもらいます。
指示は前回のChatGPTと同様
JavaScript,css,htmlを用いて、Webで動くブロック崩しゲームを作りたい。
これをAIで作成させるためのプロンプトを組み立てて欲しい。
まずは、code llama 13bから。
codellama:13b
Today at 12:10
To create a block break game using JavaScript, HTML, and CSS, you can follow these steps:
Define the rules of the game: The game should have a set number of blocks that need to be broken in order to win. Each block should have a unique color or pattern.
Create the game board: The game board should be a grid of squares, with each square representing one block. You can use CSS and HTML to create the grid and style it as needed.
Add interactivity: Use JavaScript to add interactivity to the game board. For example, you could use mouse events to move the blocks around or keyboard events to change the color of the blocks.
Add AI elements: To make the game more challenging, you can add AI elements such as obstacles or power-ups that the player needs to avoid or use. You can also add an AI opponent that the player must defeat in order to progress.
Implement collision detection: Use JavaScript to detect collisions between the blocks and the walls of the game board. This will prevent the blocks from falling off the edge of the screen.
Add a score system: The game should have a score system that tracks how many blocks the player has broken. You can use JavaScript to update the score as needed.
Add sound effects and music: To enhance the game experience, you can add sound effects and music to the game. This will help to create a more immersive and engaging experience for the player.
Test and refine the game: Once you have created the basic structure of the game, you should test it to make sure that everything works as expected. You may need to refine the game's mechanics or add new features in order to create a more enjoyable and challenging experience for the player.
By following these steps, you can create a block break game using JavaScript, HTML, and CSS that is engaging and challenging for players.
英文ですが、プロンプトには問題なさそうだし、英語での指示の方が性能良いのでこれで、コードを生成してもらいます、
しかし、このまま流しても、ダメだったので最初に次の一文追加しました。
以下の指示のもとで、完全なコードを生成してください。
この時の、メモリ使用量は41GB前後で、推論が終わると34GBに落ちました。
64GBメモリがあって、良かった。
生成されたコードは以下です。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Block Break Game</title>
<style>
* {
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
}
.game-container {
width: 80%;
margin: 20px auto;
border: 1px solid #ccc;
padding: 20px;
}
.block {
display: inline-block;
width: 50px;
height: 50px;
margin: 5px;
background-color: #333;
transition: all 0.5s ease;
}
.block:hover {
cursor: pointer;
transform: scale(1.2);
}
</style>
</head>
<body>
<div class="game-container">
<h1>Block Break Game</h1>
<p>Click on the blocks to break them.</p>
<button id="start-btn">Start Game</button>
<canvas id="game-canvas" width="600" height="400"></canvas>
</div>
<script>
const gameCanvas = document.getElementById('game-canvas');
const ctx = gameCanvas.getContext('2d');
let blocks = [];
let score = 0;
let gameOver = false;
// Initialize the game with a set of blocks and a score of zero
function initGame() {
blocks = [...Array(30)].map((_, i) => ({ x: i * 50, y: Math.floor(Math.random() * (gameCanvas.height - 100)) }));
score = 0;
}
// Update the game canvas with the current state of the blocks and the score
function updateGameCanvas() {
ctx.clearRect(0, 0, gameCanvas.width, gameCanvas.height);
ctx.fillStyle = '#333';
ctx.textAlign = 'center';
ctx.font = '24px Arial';
ctx.fillText(`Score: ${score}`, gameCanvas.width / 2, 50);
}
// Draw the blocks on the canvas
function drawBlocks() {
for (let i = 0; i < blocks.length; i++) {
const block = blocks[i];
ctx.fillRect(block.x, block.y, 50, 50);
}
}
// Update the position of the blocks based on user input
function updateBlocks() {
for (let i = 0; i < blocks.length; i++) {
const block = blocks[i];
if (block.y >= gameCanvas.height - 100) {
score++;
continue;
}
block.y += Math.floor(Math.random() * 50);
}
}
// Check for collisions between the blocks and the mouse cursor
function checkCollisions() {
const rect = gameCanvas.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
for (let i = 0; i < blocks.length; i++) {
const block = blocks[i];
if (block.x <= x && block.x + 50 >= x && block.y <= y && block.y + 50 >= y) {
score--;
break;
}
}
}
// Handle user input
function handleInput() {
gameCanvas.addEventListener('click', checkCollisions);
}
// Start the game loop
function startGameLoop() {
updateBlocks
}
</script>
結果は以下の画面が表示されるが、

Start Gameを押しても、ブロックも表示されず、パドルも出てこない。
動かない。
プログラムを見ると、パドルを動かす処理がないし、ブロックを表示させる処理はあるけど、スタートボタンを押した時に、 updateBlocksしか呼んでない。
Start Gameを押したら、ブロックを表示、ボールも表示して、動かす。
パドルは左右矢印キーで左右に動く。
上記条件を満たすようにコードを書き換えて、その完全なコードを1つのファイルにして生成してください。
と指示したところ。
まずはじめに、HTMLとCSSで以下のようにスケルトンを作成します。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Breakout Game</title>
<style>
* {
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
}
.game-container {
width: 80%;
margin: 20px auto;
border: 1px solid #ccc;
padding: 20px;
}
.block {
display: inline-block;
width: 50px;
height: 50px;
margin: 5px;
background-color: #333;
transition: all 0.5s ease;
}
.ball {
display: inline-block;
width: 25px;
height: 25px;
margin: 5px;
background-color: #333;
transition: all 0.5s ease;
}
</style>
</head>
<body>
<div class="game-container">
<h1>Breakout Game</h1>
<p>Click on the Start button to begin.</p>
<button id="start-btn">Start Game</button>
<canvas id="game-canvas" width="600" height="400"></canvas>
</div>
</body>
</html>
次に、JavaScriptを使って以下のような処理を行います。
startBtnをクリックしたとき、initGame()関数を実行する。
ブロックを表示するために、drawBlocks()関数を実行する。
パドルを表示するために、drawBall()関数を実行する。
左右の矢印キーでパドルを動かすために、handleInput()関数を実行する。
ブロックとパドルが衝突したときにスコアを加算するために、checkCollision()関数を実行する。
ゲームオーバーの条件に到達したときにゲームを終了するために、endGame()関数を実行する。
requestAnimationFrame()関数を使用して、ブロックとパドルの動作を描画するために、runGameLoop()関数を実行する。
以下は、上記の処理を行うJavaScriptコードです。
javascript
// ゲーム全体を管理するクラス
class Game {
constructor() {
this.canvas = document.getElementById("game-canvas");
this.ctx = canvas.getContext("2d");
this.blocks = []; // ブロックの配列
this.ball = {}; // パドルのオブジェクト
this.score = 0; // スコア
this.started = false; // ゲームが開始されたかどうかを判断するフラグ
}
// ゲームを初期化する関数
initGame() {
if (!this.started) {
this.createBlocks(); // ブロックの配列を作成する
this.createBall(); // パドルのオブジェクトを作成する
this.score = 0; // スコアをリセットする
} else {
console.log("Game already started");
}
}
// ブロックの配列を作成する関数
createBlocks() {
for (let i = 0; i < 10; i++) {
this.blocks[i] = new Block(this, i);
}
}
// パドルのオブジェクトを作成する関数
createBall() {
this.ball = new Ball(this);
}
// ブロックとパドルが衝突したときにスコアを加算する関数
checkCollision() {
for (let i = 0; i < this.blocks.length; i++) {
if (this.ball.x >= this.blocks[i].x && this.ball.y <= this.blocks[i].y) {
this.score++;
this.blocks.splice(i, 1); // 衝突したブロックを配列から削除する
}
}
}
// ゲームオーバーの条件に到達したときにゲームを終了する関数
endGame() {
if (this.blocks.length === 0) {
console.log("Congratulations, you won!");
// TODO: 次のレベルに進むなどの処理を行う
} else {
console.log("Game over");
}
}
// ブロックとパドルの動作を描画する関数
runGameLoop() {
if (this.started) {
this.updateBlocks(); // ブロックの配列を更新する
this.checkCollision(); // 衝突したブロックに対する処理を行う
this.endGame(); // ゲームオーバーの条件に到達したときにゲームを終了する
} else {
console.log("Game not started");
}
}
}
// ブロックのクラス
class Block {
constructor(game, index) {
this.game = game; // ゲームオブジェクトへの参照
this.index = index; // ブロックのインデックス
this.x = canvasWidth / 2 + Math.random() * 100 - 50; // ブロックのX座標をランダムに設定する
this.y = 100 + index * 20; // ブロックのY座標を設定する
this.width = 50; // ブロックの幅
this.height = 20; // ブロックの高さ
}
// ブロックを描画する関数
draw() {
const ctx = game.canvas.getContext("2d");
ctx.fillStyle = "blue";
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
// パドルのクラス
class Ball {
constructor(game) {
this.game = game; // ゲームオブジェクトへの参照
this.x = canvasWidth / 2; // パドルのX座標を設定する
this.y = canvasHeight - 100; // パドルのY座標を設定する
this.width = 20; // パドルの幅
this.height = 20; // パドルの高さ
}
// パドルを描画する関数
draw() {
const ctx = game.canvas.getContext("2d");
ctx.fillStyle = "red";
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
// ゲームを開始する関数
function startGame() {
const game = new Game();
game.initGame(); // ゲームを初期化する
requestAnimationFrame(game.runGameLoop.bind(game)); // runGameLoop()を呼び出し、毎フレーム更新されるようにする
}
上記のコードは、startGame()関数が実行されると、ゲームオブジェクトを生成し、initGame()メソッドを呼び出すことで初期化されます。次に、requestAnimationFrame()関数が使用されて、runGameLoop()メソッドが呼び出されます。この関数は、ゲームオブジェクトを更新し、ブロックとパドルの動作を描画します。
以下では、各関数の詳細について解説します。
startGame()関数: この関数は、ゲームを開始するためのエントリポイントです。以下の処理を行います。
新しいゲームオブジェクトを生成する
initGame()メソッドを呼び出すことで、ゲームを初期化する
requestAnimationFrame()関数を使用して、runGameLoop()メソッドが呼び出されるようにする
initGame()メソッド: このメソッドは、ゲームオブジェクトを初期化するために呼び出されます。以下の処理を行います。
新しいブロックの配列を作成する
新しいパドルオブジェクトを作成する
スコアを初期化する
runGameLoop()メソッド: このメソッドは、ゲームが実行されている間、毎フレーム呼び出されます。以下の処理を行います。
ブロックとパドルの動作を更新する
スコアを計算する
画面に描画する
Blockクラス: このクラスは、ゲーム内で使用されるブロックの動作を定義します。以下の処理を行います。
ブロックのX座標とY座標をランダムに設定する
ブロックの幅と高さを設定する
draw()メソッドを実装して、ブロックを描画する
Ballクラス: このクラスは、ゲーム内で使用されるパドルの動作を定義します。以下の処理を行います。
パドルのX座標とY座標を設定する
パドルの幅と高さを設定する
draw()メソッドを実装して、パドルを描画する
以上です。このコードは、ブロックとパドルの動作を更新し、スコアを計算する処理について説明しました。
日本語で表示されたのは良かった。
でも、プログラムの中身はブロック崩しでないし、動かない。
パドルとブロックが当たったら、点数が入るって、ボールはどこに行ったのだろう?
説明でも、Ballクラス: このクラスは、ゲーム内で使用されるパドルの動作を定義します。ってなっているし。
ちょっと、この調子だと無理そう。
やり方を変えて、コード生成するプロンプトは、日本語で正しいのを入れて、試してみたのが以下です。
あなたは「優秀なプログラマー」です。 以下の前提条件に基づいて、HTML、CSS、JavaScriptのみ
を用いたWeb上で動作するシンプルな ブロック崩しゲームのコードを作成してください。
【必須条件】
コードはHTML、CSS、JavaScriptで構成され、 ブラウザ上で即実行可能なものにすること
(単一ファイルまたはファイル分割のどちらでも可)。
ゲームはHTMLのcanvas要素を利用して、ボール、パドル、複数のブロックを描画し、
ボールがパドルで跳ね返り、ブロックに衝突するとブロックが消滅する動作を実装すること。
ボールがキャンバスの下部に到達した場合は「ゲームオーバー」、
すべてのブロックが消えた場合は「ゲームクリア」と判定し、ユーザーにメッセージを表示すること。
パドルはキーボード(左右の矢印キー)とマウス操作に対応するようにすること。
コードはシンプルかつ可読性が高く、必要に応じたコメントを入れること。
【追加オプション(任意)】
- ゲームオーバーやクリア後に「再スタート」できる機能の実装。
効果音や簡単なアニメーションの追加。不足している情報があれば、質問してください。
以上の条件で、シンプルなブロック崩しゲームの完全なソースコードを出力してください。
その結果は前よりだいぶマシでした。
以下がその出力です。
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Block Breaker Game</title>
<style>
#canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<h1>Block Breaker Game</h1>
<canvas id="canvas" width="500" height="300"></canvas>
<script src="game.js"></script>
</body>
</html>
CSS
#canvas {
border: 1px solid black;
}
JavaScript
// Get the canvas and context
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
// Set the canvas dimensions
canvas.width = 500;
canvas.height = 300;
// Set the ball and paddle properties
let ballX = canvas.width / 2;
let ballY = canvas.height - 30;
const ballRadius = 10;
let paddleWidth = 75;
let paddleHeight = 10;
let paddleX = (canvas.width - paddleWidth) / 2;
let paddleY = canvas.height - paddleHeight - 30;
const paddleSpeed = 7;
// Set the block properties
const blockWidth = 50;
const blockHeight = 20;
const blocksPerRow = 10;
const blockOffsetTop = 30;
const blockOffsetLeft = 30;
let blocks = [];
// Create the blocks
for (let i = 0; i < 50; i++) {
const x = (i % blocksPerRow) * (blockWidth + blockOffsetLeft);
const y = Math.floor(i / blocksPerRow) * (blockHeight + blockOffsetTop);
blocks.push({x, y});
}
// Set the game over and game clear flags
let gameOver = false;
let gameClear = false;
// Draw the ball and paddle
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.arc(ballX, ballY, ballRadius, 0, Math.PI * 2);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.rect(paddleX, paddleY, paddleWidth, paddleHeight);
ctx.fillStyle = "#D32F2F";
ctx.fill();
ctx.closePath();
// Draw the blocks
for (let i = 0; i < blocks.length; i++) {
const block = blocks[i];
ctx.beginPath();
ctx.rect(block.x, block.y, blockWidth, blockHeight);
ctx.fillStyle = "#FFC107";
ctx.fill();
ctx.closePath();
}
}
// Update the ball position and check for collisions with paddle or blocks
function update() {
// Check for collision with paddle
if (ballX + ballRadius >= paddleX && ballX - ballRadius <= paddleX + paddleWidth) {
if (ballY >= canvas.height - paddleHeight - 30 && ballY <= canvas.height - 30) {
// Collided with paddle, so update the ball's position and speed
ballX = paddleX + paddleWidth / 2;
ballY -= paddleSpeed;
}
}
// Check for collision with blocks
for (let i = 0; i < blocks.length; i++) {
const block = blocks[i];
if (ballX >= block.x && ballX <= block.x + blockWidth) {
if (ballY >= block.y && ballY <= block.y + blockHeight) {
// Collided with a block, so remove the block from the array and update the score
blocks.splice(i, 1);
break;
}
}
}
}
// Check for game over or game clear conditions
function checkGameState() {
// Check if all blocks have been removed
if (blocks.length === 0) {
gameClear = true;
alert("You win!");
} else if (ballY >= canvas.height - 30) {
gameOver = true;
alert("Game over!");
}
}
// Handle user input to move the paddle
document.addEventListener("keydown", function(event) {
if (event.key === "ArrowLeft") {
paddleX -= 10;
} else if (event.key === "ArrowRight") {
paddleX += 10;
}
});
// Main game loop
function gameLoop() {
update();
checkGameState();
draw();
}
gameLoop();
JSのコードを同じフォルダにgame.jsとして作成して、実行した結果が以下です。

でも、動かない。
ブロックの間隔が広いので、狭くしてほしい。スタートしないので、スペースキーを押したら、
ボールが動いて欲しい。
この修正をして、完全なコードを生成してください。
と修正を頼んだら、以下のコードが出てきた。
// Get the canvas and context
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
// Set the canvas dimensions
canvas.width = 500;
canvas.height = 300;
// Set the ball and paddle properties
let ballX = canvas.width / 2;
let ballY = canvas.height - 30;
const ballRadius = 10;
let paddleWidth = 75;
let paddleHeight = 10;
let paddleX = (canvas.width - paddleWidth) / 2;
let paddleY = canvas.height - paddleHeight - 30;
const paddleSpeed = 7;
// Set the block properties
const blockWidth = 50;
const blockHeight = 20;
const blocksPerRow = 10;
const blockOffsetTop = 30;
const blockOffsetLeft = 30;
let blocks = [];
// Create the blocks
for (let i = 0; i < 50; i++) {
const x = (i % blocksPerRow) * (blockWidth + blockOffsetLeft);
const y = Math.floor(i / blocksPerRow) * (blockHeight + blockOffsetTop);
blocks.push({x, y});
}
// Set the game state
let isStarted = false;
let speedMultiplier = 1;
// Handle user input to move the paddle
document.addEventListener("keydown", function(event) {
if (event.key === "ArrowLeft") {
paddleX -= 10;
} else if (event.key === "ArrowRight") {
paddleX += 10;
}
});
// Handle user input to start and stop the game
document.addEventListener("keydown", function(event) {
if (event.key === " ") {
isStarted = !isStarted;
}
});
// Update the game state based on user input
function updateGameState() {
if (!isStarted) {
return;
}
ballX += speedMultiplier * paddleSpeed;
}
// Check for collisions between the ball and blocks
function checkCollisions() {
let i = 0;
while (i < blocks.length) {
const block = blocks[i];
if (ballX > block.x && ballX < block.x + blockWidth && ballY > block.y && ballY < block.y + blockHeight) {
// If the ball collides with a block, destroy it and move on to the next one
blocks.splice(i, 1);
continue;
}
i++;
}
}
// Draw the game objects
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
ctx.fillRect(ballX, ballY, ballRadius * 2, ballRadius * 2);
ctx.fillStyle = "white";
ctx.fillRect(paddleX, paddleY, paddleWidth, paddleHeight);
for (let i = 0; i < blocks.length; i++) {
const block = blocks[i];
ctx.fillStyle = "black";
ctx.fillRect(block.x, block.y, blockWidth, blockHeight);
}
}
// Main game loop
function gameLoop() {
updateGameState();
checkCollisions();
draw();
requestAnimationFrame(gameLoop);
}
// Start the game loop
gameLoop();
これを動かしてできたのが、以下です。

スペースキーを押すと、パドルが右に動いて、消えました。
ボール亡くなっているし、ブロックの間隔は変わらないし。。。。
これは、どんどん、ハマりそう。
以上、実験失敗の巻。
一発で完成させた、ChatGPT Free の推論版、はすごいと再認識しました。
でも、ローカルLLMで行きたいので、次のLLMに進みます。