HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2016
0820
GTAndroidの乱数を再現できますか?23解決


GT

リンク

2016/8/20(Sat) 20:09:16|NO.76666


randomize 0 redraw 0 repeat 10 mes rnd(10) loop redraw 1
このスクリプトで10個の乱数を表示しますが、
Android、windows、iOSで同じ数字になりません。
Android側の乱数を再現したいのですがスクリプトなどで実現できますか?
(再現できればスクリプトでなくてもOKです)



この記事に返信する


可憐

リンク

2016/8/20(Sat) 20:43:16|NO.76667

このような感じですか?


http://lhsp.s206.xrea.com/command/rnd.html #define MAX 10 randomize dim kekka, MAX repeat MAX value = rnd(cnt + 1) kekka.cnt = kekka.value kekka.value = cnt loop repeat MAX mes kekka.cnt loop



沢渡

リンク

2016/8/20(Sat) 20:56:33|NO.76668

こちらの過去スレ↓のdonn氏の、普通のHSP3のrnd関数を再現したスクリプトに、
ちょっとだけ手を加えたものです。
(たぶん手を加える必要はなかったと思いますが、あくまでも念のため)
http://www.hsptv.sakura.ne.jp/play/pforum.php?mode=pastwch&num=59586

#module
#deffunc randomize2 int seed
holdrand=seed
return
#defcfunc rnd2 int maxn
holdrand = (holdrand * 214013 + 2531011)&0xffffffff
return (holdrand>>16&0x7fff)\maxn
#global

randomizeの代わりにrandomize2、rndの代わりにrnd2を呼ぶと、環境に関係なく結果が同じになる筈です。
「Android側の乱数を再現したい」という希望にはそえないかもしれませんが、これでよろしければ。



沢渡

リンク

2016/8/20(Sat) 20:57:34|NO.76669

あ、preで囲むの忘れました。見づらくてすみませんm(_ _)m



KA

リンク

2016/8/20(Sat) 21:17:22|NO.76670

そもそも違う環境で同じ値になる物を乱数と呼べるの?

その1:事前に乱数表を用意する。
その2:自前で乱数を実装する。
その3:既知の乱数を利用する。

どっちにしても乱数を発生させるパラメータを、ある程度制限
する必要があります。



GT

リンク

2016/8/20(Sat) 21:36:20|NO.76671

可憐さんありがとうございます。
出現した数値を2度と出さないchokkoさんのスクリプト(^^)
この発想すごいですよね。感心してしまいます。
でもスイマセン。AndroidのRND命令で出力した乱数を他のプラットフォームで再現したいです。


沢渡さんありがとうございます。
VC++の乱数発生ですね。簡潔に改造までして頂きありがとうございます。
これはこれでありがたく利用させて頂きます。(^^)
おっしゃってる通り、AndroidのRND命令で出力した乱数を他のプラットフォームで再現したいです。
iOSはobjective-c? AndroidはJAVAよりの乱数発生装置なのかなと思いますが、
知識不足で調べても実現できるのかもわからない状況です(泣)


KAさんありがとうございます。
Androidの乱数発生を実装できれば嬉しいですが知識不足ですいません。



zakki

リンク

2016/8/20(Sat) 22:35:59|NO.76672

各環境でのCランタイムのrand()を使ってるので環境ごとに挙動違いますね

試してませんがAndroidのbionic libcのrand()はrandom()使ってるっぽくて
https://android.googlesource.com/platform/bionic/+/master/libc/bionic/rand.cpp


ここのCの実装を真似すればいけるんじゃないかと思います。
http://www001.upp.so-net.ne.jp/isaku/rand.html



zakki

リンク

2016/8/20(Sat) 22:59:36|NO.76673

>>KAさん
同じの出るのまずいときは疑似乱数使わずに、WindowsのCryptGenRandomやAndroidやiOSの/dev/randomのような暗号論的擬似乱数生成器を使うしかないような



Velgail

リンク

2016/8/20(Sat) 23:20:55|NO.76674

実装を真似する……もとい移植してありますよ。メルセンヌ・ツイスタとか。
http://hsp.tv/play/pforum.php?mode=all&num=72960#75302



GT

リンク

2016/8/20(Sat) 23:46:53|NO.76675

zaikaiさんありがとうございます。
参考先の記事を読んでいる途中で頭から煙が出てきたようです。
48ビット線形合同法などがHSPで実現できるのか(多分頑張ればできるかも)
seed値の解析ができれば良いですがどうにも力量不足で情けない。
本当の乱数ではないと言う話も大変興味がありますが、
HSP3Dishのrnd命令で吐き出したAndroidでの値を再現できれば満足です(^^)


