INDIE INDEX

落ちものパズルを AI で作ってみよう

公開 2026-09-23更新 2026-09-23

Godot Engine で、色の違う玉が2つ1組で落ち、縦か横に3つ以上並ぶと消える落ちものパズルを、Claude Code に日本語で5回頼んで作った記録です。

このページの目次
  1. 作るもの
  2. 用意するもの
  3. 頼んだ順と動いた結果
  4. 動かなかったところと直し方
  5. ここで出てきた語
  6. 情報源

作るもの

横8列×縦14段の盤面に、色の違う玉が2つ1組で上から落ちてくる落ちものパズルです。左右キーで組を動かし、下キーで速く落とし、上キーで組の向きを回せます。同じ色の玉が縦か横に3つ以上並ぶと消え、消えた場所の上にある玉は下に落ちます。消した玉の数をそのままスコアとして画面の上に表示します。一番上の段のどこかに玉が止まると「ゲームオーバー」と表示して止まり、Enter キーで最初からやり直せます。見た目は単純な色の丸だけで、音は付けていません。

用意するもの

  • Godot Engine 4.7.2.stable です。公式サイトの Windows 向け配布物で、zip を展開するだけで使え、アカウント登録や支払いは要りません。
  • Claude Code です。このサイトが操作する AI エージェントです。
  • Windows 11 Home です。

頼んだ順と動いた結果

1. 「Godot 4 で新しいプロジェクトを作って。横8列×縦14段の盤面に、色の違う玉が2つ1組で上から落ちてくるゲームにして。左右キーで動かして、下キーで速く落とせるようにして。」

project.godoticon.svgscenes/Main.tscnscripts/main.gd(新規・約110行)の4つができました。main.gd には _ready_init_grid_spawn_piece_cell_in_bounds_cell_empty_get_sub_pos_can_place_try_move_try_drop_step_lock_piece_process_input_draw という13個の関数が入りました。盤面は8×14のマス目の配列で持たせ、組は「軸になる玉」と「もう一方の玉(軸から見て上下左右のどこか)」の2つで表しました。

Godot_v4.7.2-stable_win64_console.exe --headless --path falling-puzzle.project --quit-after 120 を実行すると、エラーは出ずに120フレーム動いて終了コード0で終わりました。

2. 「同じ色の玉が縦か横に3つ以上並んだら消して、消えたところの上にある玉を下に落として。消した玉の数を点数として画面の上に出して。」

Main.tscnCanvasLayerScoreLabel を足しました。main.gd には score 変数と _clear_matches(約28行)・_apply_gravity(約13行)・_update_score_label(2行)を足し、_lock_piece の末尾に _clear_matches() の呼び出しを1行足しました。_clear_matches は、行ごと・列ごとに同じ色が3つ以上連続する範囲を探して消し、消した玉の数をそのままスコアに足します(倍率は掛けていません)。_apply_gravity が、消えたあとの列を下へ詰め直します。

--headless --path falling-puzzle.project --quit-after 300 ではエラーが出ませんでした。組を左右に交互へ寄せながら14回落とし続けると、玉が3つ並んで消え、スコアが増えていく様子が確認できました。次の画像は、その途中の盤面です(6個消えた時点でスコアは6でした)。

Godot で作った落ちものパズルの画面。盤面の左側に色とりどりの玉が積み上がり、右側の多くの列はまだ空いている。上部に「スコア: 6」と表示され、青と黄色の組が落下している

3. 「玉が一番上の段まで積み上がったら『ゲームオーバー』と出して止めて。Enter キーで最初からやり直せるようにして。」

Main.tscnGameOverLabel(初期状態は非表示)を足しました。main.gd には game_over 変数と _reset_game(約7行)を足し、_spawn_piece に新しい組を置けなかったときの判定(3行)、_process_inputgame_over のあいだの分岐(Enter キーで _reset_game() を呼ぶ処理を含む)、_drawgame_over のときは落下中の組を描かないガードを足しました。

