生成AIストリーム

「Gemini」を使ってPythonで「ぷよぷよ」を生成してもらおう!

Geminiたんとつくる自家製レトロゲーム

「Gemini」を追加ってPythonで「ぷよぷよ」を生成してもらおう!

「Geminiたん」を知らないの!?

 巷では「Grok」、「ChatGPT o3-mini-high」や「DeepSeek R1」が話題ですが、筆者的にぜひともおすすめしたいのが「Gemini Experimental 1207」です。

 「Gemini」誕生1周年である2024年12月6日に突如リリースされ、いきなり世界のLLMリーダーボードの1位を獲得しました。



 「Gemini Experimental 1207」は、生成AIチャットの性能ランキング「Chatbot Arena」で、2月に入っても「Gemini-2.0-Flash-Thinking-Exp-01-21」と並んで不動の1~2位に座り続けています。

「Chatbot Arena」で「Gemini Experimental 1207」は不動の1位をキープ

 「Gemini」は無料で使えます。筆者は 「Gemini」のロングコンテキスト(長いやりとり)を使って「Geminiたん」という私設秘書をつくり、「Google AI Studio」を使って毎日のブログを推敲したり、ツッコミを入れてもらったりしています。

 過去の「Geminiたん」のブログはこちら。

「Geminiたん」に「pyxel」で「テトリス」をつくらせてみる

 「Gemini Experimental 1207」の凄さを体感してもらうために、Python向けレトロゲームエンジン「Pyxel」を使った「テトリス」のコードを生成させてみましょう。「Google AI Studio」上で動作する「Gemini Experimental 1207」は、こちらから利用できます。

 左上の[Create Prompt]から作成します。

 出来上がりは以下のような感じになります。

AIが生成した「テトリス」

 生成されたコードはこちら(長いのでTXT形式のファイルになっています)。

AIが生成した「テトリス」のコード

 制作の経過は動画でご覧ください。

Pyxel+Geminiでテトリスを一瞬で作った話

 『python tetris.py』で起動します。「Gemini」一発で生成したPythonのコードが『python teteris.py』で見事に動くのは大変気持が良い体験です。

「ぷよぷよ」をつくらせてみる

 調子に乗って、往年の落ち物パズル「ぷよぷよ」(1991年)のクローンを作らせてみます。なぜなら2月4日は「ぷよの日」なので!



「Google AI Studio」上で動作する「Gemini Experimental 1207」で「ぷよぷよ」を生成させる

 最初の質問はこんな感じです。

pyxelで「ぷよぷよ」を作りたい。できるだけシンプルに確実に動くコードを作って

 これを聞いて1分ほど待ちます。

「ぷよぷよ」を生成する「Gemini Experimental 1207」

 「Pyxel」とは日本のゲーム開発者・北尾崇さんが中心になってオープンソースで開発しているPythonによるレトロ風ゲーム開発環境です。

 最近書籍が発売されました。

生成されたコードはこんな感じ

 実際には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)を使って、ぷよの画像を読み込んでいます。よりきれいな見た目になります。

リソースファイルの作成:
  1. Pyxelエディターを開きます: pyxel edit puyopuyo.pyxres
    Image 0 に、以下のような8x8ピクセルのぷよの画像を5種類(赤、緑、青、黄、おじゃまぷよ)描きます。

    ```
    ........
    ..OOOO..
    .OOOOOO.
    .OOOOOO.
    .OOOOOO.
    .OOOOOO.
    ..OOOO..
    ........
    ```
  2. それぞれの色に対応する数字は以下のとおりです。
    • 赤: 8
    • 緑: 11
    • 青: 12
    • 黄: 10
    • おじゃまぷよ: 7
  3. 画像は横に並べて配置してください。各ぷよの間隔は8ピクセルです。
  4. エディターを保存して終了します。

実行方法:

  1. 上記のコードを puyopuyo.py のような名前で保存します。
  2. puyopuyo.pyxres を puyopuyo.py と同じディレクトリに保存します。
  3. コマンドラインから 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」です。

「puyo puyo modoki」爆誕!

 左右キーで移動、[Z]キーで回転させて、4つが隣接すると、消えます。ちょっとおかしいのは重力で2つのぷよが千切れて落ちていかないことぐらいでしょうか。連鎖っぽい現象も実装されています。完成です!

「Pyxel」エディター

 これで終わってしまっては、ちょっともったいないのでもうちょっと深めの「Pyxel」と「Gemini」の連携についても紹介しておきます。

 「Gemini」が教えてくれたように『pyxel edit puyopuyo.pyxres』で「Pyxel Editor」を起動します。ドット絵のカッコいいエディターです。マウスで操作します。

「Pyxel Editor」
「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ファイルだけで生成したコードがこちらになります。

リソースファイルを使わずにPYファイルだけで生成したコード

python puyo3.py

で実行できます。音もなります。

【AIが生成した「ぷよぷよ」をプレイ】
Puyo Puyo 2025 02 05

PythonでつくるレトロゲームとLLMコーディングは楽しい

 難しいことを考えなくても、「Gemini」をはじめとする無料で利用できるコーディングが得意なLLMで、いい感じのサンプルをスッと作る。

 エラーがあったらLLMに日本語で解説してもらう。そこから、書籍の図版やオープンソースのコードを片手に作りたいものを探求していく……これはとてもクオリティ・オブ・ライフが高まる体験です。

 お子さんとLLMを使ったレトロゲーム開発をしながら、話題にしてみていただけると良い学びになると思います。

お知らせ

 2月8日に「Pyxel」開発者とともに実際に手を動かして遊ぶイベントも開催します! 参加無料なのでぜひどうぞ。

 参加登録は木曜日までです。豪華ゲストです。オンライン参加も可能です。



 以上、ひさしぶりの生成AIストリームでした! これからも昭和生まれに突き刺さる生成AIの使い方を紹介していきます。