Velgailさんありがとうございます。
「HSP3Dishのrnd命令で吐き出したAndroidでの値 = メルセンヌツイスタ」
と言う認識でよろしいんでしょうか?
もしそうであれば速攻解決で大変感謝であります。
参考先には目にウロコの情報が沢山で助かります(^^)



GT

リンク

2016/8/20(Sat) 23:49:20|NO.76676

↑すいません zaikai× zakki○ さん



GT

リンク

2016/8/21(Sun) 00:17:22|NO.76677

早とちりですいません。メルセンヌツイスタと言うことではなかったですね。

恥ずかしながらなぜこのような質問になったのか説明します。
・すでにHSP3DishでAndroidアプリを作ってある
・randomize (ステージ数)にてrnd命令でカード配置をパターン化してある
・そのままHSP3DishでiOSに移植
・カード配置がAndroidと違う(同じ攻略パターンが使えない)
と言うことでAndroidの乱数発生パターンを再現したい訳です。
次回作る時はこんなことにならないように皆さんのスクリプト使わせて頂きますが後の祭りです(泣)



ZAP

リンク

2016/8/21(Sun) 13:46:27|NO.76683

Android側で発生させた乱数発生パターンをぜーんぶテーブルにして
iOS版ではrnd関数ではなくそのテーブルから数字を持ってくるようにすればいいのでは?

メモリを大量に消費しますけど・・・



(--)

リンク

2016/8/21(Sun) 14:20:15|NO.76685

>> NO.76677
目的としては各環境(Android,iOS,Windows?)での乱数発生方法を統一したいと
いうことなのであれば、敢えてAndroidのrndを再現しなくてもいいんじゃないでしょうか。

自前で乱数生成関数を実装して、それを
#undef rnd
#define global rnd ...
でrndに置き換えてしまえばいいと思いますが。
実装はメルセンヌ・ツイスタでもいいですし、Xorshiftなどでもいいと思います。



沢渡

リンク

2016/8/21(Sun) 15:44:41|NO.76687

もうすでにAndroid版をリリースしていて、引っ込みが付かなくなっているという状況なのではないでしょうか。
私だったら、これまでのAndroid版のステージは「Androidでのみ遊べるスペシャルステージ」と位置づけ、
それとは別に全環境で同内容の「通常ステージ」を収録すると思います。



zakki

リンク

2016/8/21(Sun) 16:23:05|NO.76688

Androidのrand()ってrandom()じゃなくてrand48()なんですか?



GT

リンク

2016/8/21(Sun) 17:42:54|NO.76689

>>ZAPさんありがとうございます。
テーブルは割と簡単に実装できそうです。
しかしステージ数900×カード数53枚=47700
大したことないといえば大したことないようなデータ量ですが・・・
あとAndroidで記録したデータを持ってこれませんが、
幸いhttpload,httpinfo命令が使えるのでネット経由でデータを持ってきてとか大変かもです。

>>(--)さんありがとうございます。
次回作るアプリでは絶対にそうします。

>>沢渡さん察して頂きありがとうございます。
リリースしてしまっていてその通りです。妥協してその方法にしたいです!

>>zakkiさんの回答にはなりませんがrand48()であってほしいです。
そうすればスクリプトで何とか実現できるかもですが、変数64(48)ビット扱ったりと厄介かも・・・。
自分なりに調べてHSPインストールフォルダの
「android/hspproj/src/tv/hsp/HspActivity.java」に、
「import java.util.Random;」とありました。
これで「javaのクラスRandom」なのではと思い、
そうであれば「48ビット線形合同法」で処理されてるのかなと勝手に思ってます。
あくまで憶測です。すいません。あまり詳しくないので間違った認識かもしれません。



(--)

リンク

2016/8/21(Sun) 22:05:58|NO.76693

ちなみにGTさんの最初のスクリプトは、Androidでどういう結果になりますか?

randomize 0 redraw 0 repeat 10 mes rnd(10) loop redraw 1



zakki

リンク

2016/8/21(Sun) 22:38:16|NO.76694

HspActivityのRandomクラスはimportされてるだけで使われてなくて
WebGLではstd::mt19937がそれ以外では各環境のCランタイムのrand()が呼ばれるはずです。

http://dev.onionsoft.net/trac/openhsp/browser/trunk/package/win32/android/hsplib/hsp3/hsp3int.cpp#L1390



GT

リンク

2016/8/22(Mon) 00:01:04|NO.76695

>>(--)さん
最初のスクリプトはそのままではビルドできませんのでもう少し丁寧に書くと