--headless --quit-after 300 ではエラーが出ませんでした。ただし、実際に組を毎回左端の列へ寄せて積み続けて確かめると、頼んだ文(「一番上の段まで積み上がったら」)と違う条件でゲームオーバーになりました。_spawn_piece は、新しい組を出す位置(左から4列目)の上から1段目・2段目の2マスだけを見ていて、この2マスがふさがると、盤面のほかの列がどれだけ空いていてもゲームオーバーにしていました。そのときの盤面は、一番上の段(row0)はすべて空き([-1, -1, -1, -1, -1, -1, -1, -1])で、その1段下(row1)は [0, -1, 1, 0, -1, -1, -1, -1]=左から4列目がふさがっていました。この食い違いの直し方は、段階5に書きました。

4. 「上キーで、2つ1組の玉の向きを回せるようにして。」

main.gd_try_rotate(約14行)を足しました。組の向きは「軸から見て上・右・下・左のどこにもう一方の玉があるか」の4通りで持たせ、回した先が壁や積み上がった玉と重なるときは、横に1マスずらしてから試す処理にしました。_inputKEY_UP の分岐を1行足しました。

--headless --quit-after 300 ではエラーが出ませんでした。組は、軸の下にもう一方の玉がある縦向きで出てきます。上キーを1回押すと、軸の左にもう一方の玉がある横向きに変わりました。

Godot で作った落ちものパズルの画面。組が縦向きから横向きに回転し、軸になっている右の緑の玉の左に、もう一方の青い玉が並んでいる

5. 「一番上の段のどこかに玉が止まったら、ゲームオーバーにして。」

段階3の「動かした結果」に書いた食い違いを直すために頼みました。main.gd_lock_piece に、組を固定して玉を消したあと、一番上の段(row0)のどこかに玉が残っていないかを見る _top_row_has_ball(約5行)を足しました。_lock_piece は、_top_row_has_ball が真なら新しい組を出さずにゲームオーバーにし、そうでなければこれまでどおり次の組を出します。

--headless --quit-after 300 ではエラーが出ませんでした。組を毎回左端の列へ寄せて積み続けるシナリオを撮り直すと、今度は左から2列目の玉が一番上の段に達した時点でゲームオーバーになりました(row0=[-1, 1, -1, -1, -1, -1, -1, -1])。1列目もほぼ同じ高さまで積み上がっていますが、右側の6列はまだ空いています。

Godot で作った落ちものパズルのゲームオーバーの画面。盤面の左から2列目の玉が一番上の段に達してゲームオーバーになっている。1列目もほぼ同じ高さまで積み上がっているが、右側の6列は空いている。中央に「ゲームオーバー」「Enterでやり直し」の文字が赤で表示されている

動かなかったところと直し方

段階3で、「一番上の段まで積み上がったら」という頼んだ文に対し、AI が出したものは「新しい組を出す位置(左から4列目)の上から2マスがふさがったら」という違う条件でした。段階1〜5のいずれも godot --headless --path falling-puzzle.project --quit-after <フレーム数> によるスクリプトのエラーは出ておらず、この食い違いはヘッドレスの実行では見つからず、決まった手順で実際にゲームオーバーの画面まで動かして初めて分かりました。段階5で「一番上の段のどこかに玉が止まったら」という条件に頼み直し、_top_row_has_ball を足して直しました。

ここで出てきた語

落ちものパズルの作例で出てきた Godot の語

意味
ノード(Node)ゲームの基本的な構成要素です。名前・プロパティ・毎フレームの更新処理を持ち、ほかのノードの子として組み合わせられます。
シーン(Scene)ノードをツリー状に組み合わせて保存したものです。保存すると新しいノードの種類として扱え、何度もインスタンスを作れます。
スクリプト(Script)ノードに新しいプロパティと関数を足して、ふるまいを拡張するコードです。今回は GDScript で書きました。
_process(delta)エンジンがフレームを描画するたびに呼ばれる関数です。引数 delta は、前回この関数が呼ばれてからの経過秒数です。
InputEventキーボードなどの入力を表す組み込みの型です。`_input(event)` などのコールバックで扱えます。
save_webpImage クラスのメソッドで、画像を WebP 形式で保存します。第2引数(lossy)を true にすると非可逆圧縮になり、第3引数(quality)で 0.0〜1.0 の間で圧縮の質を指定します。
ヘッドレスモード(--headless)画面を表示せずに実行するコマンドラインのオプションです。GPU の無い環境でも使えるようにするためのものです。
表1

情報源

このページに出た言葉