2018/12/20発行こんにちは、プログラミング書籍の館の江畑です。前回から少し間が空いてしまいました。MacBookの電源が入らなくなり、しばらく修理に出してまして...思っきりテンション下がってたのが理由です。昔にAppleのサポートは切れていたので、スマホドック24名駅店さんに持ち込みました。「調査中に動くようになったので、修理代はゼロで良いです」との事でした。結局原因は分からずでしたが、とにかく直って良かったです。スマホドック24さんの良心的な対応に感謝です。今回のテーマはドラクエ4とコンピュータサイエンスです。僕の自慢できる白歴史ドヤァァァひどい話クイズの答えクイズあのゲームの文字??ドラクエ4で学ぶコンピュータサイエンスコイン増殖の裏技?今回のテーマはゲームのバグです。バグの原因をコンピュータサイエンス的な視点で見てみましょう。プログラマーはバグを「裏技」と呼んで、修正せず発売しようとします。今回のバグも、僕は裏技だと思ってました。そのバグとは、有名な?ドラクエ4のコイン増殖です。ドラクエ4ではカジノがあり、初めに「コイン」を買ってポーカーやスロットで賭けれます。コインが増えると、交換所で景品(はぐメタの盾とか)をゲットできます。そのコインは1枚20ゴールドするのですが...なぜか枚数を838861枚にすると、わずか4ゴールドで買える裏技があります。当時の子供達(僕含む)はこれを知ってヒャッハーしました。※リメイク版では修正済みですかんたんな解説さてこの裏技、実はバグです。1677万7220ゴールドになります。ところがドラクエ4では、ゴールドの最大値は1677万7215になってます。上限を超えた金額を表示しようとしてる訳です。←5多い!その結果、数字がループして一旦ゼロへ戻ってしまい、すごく安い金額になったのです。この時、支払う金額は以下のような関係になります。←今回はこれ6多い:5ゴールド(以下略)本来なら、1だけ多い1677万7216ゴールドにして、無料でゲットしたい所ですが...コインの金額(20ゴールド)で割り切れないため、一番安いのは4ゴールドになってます。この話をもっとコンピューターサイエンス的に見てみましょう。前述のように、ドラクエ4のゴールド最大値は1677万7215でした。これは2進数で表すと次のようになります。111111111111111111111111ゲシュタルト崩壊しそうですね...コレ1が24個ならんでます。24ケタの2進数です。これを24ビットと言います。言い換えると、ドラクエ4のゴールドは24ビットの整数って事です。現在ほとんどの環境(CやJava)で整数型(int)は32ビットですから、かなり小さいですね。この1677万7215に1を足すとこうなります。1677万7216)1000000000000000000000000なんだかキリの良い数字になりました。後1ケタ増えて25ケタ、つまり25ビットになっています。困ったことに、ゴールドの変数は24ビットしか認識しません...よって増えた25ケタ目の1は無視されます。その結果ゴールドは↓のようになり、0に戻ってしまいました。000000000000000000000000これがコイン増殖バグの仕組みです。1枚20ゴールドのコインを838861枚買うと、必要なゴールドは1677万7220でした。1677万7220を2進数にするとこうなります。1000000000000000000000100さっきと同じように25ケタ目は無視されるので、ゲーム内では000000000000000000000100と認識されます。3ケタ目だけが1ですね。これは10進数で4になるので、コインが4ゴールドで買えてしまう訳です。中の仕組みはともかく、当時の僕はこのバグを裏技だと歓喜し使いまくりました。このバグ、一歩間違うと危険なんですよ。25ケタ目は別の変数の領域だからです。プログラムはゴールド以外にも色んな値を記憶してます。敵味方のステータス、進行フラグ、町やダンジョンの場所などなどところがこのバグを使うと、ゴールドの隣に記憶してあった値を意図せず変更してしまうのです。・もしも隣の変数が全滅フラグで、1ならゲームオーバーになるプログラムだったら...・現段階で1にすると進行不能になるフラグだったら...・不用意に変更したせいで影響が連鎖的に広がり、ゲームがフリーズしたら...ええ、怖いですね。いうのをメモリ破壊バグと言います。今回は特に影響なくて済みましたが、これで回収騒ぎになったゲームもあります。8逃げ会心ドラクエ4には、もう一つ有名な裏技があります。それは8回逃げた後に攻撃すると必ず会心の一撃が出るというトンデモナイ技です。「8逃げ会心」と言います。実はこれもメモリ破壊バグです。ドラクエ4では、逃げた回数を2進数2ケタ(2ビット)の変数に入れてます。ところが、8という数字は2進数では1000のように「4ケタ」になってしまいます。あふれ出た4ケタ目の1は、やはり別の変数を書き換えるのですが...これが偶然にも、パルプンテ(何が起こるか分からない魔法)の会心発生フラグだった為、会心の一撃がバシバシ出るようになったのです。(なお3ケタ目は時の砂に関するフラグらしい)このバグもメモリを破壊してますが、たまたまプレイヤーが喜ぶ現象だったので「裏技」として広まったケースです。【今日の格言】バグと裏技、紙一重さて、今回はドラクエ4のバグをコンピュータサイエンス的に見てみました。無味乾燥で退屈な2進数も、こうやってゲームを例にすると少し鮮やかに見えて来ませんか?色んなゲームバグの仕組みを知ると、ゲーム画面とリンクしてコンピューターの動きが分かります。こんなコンピュータサイエンスの学習も面白いと思います。僕も講義をする際はいつも楽しげな具体例を話すようにしてますぜヒャッハー。メルマガでも色々なゲームバグを紹介したいと考えてます。Twitterハイライト今月はこんなこと呟きました。2018年12月5日これがザクに見えたら貴方は疲れてますこれがザクに見えた。2018年11月27日ひどい話クイズの答えさて、前回出題した「ひどい話クイズ」の答えです。次のうち、僕が実際にやった事の「ない」ものはどれでしょうか?(つまり3つは本当です)A:同僚が椅子を投げて喧嘩を始めたけど、面倒なので止めもせず昼飯へ行ったB:バグを解明しても報告せず、究明してるふりして2ch見てたC:デスマーチがダルくて、勤務中に酒を飲んでいたD:前向きなメールに縦読みで本音を仕込んでた(例:たぶんむり)正解はCでした。デスマでSAN値削れてステ異常な時に酒なんか飲んだらリバース確定ですからね...今回は13人の方に応募いただき、正解者は6名でしたパチパチ。うち3名の方には、Amazonギフト券をメールで送信しました。これで家でも買うといい。