#include "hsp3dish.as" redraw 0 color 1,1,1 boxf color 255,255,255 pos 0,0 randomize 0 repeat 10 mes rnd(10) loop redraw 1 stop
HSPのバージョンによるものかバグか結果で問題が起きました。何種類かの違う結果が出てしまいました。
数字1個目の4 と2個目の0 が固定で、3個目からバラバラの数字が出てしまいます。
ただ、1番多く出力される結果は2種類あって
4041624818 と 4041112810 です。(横表示ですいません)
これは大問題です。アプリ起動した直後は不安定なのか WAITかけないとダメなのかな・・・
Windowsでは常に 8987575502
ちなみにhsp3dish.jsでは常に 5033793524 でした。



GT

リンク

2016/8/22(Mon) 00:09:01|NO.76696

>>zakkiさん
そうなんですね!勉強になります。
ちなみに、もしや hsp3dish.jp と出力結果が同じになるかも!と思い試しましたが違う結果でした。
これはWebGL側のメルセンヌツイスタ(std::mt19937)の値なんですね。


Androidの挙動がおかしいのもあり、しばらく頭を冷やそうと思います。



(--)

リンク

2016/8/22(Mon) 07:21:14|NO.76697

>> GTさん
確かにHSP3Dishのrndは各環境のrand()を呼び出していたので、
Androidでの実装を追っていったところ、rand48が使われていることが分かりました。
(ただし、Android APIのバージョンによっては変わるかもしれません)
それを単純に移植しましたのでここに置いておきます。
http://ux.getuploader.com/blackcoffee/download/1/rand48.as

これを実行すると、4041087204 となります。
最初の4つ(4,0,4,1)が、一番多く出力される結果と一致していることで確信が
持てましたが、その後不定になってしまうというのが良く分かりません。
調べてみたところ、hgdx.cpp, hgemitter.cppなどでrand()が呼び出されており、
それが関係しているのかもと思っています。
ただAndroid上でのHSPの実装がどうなっているのか分からず、どのタイミングで
rand()が呼び出されるのか分からないと他のプラットフォームへの移植は
難しいと思いますので、やはり既にリリースされたAndroidアプリのほうを更新できる
のであれば、自前で乱数を実装してすべての環境でそれを呼び出すのが得策かなと。



GT

リンク

2016/8/22(Mon) 08:13:47|NO.76698

>>(--)さん有力情報ありがとうございます
現在試せる手段がありませんので
家に帰ってから色々やってみたいと思います!



GT

リンク

2016/8/22(Mon) 23:23:56|NO.76699

>>(--)さま
「Androidの乱数を再現」は移植して頂いたrand48で出来るということで、
今回の件は無事解決ということになりました。感謝です!
お付き合い下さった皆様大変ありがとうございます。


以下、余談です。

検証環境
hsp3dish Helper Ver1.4と1.2
Java JDK6
SDK 24.3.3
NDK r8d
ant 1.8.4
API 17 (Android4.2.2)
Windows10 32bit
Android実機 elephoneP2000,Kindlefire,optimusL-01d,nexus7,dtab01,(BlueStacks)

Android実機でHSP3dishの動作がイマイチ不安定です。
(擬似)乱数の統計など滅多に取らないので気付きませんでした。
乱数に限らず内部初期値のパラメータを変更する命令などが不安定っぽいです。
画像の拡大縮小も表示されたりされなかったり・・・
今回、乱数(randomize,rnd命令)について試しています。
前のスクリプトではやはり数値が一定しません。機種によってはループ2個目から違う。
ループ1つ目はどの機種も「4」が出ました。
少しでも動作が一定するようにスクリプトも変更しました。

#include "hsp3dish.as" wait 10 a=“” randomize 0 repeat 10 await 1000/60 a=“”+a+rnd(10) loop redraw 0 color 1,1,1 boxf color 255,255,255 pos 0,0 mes a redraw 1 stop
結果は、ほぼどの機種でも 4041085440 になりました。が、
50回に1度くらい、下4けた(ループ7回目以降)の数字が不安定だしrand48と違う。
ちなみに、
randomize 0
標準rnd → 4041085440
rand48 → 4041087204

randomize 1
標準rnd → 4355750118
rand48 → 4355752172

randomize 2
標準rnd → 3578392975
rand48 → 3578394731

hsp3dish Helper Ver0.8辺りには上記のような不具合?はなかったような気がするので、
移植して頂いた「rand48」も何の変更なしに素直に組み込めるため利用させて頂きます。
特定のステージを攻略した動画もすでにアップしてあるため、
そのステージは乱数を使用しないで変数テーブルで対処しようと思います。
上記不具合がいつから発生しているか分からないので、1万DLの少ないうちに修正しようと思います。

もっと乱数を煮詰めていればこんなことにならなかった・・・
不安定なのはアプリ開発者だったり・・・ orz



ONION software Copyright 1997-2021(c) All rights reserved.