今回やったこと
Gemini CLIについて学ぶため、Gemini CLIにローグライクゲームを作ってもらいました。
Gemini CLIのバージョンは0.1.9
でした。
今回分かったこと
Gemini CLIは、頼まれていないことも、気を利かせて?いろいろ実装してくれることが分かりました。 (そう思った部分:その1、その2)
今回、私はこの挙動を好意的に受け取りましたが、時と場合と人によっては、余計なことをする、と受け取られる場合があるかも知れないと思いました。
Gemini CLIにローグライクゲームを作ってもらう
まずは直球で聞いてみました。
JavaScriptで簡単なローグライクゲームを作ってもらえますか?
✦ はい、承知いたしました。JavaScriptで簡単なローグライクゲームを作成します。
まず、以下の3つのファイルを作成する計画を提案します。
* index.html: ゲームの基本的な骨格となるHTMLファイルです。
* style.css: ゲームの見た目を整えるためのCSSファイルです。
* game.js: ゲームのロジックを記述するJavaScriptファイルです。
この計画で進めてもよろしいでしょうか?
「はい」と答えると、早速、下記のゲームを作ってくれました。
いや…「簡単な」とは言いましたが、あまりにもシンプルすぎる。😅
これはローグライクゲームとは言えないので、これにローグライクゲームっぽい要素を追加して行ってもらいました。
ランダムなダンジョンを生成してもらう
ランダムなダンジョンを生成してもらえますか?
✦ はい、承知いたしました。ランダムなダンジョンを生成するようにgame.jsを修正します。
✦ ダンジョン生成ロジックを追加し、描画処理を更新します。具体的には、壁と床を表現するマップ配列を作成し、ランダムな部屋と通路を生成する処理を追加します。
おお、凄い。
ちゃんとランダムなダンジョンが生成されました。
しかし、プレイヤーが壁を歩けてしまいます。
プレイヤーが床のみ歩けるようにしてもらう
プレイヤーが床のみ歩けるようにしてください。プレイヤーが壁を歩けないようにしてください。
✦ はい、承知いたしました。プレイヤーが壁に移動できないように、衝突検知のロジックを追加します。
✦ プレイヤーの移動処理を修正し、壁との衝突判定を追加します。具体的には、移動先のタイルが床(map[y][x] === 0)であるかどうかを確認し、床である場合のみプレイヤーの座標を更新するようにします。
✦ これで、プレイヤーは壁を通り抜けられなくなりました。
ちゃんとプレイヤーが床のみ歩けるようになりました。
部屋と通路を生成してもらう
マップにいくつかの部屋が生成されるようにしてください。そして、それらの部屋が通路で結ばれるようにしてください。
✦ はい、承知いたしました。部屋とそれらをつなぐ通路を持つ、より洗練されたダンジョンを生成するように game.js を更新します。
ちゃんと部屋と通路が生成されました。
一気にローグライクゲームっぽくなりました。
階段を追加してもらう
どこかの部屋に下り階段を1つ追加するようにしてください。
✦ はい、承知いたしました。ダンジョンのどこかの部屋に下り階段を1つ追加します。
✦ 承知いたしました。game.jsに階段を追加し、プレイヤーが階段に到達すると新しいダンジョンが生成されるようにします。
階段の追加と、関連するロジックの変更をgame.jsに適用します。具体的には、階段を表す新しいタイルタイプを作成し、最後の部屋に配置します。
また、プレイヤーが階段タイルに移動したときに createDungeon()関数を再度呼び出すように、移動ロジックを更新します。
✦ これで、ダンジョンの最後の部屋に黄色の下り階段が表示され、プレイヤーがその上に移動すると新しいダンジョンが生成されるようになりました。
私は階段を追加することのみ頼みましたが、Gemini CLIは、気を利かせて?プレイヤーが階段に乗ったら、プレイヤーを次の階へ進めるところまでやってくれました。
階数を表示してもらう
画面にプレイヤーがいる階数を表示してください。
✦ はい、承知いたしました。現在の階数を画面に表示するようにします。
ちゃんと階数が表示されるようになりました。
敵を追加してもらう
マップのどこかに敵を追加してください。
✦ はい、承知いたしました。マップに敵を追加します。
✦ 次に、プレイヤーの移動ロジックを更新して、敵との衝突を処理するようにします。
プレイヤーが敵のいるタイルに移動しようとすると、その敵はマップから削除されます。
これは、基本的な攻撃のアクションをシミュレートしたものです。
✦ これで、マップ上に赤い敵が表示され、プレイヤーがそれに接触すると敵が消えるようになりました。
ちゃんと敵が追加されましたが、Gemini CLIは「プレイヤーが敵にぶつかったら、敵が消えるようにした」と言いましたが、なぜか消えませんでした。😅
あと、敵が多すぎる場合があったので、下記の通りお願いしました。
敵は1つのマップに3つまで生成されるようにしてください。
✦ はい、承知いたしました。各マップに生成される敵の数を3体に制限します。
ちゃんと敵が3つまで生成されるようになりました。
プレイヤーのHPを表示してもらう
画面にプレイヤーのHP(ヒットポイント)を表示してください。HPの初期値は100にしてください。
✦ はい、承知いたしました。プレイヤーのHPを100で初期化し、画面に表示するようにします。
なぜか文字が赤いですが、ちゃんとプレイヤーのHPが表示されました。
敵が動くようにしてもらう
プレイヤーが一歩歩いたら、敵もランダムに一歩歩くようにしてください。
✦ はい、承知いたしました。プレイヤーが行動した後に、敵がランダムに一歩動くようにします。
また、敵がプレイヤーに接触した際に、プレイヤーがダメージを受けるようにします。
game.jsを更新して、敵の移動、プレイヤーへの攻撃、そしてゲームオーバーのロジックを実装します。
具体的には、プレイヤーの各アクションの後に敵のターンを実行し、敵はランダムに移動します。
敵がプレイヤーのタイルに移動しようとすると、プレイヤーのHPが減少し、HPが0になるとゲームオーバー画面が表示されます。
✦ これで、プレイヤーが移動すると敵もランダムに移動し、プレイヤーに接触すると10のダメージを与えるようになりました。
プレイヤーのHPが0になると、ゲームオーバー画面が表示されます。
敵が動くようになったことで、一気にゲームっぽくなりました。
また、頼んでなかったんですが、またも気を利かせて?プレイヤーと敵がぶつかった時にプレイヤーにダメージが入るようになったり、ゲームオーバーの画面も追加したり、してくれました。
あと、敵が消えないバグ?も勝手に直りました。
プレイヤーが敵の視界に入ったら、敵がプレイヤーに近づくようにしてください。
✦ はい、承知いたしました。敵がプレイヤーを「発見」し、追跡するようにします。
これは、敵の振る舞いをより高度にするための一般的なローグライクの機能です。
✦ moveEnemies関数を更新して、視界判定と追跡ロジックを実装します。
敵は、プレイヤーが視界(この場合は8タイル以内)に入ると、ランダムな動きからプレイヤーを追跡する動きに切り替わります。
プレイヤーが視界から外れると、敵は再びランダムな動きに戻ります。
これをどう頼むか迷ったんですが、Gemini CLIは、抽象的な頼みでも、ちゃんとそれっぽく実装してくれました。
言語モデルがgemini-2.5-flash
に切り替わる
その後、いくつか微調整を行なった後、下記のメッセージが表示され、言語モデルがgemini-2.5-pro
からgemini-2.5-flash
に切り替わりました。
gemini-2.5-flash
はプログラミング用途としては微妙と聞いていたので、ここで一旦作ってもらうのをやめました。
ℹ ⚡ Slow response times detected. Automatically switching from gemini-2.5-pro to gemini-2.5-flash for faster responses for the remainder of this session.
⚡ To avoid this you can either upgrade to Standard tier. See: https://goo.gle/set-up-gemini-code-assist
⚡ Or you can utilize a Gemini API Key. See: https://goo.gle/gemini-cli-docs-auth#gemini-api-key
⚡ You can switch authentication methods by typing /auth