これから作る三つの的
これからこのゲームを事例に、一緒にゲームを創っていきます。見本ゲーム「三つの的」です。下にあるのは6章まで進めた完成形。そのまま遊べます。まず1回遊んで、目的地を体で知ってから読み進めてください。
結論から言うと、ルールは箇条書きで全部書き出してください。 書いていないところは、AIが勝手に決めてしまうんです。
なぜ要るか
ここが企画で一番効く作業です。
AIはルールが書かれていれば作れます。書かれていなければ、勝手に決めます。 そして勝手に決められた部分は、たいてい自分の思っていたものとは別物です。結局、あとで直すことになるんですね。
しかも人間側も、書き出すまで気づかないんですよ。「同時に出す」と書いてみて初めて「1台のパソコンだと後の人が有利じゃないか」と気づきます。1台を交代で使うと、後に操作する人は先の人が置いた場所を見てから選べてしまうからです。書くことで穴が見えます。
だから、コードを1行も書く前にルールを並べます。20分かけるだけで、あとの手戻りを何時間分も節約できます。
AIプロンプト
この術の作業をAIへ任せるときは、これをそのまま貼ってください。
下のルールで、決まっていないことを質問の形で全部挙げてください。
同点、引き分け、終わり方、同時に出す方法は特に念入りに。
まだ答えは提案しないでください。
(ここへルールを貼る)
(ここへルールを貼る)の部分は、自分で書いた箇条書きのルールに置き換えてください。
書き方は箇条書きだけ
文章にしないでください。1ルール1行の箇条書きにします。
書く順番はこの5つで足ります。
| 順番 | 何を書くか | 例 |
|---|---|---|
| 1 | 何を使うか | 1から5の札を1人1組と、的を3つ |
| 2 | どう始まるか | お互いに、自分の山から3枚配られる |
| 3 | 1回の手番で何をするか | 1枚えらび、置く的を決めて、同時に出す |
| 4 | 勝ち負けの決まり方 | 的ごとに合計が大きい方がその的を取り、的を多く取った方が勝ち |
| 5 | いつ終わるか | 手札3枚を置き切ったら終わり |
この5つが埋まれば、遊べるゲームになります。埋まっていないものが1つでもあると、作れないんです。
忘れやすいのは「引き分け」と「終わり方」
僕が何度もやった失敗です。
引き分けを決めていないと、最後の最後で止まります。的の合計が同じだったら? 取った的の数が同じだったら? ここが未定義、つまり「どうするか決めていない状態」だと、画面に何を出すか決まらず、完成の一歩手前で足が止まります。
終わり方も同じです。「手札を置き切ったら終わり」なのか「どちらかが的を2つ取ったら即終わり」なのか。書いてください。
この2つは、書くだけなら10秒です。書かないと、1時間悩むことになりますよ。
実例: この箇条書きが、そのまま画面になります
下の「やってみる」で書くルールは、そのまま見本ゲーム三つの的のルールです。書いた1行1行が、完成した画面のどこになったかを見てください。左の列が箇条書きに書いた文、右の列がそれが画面上のどこに現れたかです。
| ルールの行 | 画面のどこに現れたか |
|---|---|
| 札は1から5の数字 | 手札に書かれた数字 |
| 3枚配られる | 自分の手札3枚と、相手の伏せ札3枚 |
| 場に的を3つ置く | 中央の3つの枠 |
| 1枚えらび、置く的を決めて、同時に出す | 札を選ぶ→的を選ぶ、の2タップ。相手の札は伏せて置かれ、自分が置くとめくれる(1台でも「同時」にする工夫。3-3で作ります) |
| 出した札は置いたままにする | 的の上下に並んでいく札 |
| 手札が無くなったら合計をくらべる | 的ごとの「相手 4 / 自分 5」 |
| 的を多く取った方が勝ち | 決着時の勝敗表示 |
ルールに書いた行は、全部画面のどこかにあります。逆に、ルールに書いていないものは画面にもありません。 箇条書きは、そのまま設計図です。
もう1つ、6行目に注目してください。「手札が無くなったら合計をくらべる」——いつ判定するのかまで書いてあります。「置くたびに取り合う」のか「置き切ったあとに一度だけくらべる」のかで、作るものはまるで別物です。書いていなければ、AIが勝手にどちらかへ決めます。
それから、このルールは完成後に1行だけ変わっています。同点の的です。最初は「同点の的は誰のものでもない」と書きました。6章で実測したら引き分けが多すぎて、「あとに置いた方が取る」へ直しています(6-6でやります)。最初から完璧なルールは要りません。書いてあるルールなら、直すのも1行なんです。
ルールの1行は、そのまま部品になります
箇条書きにする理由は、読みやすさだけではないんです。書いた1行が、そのまま1つの部品になります。
たとえば、さきほどの6行目を見てください。
手札が無くなったら、的ごとに合計をくらべ、大きい方がその的を取る
この行は、何かを受け取って、何かを返しています。受け取るものを入力、返すものを出力と呼びます。
- 入力: その的に置かれた札
- 出力: どちらがその的を取ったか
入力と出力がはっきりしていると、この1行だけを取り出して試せます。 絵も音も画面も要りません。札の並びを渡して、返ってきた答えを見るだけです。
逆に、この判定が画面を描く処理と一体になっていると、そうはいきません。確かめるたびにブラウザを開いて、実際に札を3枚置くことになります。
このように仕事ごとに切り分けて、それぞれの入力と出力を決めておくことをモジュール化と呼ぶんですね。日本語にすれば「部品に分ける」です。
同じ入力なら、同じ出力になるようにします
部品には、もう1つ守ってほしいことがあります。同じ入力を渡したら、いつでも同じ出力が返ることです。
これを壊すのは、部品が中で勝手に拾ってくる値なんです。
| 部品が中で拾うと壊れるもの | どうするか |
|---|---|
| 乱数(サイコロ) | 呼ぶ側が振って、出た目を渡す |
| 現在時刻 | 呼ぶ側が読んで、その値を渡す |
| 画面のいまの状態 | 呼ぶときに一緒に渡す |
| 通信で取ってくる値 | 先に取ってから渡す |
たとえば勝敗の判定が中でサイコロを振っていると、同じ盤面を渡しても答えが変わります。答えが変わる部品は、機械に見張らせられません。 何を正解とするかが決められないからです。
それでも、乱数を使いたい場面は出てきます。そのときは、乱数の種(シード)を固定してください。 種というのは、出目を決めるもとになる数字です。同じ種を渡せば同じ目が出るので、同じ入力から同じ出力になるわけです。
つまり、乱数そのものが悪いわけではありません。外から渡せる形にしておけば、乱数を使っても同じ出力を作れます。
そして、いま挙げた2つ(部品に分ける/同じ入力なら同じ出力)は、あとから足すのが一番つらい性質です。すでに組み上がったものを、いったんほどくことになるからです。だからこそ、まだ紙の上にいるうちに意識しておきます。
やることは重くありません。1行書くたびに、その行の入力と出力を言葉にしてみてください。 それだけです。
実例: この形にしたので、カード139枚分を機械が試しています
次の術で出てくる僕のカードゲームは、この形で組んであります。
カードの効果は1枚ずつ違います。ですが、書き込む場所は全部同じです。 このカードはいま使えるのか、使ったら盤面がどう変わるのか。決まった問いがいくつかあって、そこへカードごとの答えを足していきます。だから1枚増やすときも、どこへ書くか迷わないんですね。
入力も固定してあります。テスト用の山札を、並び順まで決めて用意しました。切り混ぜません。同じ山札から同じ手順を踏めば、盤面は必ず同じ形になるんです。
その結果が、これです。
カードのテスト 139ファイル(カード1枚につき1ファイル)
テストの件数 570件
これを人は実行しません。全部、機械が回します。おかげでカードを1枚直したとき、残り138枚が巻き添えで壊れていないかが、待っているだけで分かります。 同じことを手でやるなら、1枚ずつ対戦を組んで盤面を作らないといけません。
もう1つ、AIとの相性もよくなりました。形が揃っているので、テストを書かせられます。 頼み方は「このカードのテストを、隣のカードと同じ形で書いて」だけで十分です。実際、効果そのものを作る前に、テストを先に書かせています。これを専門的にはテスト駆動開発(TDD)と呼びます。
速く作れるようになった、という話ではありません。壊しても気づけるようになったので、思い切って触れるようになりました。 品質と速さは、ここでは同じ話です。
三つの的では、どこまでやるか
カードは139枚もありませんから、ここまでは要りません。守るのは2つだけです。
- 勝敗の判定を、画面を描く処理から離しておく
- その判定に、乱数や時刻を中で拾わせない
この2つを守っておけば、7-2で機械に見張らせるとき、書いたものをそのまま渡せます。守っていないと、そこで作り直しから始まります。
やってみる
docs/plan.mdにルールを書き足す前の術で作った
docs/plan.mdの続きに、先ほどの5つの順番で並べます。文章にせず、1行1ルールを守ってください。## 遊びのルール - 札は1から5の数字。1人1組ずつ持つ - お互いに、自分の山から3枚配られる。残り2枚は使わない - 場に的(まと)を3つ置く - 毎回、手札から1枚えらび、置く的を決めて、同時に出す - 出した札は、その的の前に置いたままにする - 手札が無くなったら、的ごとに合計をくらべ、大きい方がその的を取る - 的を多く取った方が勝ち声に出して読んでみる
黙読だと目が滑るので、実際に口に出して読みます。引っかかったところが穴です。「同時に出すって、1台のパソコンでどうやる?」のように、読むと出てきます。
いま気づけば、直すのはタダです。
AIにも穴を探させる
自分の目だけだと、思い込んでいる部分の穴は残ります。
下のルールで、決まっていないことを質問の形で全部挙げてください。 同点、引き分け、終わり方、同時に出す方法は特に念入りに。 まだ答えは提案しないでください。 (ここへルールを貼る)「答えは提案しないで」が要点です。 決めるのは自分です。ここでAIに埋めさせると、冒頭に書いた「勝手に決められる」がもう起きています。
保存して送り返す
cd my-first-game git add . git commit -m "遊びのルールを書いた" git push並んだことを確認する
この箇条書きが、あとでそのままAIへの指示になります。 3章でこれを渡して作らせます。
つまずきどころ
ルールが多すぎる
10行を超えたら、それは最初の1本には大きすぎます。削ってください。 前の術で決めた「面白さの1行」に効かないルールから消します。
細かいところが決まらない
「カードは何枚あるのか」「同じ数字を2枚持てるのか」のような細部です。とりあえず決めて書いてください。 遊んでみて違ったら直せます。決めないまま進むのが、一番遅いんです。
書いてみたら面白くなさそうに見えた
いい兆候です。紙の上で気づけたということです。 コードを書いてから気づくより百倍安く済みました。ルールを1つ変えて、また読み返してください。
Windows の場合
編集と git だけなので、macOS と同じです。
次の一歩
書いたルールで、紙とペンで1回遊んでみてください。 的の代わりにコースターを3枚置き、数字を書いた紙を3枚ずつ持って、置き合うだけです。
これが最速のテストです。5分でやってみると、次に直すところが自分で分かります!

