ChatGPT4を使ってシンプルなブロック崩しゲームを作成
先日リリースされたChatGPT4、ChatGPT3.5のリリース時から、文章生成だけでは無くプログラムなどにも活用できることは話題になっていましたが、今回はアップデートされたChatGPT4を使って、シンプルなブロック崩しゲームを一緒に創ってみました。
まずはプログラマーの人格を付与
生成するにあたり、以下を最初に入力しました。
あなたは「優秀なプログラマー」です。以下の前提条件をもとに、ブロック崩しのゲームのコードを書いてください。
前提条件
・HTML+CSS+JSで完結する
・コードの行数を少なくシンプルに
初期のコード
<!DOCTYPE html>
<html lang="ja">
<head>
<style>
canvas { display: block; margin: auto; background: #eee; }
body { text-align: center; }
</style>
</head>
<body>
<canvas id="game" width="480" height="320"></canvas>
<script>
const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');
let ball = { x: canvas.width / 2, y: canvas.height - 30, dx: 2, dy: -2, r: 10 };
let paddle = { w: 75, h: 10, x: (canvas.width - 75) / 2 };
let bricks = [], r = 3, c = 5, w = 75, h = 20, p = 10;
for (let i = 0; i < c; i++) {
bricks[i] = [];
for (let j = 0; j < r; j++) bricks[i][j] = { x: 0, y: 0, status: 1 };
}
document.addEventListener('mousemove', e => {
let x = e.clientX - canvas.offsetLeft;
if (x > 0 && x < canvas.width) paddle.x = x - paddle.w / 2;
});
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBricks();
drawBall();
drawPaddle();
collisionDetection();
ball.x += ball.dx;
ball.y += ball.dy;
if (ball.x + ball.dx > canvas.width - ball.r || ball.x + ball.dx < ball.r) ball.dx = -ball.dx;
if (ball.y + ball.dy < ball.r) ball.dy = -ball.dy;
else if (ball.y + ball.dy > canvas.height - ball.r) {
if (ball.x > paddle.x && ball.x < paddle.x + paddle.w) ball.dy = -ball.dy;
else alert('GAME OVER'), document.location.reload();
}
requestAnimationFrame(draw);
}
function drawBricks() {
for (let i = 0; i < c; i++) {
for (let j = 0; j < r; j++) {
if (!bricks[i][j].status) continue;
let brickX = i * (w + p) + p, brickY = j * (h + p) + p;
bricks[i][j].x = brickX;
bricks[i][j].y = brickY;
ctx.beginPath();
ctx.rect(brickX, brickY, w, h);
ctx.fillStyle = '#0095DD';
ctx.fill();
ctx.closePath();
}
}
}
function drawBall() {
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.r, 0, Math.PI * 2);
ctx.fillStyle = 'red';
ctx.fill();
ctx.closePath();
}
function drawPaddle() {
ctx.beginPath();
ctx.rect(paddle.x, canvas.height - paddle.h, paddle.w, paddle.h);
ctx.fillStyle = '#0095DD';
ctx.fill();
ctx.closePath();
}
function collisionDetection() {
for (let i = 0; i < c; i++) {
for (let j = 0; j < r; j++) {
let b = bricks[i][j];
if (b.status && ball.x > b.x && ball.x < b.x + w && ball.y > b.y && ball.y < b.y + h) {
ball.dy = -ball.dy;
b.status = 0;
let remainingBricks = 0;
for (let i = 0; i < c; i++) {
for (let j = 0; j < r; j++) {
remainingBricks += bricks[i][j].status;
}
}
if (!remainingBricks) {
alert('YOU WIN!');
document.location.reload();
}
}
}
}
}
draw();
</script>
</body>
</html>
上記のようなコードは生成されました。パッと見た感じ違和感が無く、普通に動作もしました。ここからさらに改善をChatGPTとやり取りしながら創っていきます。
プログラムの改善
初期の状態ですと、ゲームクリア/ゲームオーバーした際にリロードをしなくてはいけないコードになっているのでゲームオーバー、クリアしたときに「OK」を押したらリセットされ、リロードしなくてもゲームが再スタートできるコードを改修したいと、ChatGPT4に相談しました。
ChatGPTからの提案
1. resetGame関数の追加
function resetGame() {
ball = { x: canvas.width / 2, y: canvas.height - 30, dx: 2, dy: -2, r: 10 };
paddle = { w: 75, h: 10, x: (canvas.width - 75) / 2 };
bricks = [];
for (let i = 0; i < c; i++) {
bricks[i] = [];
for (let j = 0; j < r; j++) bricks[i][j] = { x: 0, y: 0, status: 1 };
}
}
2.resetGame関数を呼び出し
draw();
resetGame();
3.クリア時のアラートからrestGame関数を呼び出し
if (!remainingBricks) {
if (confirm('YOU WIN! Restart?')) resetGame();
}
4.ゲームオーバー時のアラートからrestGame関数を呼び出し
else alert('GAME OVER'), document.location.reload();
コードを反映
プログラムがわかる方は上記の4を見て「?」となったかもしれませんが、ゲームオーバーの処理をミスしています。これは上記のクリアの際と同じ用に「 resetGame();」として記載する必要があります。
すごく便利ですが、完全な動作を求めるのはまだ時間がかかりそうです。ただそれは人間のプログラマも同じなので簡単なものはこういった創り方もありかもしれません。
出来上がったサンプルは「こちら」(PCでのみ操作可能)
サポート役としては十分
ものすごく簡素なものですが、0からコードを書くとそれなりに時間がとられると思いますが、ChatGPTであっという間に完成しました。
今後発展していけば、更に複雑なコードも書けるようになるかもしれませんね。基本のプログラム知識は必須とはなりますがプログラマにとってはとても有意義なサポート役だと思います。今後も色々とChatGPTと一緒に作る企画を試してみたいと思います。