れぶろぐ -ザ・フォース-
新シーズン始めます
RECENT ENTRIES
スポンサーサイト
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
--/--/--(--) --:--:-- | スポンサー広告 | Trackback(-) | Comment(-)
もはや経済学じゃないぞ
コンピュータにおける「ランダム性」とは何か。これは「擬似乱数」と呼ばれる一見すると乱数に見えるような数列を生成するプログラムを元にしています。

これを詳しく説明してもしょうがないのでざっくり解説すると、ある数から別の数を作る関数があって、その関数を用いて順々に数を作っていく仕組みです。数学的には漸化式と呼ばれるもの。おそらく二項間(直前の数字だけを用いて新しい数を作る)漸化式が主流だと思うんですが、もしかしたらそれ以上のもあるかもしれません。まぁ通常プログラミングで使う乱数生成関数は二項間のはずです。

で、ここで知っておいてほしいのは一般的なプログラミングで用いる擬似乱数生成器にはある脆弱性があって、
・内部構造を知っていれば、次にどんな数がくるか予測がつく
・大抵の場合、周期が存在する
という2点。すなわち、欠損がなくかつ十分なサンプル数を用意すれば、メイプル内においてもあらゆるランダム現象を予測できるということです。

だからたまに耳に入る「ある程度適当な書を使って成功・失敗パターンを取得すれば、傾向が読める」とかっていういかにも胡散臭い話も100%は否定できないわけです。

とは言っても…99.9%は否定できますけどね。たとえプログラミングをちょっとかじっただけのようなやつでも、擬似乱数生成の仕組みを知ってある程度の対策をすれば、数万オーダー以上の周期にすることができますから。メイプルというそりゃ素晴らしいゲームの開発者がこの程度のことをしてないはずがありません。

しかも乱数を生み出す際の元となる行動はサーバー全体が対象でしょうから、まぁサーバー全員の行動を制限しないと予測など不可能。上記の妄言を言ってるような人がいても信用しないのが吉です。

ついでに言うと囮書なんてものも全くもって関係ないです。ジンクスなら構いませんが、理論的裏づけは皆無です。まぁそういう奇特な人たちのおかげでクズ書が売れるなら、それを利用してやるほうが勝ち組ですね。




もう一つプログラムに関連した話題。現在の1キャラが持てるメルの最大額は2,147,483,647ですが、一見するとキリの悪いこの数はどっから出てきたんでしょう。

これは「符号付き32ビット整数型の最大値」ってやつです。32ビットっていうのは要するに2進法表示で32桁まで表せますよ、ということ。なぜ2進法なのかというと、コンピューター内部では全てのデータが0または1で表現されているからです。

例えば、メルをちょうど100m持っていたとすると、内部では

0, 0000101111101011110000100000000

ってな感じで表されています。最初の離れた0は符合を表していて、1だと負です。メルだと負数はいらないので常にここは0です。

ということは、数値を表現するために使えるのは31桁で、この31桁を用いて表せる最大の数がさっきの2,147,483,647なのです。

ところでよくドラクエのステータスカンスト値が255だったりするのは、符号無し8ビット整数型の最大表現数が255だからです。2進数表現だと
00000000 ~ 11111111
がステータスの範囲になります。



ところで個人的にインフレの影響として最もまずいのは「メルカンストがあまり大きな数でなくなってしまったこと」だと思っています。今の相場だと価値として2,147,483,647メルを超えるものが珍しくないわけですが、こういう商品を取引するには現状だと危険を冒して信用取引するか、MTSに出品するしか方法がありません。まぁ切手があれば安全に取引できたんですがね。あ、物々交換って手もありますか。

こういう状況を打開するなら、インフレをなくすか、プレミアム切手を復活させるか、カンスト額を引き上げるしかなさそうに思えます。ただまぁどれも難しそうですけどねぇ。

もしメイプルのプログラム(の根源的な部分)をいじれるならば、カンスト額を引き上げる方法はなくもありません。

基本的に符号付き32ビット整数型っていうのはC言語というプログラム言語なら"int"という宣言を使って定義されますが、このintの部分を変更してしまえばいいのです。使えるデータを動かしたくなければ、符号無し整数型("unsigned int"という宣言)にしちゃえば表現できる最大値がほぼ倍になります(符号を表す1桁を数値表現に使えるから)。これなら実際のメルの桁も増えないからインターフェースをいじる必要もないし、なかなかいい案だと思うんだけどなぁ。

Comment
≪この記事へのコメント≫
ランダム関数(疑似乱数を発生させる関数)は、ある値を参照してその値を基にある数値を出力するもの。参照値が固定されていれば、(処理環境が同じ場合)必ず同じ周期が出てしまう。
でも、普通はそうならないようにしてます。一般的に参照値に使われるものは常に変化する数値・・・つまり「時間」。
rand(time());
ということは、1秒毎に参照される値が変わるから出力結果も変わり、予測や周期なんか普通は出来ないのですよ。ランダム関数を扱う上での基本です。
更にランダム性を高めたければ、時間関数に加えてキャラクターの座標とか参照すればいいだけ。

unsigned intは現状においては俺もいい案だとは思うけど、その現状が気に食わないからもっとメルを回収するようなことをして欲しいなぁ。
2008/10/20(月) 05:18:00 | URL | 揺月 #Tx0QuhMQ[ 編集]
何の言語について言ってるのか定かじゃないけど、rand(time)というのはないよ。C言語ではrandは引数をとらない。javaの場合は引数をとるのはコンストラクタ(つまり乱数ジェネレータの初期化)のときだけ。他もたぶんそうでしょう。

普通やられるのは乱数「種」に時間を入れる(C言語ならsrand(time(NULL))で種を変えられる)のだけど、これは一種の乱数に一度しかやりません。乱数を呼び出すたびに時間を引数にして乱数種を変えてたらそれこそ乱数じゃないね。それは時間を引数に持つただの関数。

そもそもなぜ乱数種に時間を入れるかといえば、それは「周期をなくすため」ではなく、「プログラムを実行するたびに違う乱数を出力してほしいから」です。プログラムの入門でもこのように説明されてるんじゃないかな。

だからあくまで連続的にプログラムが実行されている限りでは周期は不可避です。ちなみに周期を伸ばすことは可能で、自分が使ってるプログラムでも長周期型の乱数ジェネレータを自作してます。もっといいのがほしければメルセンヌツイスタとか使えばいいのかな。


…まぁ、メイプルのプログラムでもしかしたら毎回srandしてんのかもしれんけど、そんなメモリリッチなことはまさかしていないだろう。
2008/10/20(月) 08:22:34 | URL | れぶち #-[ 編集]
srand((unsigned) time(NULL));
正式に書くとこうか。Cから離れて3年だしな・・・。

>…まぁ、メイプルのプログラムでもしかしたら毎回srandしてんのかもしれんけど、そんなメモリリッチなことはまさかしていないだろう。

ってのが焦点だけど、中身見てみないことには分からないからねぇ。
でも、暴風みたいな高速攻撃は分からんけど、他は可能性高いと思うけど?
2008/10/20(月) 16:31:48 | URL | 揺月 #Tx0QuhMQ[ 編集]
あーたーまーいーたーいーw
2008/10/21(火) 18:57:00 | URL | 起亜 #-[ 編集]
コメントを投稿する
URL:
Comment:
Pass:
Secret: 管理者にだけ表示を許可する
 
Trackback
この記事のトラックバックURL
≪この記事へのトラックバック≫
Designed by aykm.
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。