はじめに
Pythonでブラウザゲームを作っていたら、randomを使う際の落とし穴を見つけたので、その話を書こうと思います。
randomの反抗
それはタイピングゲームの開発中に起こりました。ローカルで作った後、ブラウザ上での動作確認も済み、公開後に自分で遊んでいた筆者は気づきます。「あれ?これさっきも見た順番な気が...」。そう、何回プレイしても同じ順番でお題が表示されるのです。こうして筆者はタイムリープに巻き込まれてしまいました...では勿論なくて、どうやらrandom.choiceが同じ順番でお題を選んでしまっているようです。
筆者は慌てて他のゲームも確認してみました。そのゲームはrandom.randintを使っているのですが、やはり敵の湧く位置が同じでした。どこに敵が湧くのか、その全てをすでに知っている。筆者は未来視の能力に目覚めました。それはそれで楽しいですが、そのままにしておくわけにもいきません。まずは原因を特定することにしました。
seedの犯行
原因の特定といっても、もうこいつくらいしか心当たりが無かったので、試してみたら当たりでした。ローカルで試している間は毎回違うシード値を使って身を潜め、ブラウザ上で動作させた途端に、毎回同じシード値を使い、問題を引き起こす...今回の犯人の犯行は、計画的で卑劣なものであると言わざるを得ません。
筆者の反攻
このまま黙って引き下がるわけにはいかないので、筆者は次の方法で反撃に出ました。
import time, random
random.seed(time.time())
random.seedを使うと、手動でシード値を設定することができます。time.timeと組み合わせてあげることで、時間ごとに一意なシード値を得られるので、同じシード値が繰り返される事はないわけです。タイムリープのような現象を抜け出すためにtimeモジュールを使う、ちょっとエモい解決策でした。めでたしめでたし。
まとめ
ブラウザゲームを作る際には、randomとtimeを組み合わせてシード値を設定しよう!
最後に
ここまで読んでくださりありがとうございました。ブラウザゲームを作るって人はそう多くないかもしれませんが、他にもこの問題に遭遇する場面はあると思うので、1回試してみると良いと思います。random.seedを使って、逆に固定の配列を用意するってのもあるみたいですね、慣例的に42が使われるんだとか。(というかそれが正規の使い方なのかな?)