はじめに
最近、AIを使ったプログラミングが注目されていますが、実際にどこまでできるのか試してみたくなりました。そこで今回は、Claude/ChatGPTにPythonでテトリスゲームを作らせてみることに。
結果から言うと、最初は失敗しましたが、適切な指示を出すことで無事に完成しました。この記事では、その過程で学んだ「AIプログラミングで重要なこと」をシェアします。
AIに最初にテトリスを作らせてみた
まずは、シンプルに「Pythonのpygameでテトリスを作って」とお願いしました。
AIは素早くコードを生成してくれて、一見すると動作しているように見えました。ブロックも落ちてくるし、回転もできる。順調!…と思ったのですが。
発生したバグ:一列消えたら枠の外まで消えた
実際にプレイしてみると、一列揃って消えた瞬間、ゲーム画面の枠の外まで消えてしまうという奇妙なバグが発生しました。
これはおかしい。テトリスではゲーム画面内のブロックだけが消えるはずなのに…。
問題の原因を推測する
ここで重要だったのが、AIが書いたコードの仕組みを理解しようとすることでした。
バグの挙動から、私はこう推測しました:
「消える処理の基準点がマイナス(枠外)まで及んでいるのでは?」
そして、テトリスの構造について考えました:
- テトリスは基本的にグリッド状の配列で管理されるべき
- 各マス目に「ブロックがあるか/ないか」を記録する
- 一列揃ったら、その配列の行を削除する
つまり、最初にAIが生成したコードは、ブロックの座標を直接管理していたために、枠外の判定がうまくいっていなかったのだと考えました。
最初のコード(問題があったバージョン)
# shapesの定義(2次元配列形式)
shapes = [
{'shape': [[1, 1, 1, 1]], 'color': (0, 255, 255)}, # I
{'shape': [[1, 1], [1, 1]], 'color': (255, 255, 0)}, # O
# ...
]
# clear_lines関数(簡略版)
def clear_lines(grid, blocks):
full_lines = []
for y in range(len(grid)):
if all(grid[y]):
full_lines.append(y)
for y in full_lines:
del grid[y]
grid.insert(0, [0 for _ in range(game_screen_width // 20)])
# この部分の処理が複雑で、枠外まで影響していた
for y in full_lines:
for block in blocks:
for by, brow in enumerate(block['shape']):
for bx, bcell in enumerate(brow):
if bcell:
block_y = (block['y'] - start_gm_y) // 20 + by
if block_y < y:
block['y'] += 20
このコードでは、ブロックの形状を2次元配列で表現していて、ライン消去時の処理が複雑になっていました。
解決方法:「配列構造で書いて」と指示
そこで、AIに対して具体的な改善案を伝えました:
「テトリスのブロックを配列構造(座標のタプル形式)で管理するように書き直して」
この指示がポイントでした。漠然と「バグを直して」ではなく、どういう構造で実装してほしいかを明確に伝えたのです。
修正後のコード(座標タプル形式)
# shapesの定義(座標タプル形式)
shapes = [
{'shape': [(0, 0), (1, 0), (2, 0), (3, 0)], 'color': (0, 255, 255)}, # I
{'shape': [(0, 0), (1, 0), (0, 1), (1, 1)], 'color': (255, 255, 0)}, # O
# ...
]
# clear_lines関数(改善版)
def clear_lines(grid, blocks):
full_lines = []
for y in range(len(grid)):
if all(grid[y]):
full_lines.append(y)
for y in full_lines:
del grid[y]
grid.insert(0, [0 for _ in range(game_screen_width // 20)])
# 座標タプル形式なので処理がシンプルに
for y in full_lines:
for block in blocks:
for i, (bx, by) in enumerate(block['shape']):
block_y = (block['y'] - start_gm_y) // 20 + by
if block_y < y:
block['shape'][i] = (bx, by + 1)
block['y'] += 20
座標タプル (x, y) 形式にすることで、各ブロックの位置が明確になり、ライン消去時の処理もシンプルで分かりやすくなりました。
結果:バグが完全に解消され、正常に動作するテトリスが完成しました!
AIプログラミングで学んだこと
この経験から学んだのは、AIを使いこなすには「アルゴリズムとデータ構造の理解」が重要だということです。
アルゴリズム・データ構造の知識が活きる場面
今回の問題解決で重要だったのは、「指示の出し方」よりも**「どういうデータ構造で実装すべきか」を理解していたこと**でした。
なぜアルゴリズムの理解が重要なのか
- 問題の本質を見抜ける
- バグの挙動から「座標管理の問題」だと推測できた
- テトリスが「グリッド配列」で管理されるべきだと知っていた
- 2次元配列と座標タプルの違いを理解していた
- 最適なデータ構造を選べる
- AIは「動くコード」は書けるが、「最適な設計」を選ぶのは人間
- 今回は座標タプル形式が適していると判断できた
- データ構造の選択が、バグの有無を左右した
- 的確な改善案を提示できる
- 「直して」→ 漠然としていてAIも困る
- 「配列構造で管理して」→ 具体的で実装可能
AIプログラミングのポイント
- アルゴリズムとデータ構造を理解する
- AIが生成したコードの「設計」を評価できる力が必要
- 配列、リスト、辞書、スタック、キューなどの基本を押さえる
- 処理の流れ(アルゴリズム)を理解する
- バグから逆算してデータ構造を考える
- 「なぜこのバグが起きるのか」→「データがどう管理されているか」
- 問題の原因を、データ構造レベルで推測する
- 設計レベルでAIに指示を出す
- 「直して」ではなく「このデータ構造で実装して」
- アルゴリズムの方向性を示す
プログラミングの基礎知識こそがAI時代の武器
AIは実装の効率化ツールであって、設計を考えるのは人間の役割です。
今回のケースでは、「テトリスのグリッドは配列で管理されるべき」というアルゴリズム・データ構造の知識があったからこそ、問題を解決できました。
AIが普及しても、いや、AIが普及したからこそ、アルゴリズムとデータ構造の理解が重要になります。AIに「何をどう実装させるか」を判断するのは、結局のところ人間だからです。
まとめ
AIにテトリスを作らせた結果:
- 最初は枠外まで消えるバグが発生
- アルゴリズムとデータ構造の知識から原因を分析
- 「配列構造(座標タプル)で実装」と具体的に指示
- バグが解消され、正常に動作するテトリスが完成
AIプログラミングで本当に重要なのは、アルゴリズムとデータ構造の理解です。
AIは「コードを書く」作業を効率化してくれますが、「どういう設計で実装すべきか」を判断するのは人間の役割。プログラミングの基礎知識、特にデータ構造とアルゴリズムの理解があれば、AIをより効果的に活用できます。
AI時代だからこそ、プログラミングの基礎が重要になる—そんなことを実感した開発体験でした。
補足:完成したテトリスの機能
最終的に完成したテトリスには以下の機能があります:
- ブロックの自動落下
- 矢印キーでの左右移動
- スペースキーでの回転
- 下キーで高速落下
- ライン消去とスコア計算
- 次のブロックのプレビュー
興味のある方は、ぜひ自分でもAIにゲームを作らせてみてください!
※この記事は実際の開発体験に基づいています。使用したAI: Claude/ChatGPT、言語: Python、ライブラリ: Pygame

コメント