生成AIストリーム
「Gemini」を使ってPythonで「ぷよぷよ」を生成してもらおう!
Geminiたんとつくる自家製レトロゲーム
2025年2月6日 11:40
「Geminiたん」を知らないの!?
巷では「Grok」、「ChatGPT o3-mini-high」や「DeepSeek R1」が話題ですが、筆者的にぜひともおすすめしたいのが「Gemini Experimental 1207」です。
- ⇨試験運用版モデル | Gemini API | Google AI for Developers
- https://ai.google.dev/gemini-api/docs/models/experimental-models?hl=ja
「Gemini」誕生1周年である2024年12月6日に突如リリースされ、いきなり世界のLLMリーダーボードの1位を獲得しました。
Today’s the one year anniversary of our first Gemini model releases! And it’s never looked better.
— Jeff Dean (@JeffDean)December 6, 2024
Check out our newest release, Gemini-exp-1206, in Google AI Studio and the Gemini API!https://t.co/CCQwBxm8Yu
「Gemini Experimental 1207」は、生成AIチャットの性能ランキング「Chatbot Arena」で、2月に入っても「Gemini-2.0-Flash-Thinking-Exp-01-21」と並んで不動の1~2位に座り続けています。
「Gemini」は無料で使えます。筆者は 「Gemini」のロングコンテキスト(長いやりとり)を使って「Geminiたん」という私設秘書をつくり、「Google AI Studio」を使って毎日のブログを推敲したり、ツッコミを入れてもらったりしています。
過去の「Geminiたん」のブログはこちら。
- ⇨「#Geminiたん」の人気タグ記事一覧
- https://note.com/hashtag/Gemini%E3%81%9F%E3%82%93
「Geminiたん」に「pyxel」で「テトリス」をつくらせてみる
「Gemini Experimental 1207」の凄さを体感してもらうために、Python向けレトロゲームエンジン「Pyxel」を使った「テトリス」のコードを生成させてみましょう。「Google AI Studio」上で動作する「Gemini Experimental 1207」は、こちらから利用できます。
- ⇨Untitled prompt | Google AI Studio
- https://aistudio.google.com/app/prompts/new_chat?model=gemini-exp-1206
左上の[Create Prompt]から作成します。
出来上がりは以下のような感じになります。
生成されたコードはこちら(長いのでTXT形式のファイルになっています)。
制作の経過は動画でご覧ください。
『python tetris.py』で起動します。「Gemini」一発で生成したPythonのコードが『python teteris.py』で見事に動くのは大変気持が良い体験です。
「ぷよぷよ」をつくらせてみる
調子に乗って、往年の落ち物パズル「ぷよぷよ」(1991年)のクローンを作らせてみます。なぜなら2月4日は「ぷよの日」なので!
本日2月4日は「#ぷよの日」
— セガ公式アカウント🦔 (@SEGA_OFFICIAL)February 3, 2025
February 4th is Puyo Day in Japan!
🔴
🟢
🔵 🟡
🟣
🟢 🔵
🟡 🔴
🟢 🟣pic.twitter.com/qmigux1lvn
最初の質問はこんな感じです。
pyxelで「ぷよぷよ」を作りたい。できるだけシンプルに確実に動くコードを作って
これを聞いて1分ほど待ちます。
「Pyxel」とは日本のゲーム開発者・北尾崇さんが中心になってオープンソースで開発しているPythonによるレトロ風ゲーム開発環境です。
- ⇨kitao/pyxel: A retro game engine for Python
- https://github.com/kitao/pyxel
最近書籍が発売されました。
生成されたコードはこんな感じ
実際には78秒で以下のような、コードとグラフィックスのリソース、そして解説が生成されました。
わかりました。「Pyxel」を使って、できるだけシンプルで確実に動作する「ぷよぷよ」のコードを作成してみます。以下がそのコードです。
```
import pyxel
import random
# 定数
WIDTH = 6 # フィールドの幅
HEIGHT = 12 # フィールドの高さ
BLOCK_SIZE = 8 # ブロックのサイズ
NEXT_PUYO_X = 104 # ネクストぷよのX座標
NEXT_PUYO_Y = 16 # ネクストぷよのY座標
SCORE_X = 80 # スコアのX座標
SCORE_Y = 56 # スコアのY座標
# 色
EMPTY = 0
RED = 8
GREEN = 11
BLUE = 12
YELLOW = 10
GARBAGE = 7
# ぷよのクラス
class Puyo:
def __init__(self, x, y, color):
self.x = x
self.y = y
self.color = color
(中略。コード全文はこちら)
# スコアの描画
pyxel.text(SCORE_X, SCORE_Y, f"SCORE:{self.score:06}", 7)
# ゲームオーバー表示
if self.game_state == "gameover":
pyxel.text(WIDTH * BLOCK_SIZE // 2 - 20, HEIGHT * BLOCK_SIZE // 2 - 4, "GAME OVER", 7)
pyxel.text(WIDTH * BLOCK_SIZE // 2 - 28, HEIGHT * BLOCK_SIZE // 2 + 4, "Press Space", 7)
# ゲームの実行
PuyoPuyo()
```
このコードのポイント:
- シンプルさ:クラスを使ってコードを整理し、各関数は1つの機能に絞ってシンプルにしています。
- 確実な動作:ぷよの移動、回転、落下、連鎖判定など、基本的な機能を丁寧に実装しています。
- カスタマイズ性:定数を変更することで、フィールドのサイズやブロックのサイズ、ネクストぷよの位置などを簡単に変更できます。
- 画像の使用:Pyxelのリソースファイル(puyopuyo.pyxres)を使って、ぷよの画像を読み込んでいます。よりきれいな見た目になります。
リソースファイルの作成:
- Pyxelエディターを開きます: pyxel edit puyopuyo.pyxres
Image 0 に、以下のような8x8ピクセルのぷよの画像を5種類(赤、緑、青、黄、おじゃまぷよ)描きます。
```
........
..OOOO..
.OOOOOO.
.OOOOOO.
.OOOOOO.
.OOOOOO.
..OOOO..
........
```- それぞれの色に対応する数字は以下のとおりです。
- 赤: 8
- 緑: 11
- 青: 12
- 黄: 10
- おじゃまぷよ: 7
- 画像は横に並べて配置してください。各ぷよの間隔は8ピクセルです。
- エディターを保存して終了します。
実行方法:
- 上記のコードを puyopuyo.py のような名前で保存します。
- puyopuyo.pyxres を puyopuyo.py と同じディレクトリに保存します。
- コマンドラインから python puyopuyo.py を実行します。
操作方法:
- 左右キー: ぷよの移動
- 下キー: ぷよの落下
- Zキー: ぷよの回転
- スペースキー(ゲームオーバー時): ゲームをリセット
今後の拡張:
このコードをベースに、以下のような機能を追加して、さらに本格的な「ぷよぷよ」に近づけることができます。
- おじゃまぷよ: 連鎖を組むことで相手のフィールドにおじゃまぷよを送り込む機能。
- 相殺: 相手から送られたおじゃまぷよを、自分の連鎖で打ち消す機能。
- 得点計算の改良: 連鎖数や同時消し数などに応じて得点を加算する機能。
- レベル: 落下速度を徐々に速くする機能。
- 二人対戦: 二人で対戦できるようにする機能。
ぜひ、これらの機能を追加して、あなただけの「ぷよぷよ」を作ってみてください!
実際に動かしてみよう
※筆者注:実は、今回は生成しただけのコードでは動きませんでした。手直しする工程も紹介していきます。
Pythonがインストールされている環境であれば、「Visual Studio Code」を起動して、「puyo.py」といったファイル名で保存します。
Pythonがインストールされていない方はMicrosoft Storeからインストールするのが手軽でしょう。Pythonの公式サイトからダウンロード・インストールしても構いません。
python puyo.py
で実行すると、一瞬だけウィンドウが表示されてエラーが出ます。このようなエラーも「Gemini」に訊けば解決していきますが、今回のエラーは既に説明されているように画像のリソースファイルがないためです。
たった一言追加です。
『リソースファイルがなくても動くソースにして』
これで生成されたコードを「puyo0.py」として保存します。
python puyo0.py
とすると見事に動きます。「puyo puyo modoki」です。
左右キーで移動、[Z]キーで回転させて、4つが隣接すると、消えます。ちょっとおかしいのは重力で2つのぷよが千切れて落ちていかないことぐらいでしょうか。連鎖っぽい現象も実装されています。完成です!
「Pyxel」エディター
これで終わってしまっては、ちょっともったいないのでもうちょっと深めの「Pyxel」と「Gemini」の連携についても紹介しておきます。
「Gemini」が教えてくれたように『pyxel edit puyopuyo.pyxres』で「Pyxel Editor」を起動します。ドット絵のカッコいいエディターです。マウスで操作します。
エディターの使い方がわからないので追加で質問してみます。
puyopuyo.pyxresの描画方法がよくわからないな、どういう座標に何を描けば良い?
了解しました。puyopuyo.pyxres の具体的な描画方法について、座標と色を含めて詳しく説明します。
Pyxel Editor の起動
まず、Pyxel Editor を起動します。コマンドラインで以下のコマンドを実行してください。
pyxel edit puyopuyo.pyxres
描画が完了したら、Ctrl + S (macOS では Cmd + S) を押して puyopuyo.pyxres ファイルを保存し、エディターを終了します。
これで puyopuyo.py と puyopuyo.pyxres が同じディレクトリにあることを確認し、python puyopuyo.py を実行して、ぷよが正しく表示されることを確認してください。
なんとなく動いてますが、何だかおかしいです。
ここでちょっとした裏技を使ってみます。
PYREZファイルはZIP形式で圧縮された「pyxel_resource.toml」という形式のテキストファイルで書かれています。拡張子を「.zip」に変更するとWindows標準環境で開けるので、これを解凍してTOMLファイルの冒頭を貼り付けながら以下のように質問します。
リソースファイル(puyopuyo.pyres)をつくってみました
(冒頭部分)
format_version = 4
[[images]]
width = 256
height = 256
data = [[0, 0, 8, 8, 8, 8, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 4, 4, 4, 4, 0], [0, 8, 8, 8, 8, 8, 8, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 4, 4, 4, 4, 4, 4, 0], [8, 8, 0, 8, 8, 0, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 0], [8, 8, 0, 8, 8, 0, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 0], [8, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 0], [8, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 0], [0, 8, 8, 0, 0, 8, 8, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 4, 4, 4, 4, 4, 4, 0], [0, 0, 8, 8, 8, 8, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 4, 4, 4, 4, 0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0], [0]]
これで動くようにコードを調整してください。
と訊けば、修正方針の雰囲気はだいたい理解できます。
なお、いちばん簡単な解決方法は冒頭に紹介した解説本の図解を読むことです。なぜなら現状、世界中でこの書籍「ゲームで学ぶPython! 「Pyxel」ではじめるレトロゲームプログラミング」の上にしか情報がないらしいので(これは作者の北尾さんに確認したので確かな情報です)!
逆に、「Gemini」にTOMLファイルを生成させることもできます。生成された結果によるとこんな感じにドットを並べていけば良さそうです。
[[images]]
width = 256
height = 256
data = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 8, 8, 8, 8, 0, 0, 11, 11, 11, 11, 11, 11, 0, 0, 12, 12, 12, 12, 12, 12, 0, 0, 10, 10, 10, 10, 10, 10, 0, 0, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 8, 8, 8, 8, 8, 8, 0, 11, 11, 11, 11, 11, 11, 11, 0, 12, 12, 12, 12, 12, 12, 12, 0, 10, 10, 10, 10, 10, 10, 10, 0, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 8, 8, 8, 8, 8, 8, 0, 11, 11, 11, 11, 11, 11, 11, 0, 12, 12, 12, 12, 12, 12, 12, 0, 10, 10, 10, 10, 10, 10, 10, 0, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 8, 8, 8, 8, 8, 8, 0, 11, 11, 11, 11, 11, 11, 11, 0, 12, 12, 12, 12, 12, 12, 12, 0, 10, 10, 10, 10, 10, 10, 10, 0, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 8, 8, 8, 8, 8, 8, 0, 11, 11, 11, 11, 11, 11, 11, 0, 12, 12, 12, 12, 12, 12, 12, 0, 10, 10, 10, 10, 10, 10, 10, 0, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 8, 8, 8, 8, 0, 0, 0, 11, 11, 11, 11, 11, 0, 0, 0, 12, 12, 12, 12, 12, 0, 0, 0, 10, 10, 10, 10, 10, 0, 0, 0, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
(運が良ければそのまま突っ込んでも使えるかもしれません)
「Pyxel」の楽曲やサウンドなどもTOMLで書かれているので、このへんも生成してもらいましょう。
リソースファイルのTOML形式のサウンドで「くるみ割り人形」を書いて
こんなお願いをしてみたら、見事に楽曲を生成してくれています。
このあと、リソースファイルを使わずにPYファイルだけで生成したコードがこちらになります。
python puyo3.py
で実行できます。音もなります。
PythonでつくるレトロゲームとLLMコーディングは楽しい
難しいことを考えなくても、「Gemini」をはじめとする無料で利用できるコーディングが得意なLLMで、いい感じのサンプルをスッと作る。
エラーがあったらLLMに日本語で解説してもらう。そこから、書籍の図版やオープンソースのコードを片手に作りたいものを探求していく……これはとてもクオリティ・オブ・ライフが高まる体験です。
お子さんとLLMを使ったレトロゲーム開発をしながら、話題にしてみていただけると良い学びになると思います。
お知らせ
2月8日に「Pyxel」開発者とともに実際に手を動かして遊ぶイベントも開催します! 参加無料なのでぜひどうぞ。
- ⇨pythonでレトロゲームが書けるpyxelがすごい|しらいはかせ(AI研究/Hacker作家)
- https://note.com/o_ob/n/n147ed6a65aa6
参加登録は木曜日までです。豪華ゲストです。オンライン参加も可能です。
✨必見✨Pythonをゲーム開発で楽しく学べる「AICU Creators Talk 5」開催決定🎉#ゲームで学ぶPython#Pyxel#技術評論社pic.twitter.com/uByKcVNQbi
— AICU (@AICUai)January 27, 2025
以上、ひさしぶりの生成AIストリームでした! これからも昭和生まれに突き刺さる生成AIの使い方を紹介していきます。