2020年12月31日木曜日

100ゲームを集計

詳しい結果はまたあとで書く可能性あり。
とりあえず、100ゲーム分やった結果によると
6BETを3面で100ゲームなので、トータル1800BET。
これに対してOUTは1230であり、ワンダー抜きのPO率は68.3%となった。
また、開始時にFREEが1個だけ出現した割合は69.4%、FREE2個出現が25.4%、FREE3個出現は5.2%ほどであった。ただし自動探査なので違う情報が入っていることも少々ある点に注意。

いやしかしこれは100%を超えようとすることはこのままでは不可能な気がしてきた。
あの当たりにくいラウンドワンのアニマロッタでPO率90%くらいときくので、70%を優に割っているこのコナステを果たしてどうとらえるべきか…。
掲示板で全然当たらないというのも納得である。

しかしまだ当たらない、というには早計である。
もっとデータをとり、もっと戦略を練り、さらに高い精度で記録できて初めてビンゴバルーンを真に解析したといえるだろう。
というわけで詳しい情報はまた後程。

2020年12月30日水曜日

エクセルへの反映状況

 6BETでやっているのに、メダルが何百枚あってもすぐに消える。

なお、上がその自動稼働の際に入手したエクセルのデータである。

ライセンスがないらしく、操作はできないし保存もできない。しかし平均ならばとれるみたいなので、それをやったところ、平均は4.987とでた。

これは26ゲーム分、つまり78個のビンゴバルーンの実践で得た結果となる。

このデータを取得するときに、やはりバルーンの最適解入力がどうも甘いので以後はここを確実にする方法を考えようと思う。ところどころ欠けているマスがあるが(5ケタの部分)、これは最適解に至るまでのIDを算出するところで、賭けているということはその操作に到達していないことを意味する。ただしリザルトは完全に入力できている。

あと、最も上のゲームにFREEが3個配置されたことは一度もないらしい。

これではPO率が83%なので、以前よりましになったといえども、まだまだ実機の標準PO率には程遠い。

なお、FREE配置個数は

1個 53回

2個 22回

3個 2回

となっている。うち1回はプログラムがおかしくなり、0を返してしまった。

入手個数は、判明しているもので

1個 45回

2個 19回

3個 0回

4個 0回

他にも2ゲーム目と3ゲーム目のFREE出現位置が同じなど、かなり怪しい部分もあるので上記の値はあまり信用できない。ただし、この値からそこまでぶれることはないと考えてよい。

ちなみに、過去の我の計算によると、各FREE配置可能個数での平均PO率は以下。

FREE0個配置 7.6%
FREE1個配置 43.8% 
FREE2個配置 189.9%
FREE3個配置 488.2%
FREE4個配置 1535.8%

上記配置可能FREE数とこの平均PO率から理論上のPO率をたたき出すと、

(49/64)*0.438+(15/64)*1.899=0.765625*0.438+0.234375=0.33534375+0.445078125

=0.780くらいとなり、PO率は78%である。

実際のPO率83%にかなり近い数字となっている。


他にも、初期配置FREE個数から理論PO率を算出できるし、少々大変だが、初期配置FREEの位置から理論PO率も計算できる。

もし初期の段階での理論POが高いのに、後半に行けば行くほど低くなり、実際の値はさらに低い、となると操作をしている疑いが高くなる。

とりあえずはもっとデータを正確にとれるシステムの構築を目指していくことになる。

あとエクセル、これはもう買ったほうが良いだろう。


ちなみに、せっかくなのでチェーンボンバー大辞典のように、画面上に配置された番号、色、爆弾の位置関係から理論PO率を推測し、それを実際結果と比較するチェーンボンバー超大辞典みたいなものも暇なら作ってみようかと思っている。

チェーンの内部処理はuwscでは大変なので、そこはすでに演出付き8ゲームすら実装できている我の自作アニマロッタのプログラムを流用するとする。

ここへきていろいろ役に立ってきたわ…。

ビンゴバルーン自動稼働の様子

 いよいよ放置しながらエクセルに結果を反映させ、その様子を見ている。

その雰囲気だと、赤バルーンの判定はほぼ確実に行われている。ただ、少し移動できるよ!の文字がシンキングタイム中に一瞬でかくなるのでそのときに若干の誤作動がごくまれに発生するくらい。

FREEの配置可能個数の判定は極めて正確。ただしその後の最適解配置は、やはり6連続クリックを行っていてもなかなか認識してくれない。そのため、1ゲーム分の処理に時間がかかり、たまに3ゲーム目に間に合わないことも。

別のPCに動作させたため、処理速度が遅い問題はかなり軽減され、夜通し放置していても大丈夫そうなくらいにはうまく動くようになった。

なお、6BETずつ3面という非常に少額で自動マクロを行っているが、メダルの減りが速すぎる。とてもではないが遊べるような設定ではない。

そういうつもりならこちらもそれ相応の策を練らねばならない。

2:13 12 0 6 メモ ワンダ30

2020年12月29日火曜日

エクセルへの入力方法

 難しそうかと思われたがこれは普通に、(名前).CELLS(1,11)=""みたいな感じでよいらしい。

エクセルを本来は複数個起動してやりたいが、なんか面倒そうなので最適解データの11列目からを使うことにする。そのデータをエクセルオンライン側に送り込んで、そこで編集をしようと思う。あくまで暫定的な保存場所ということになる。

あとはこのエクセルへのゲーム状況のコピペを、3ゲームにするのみである。

そしていろいろあって、ようやく完成。

これは我の考案したコナステ自動最適解配置機(仮)である。
上野画像で、黄色にバルーンを配置しているが、これは3面分を最適解配置プログラムにのっとって自動で配置したものであり、下のエクセルにはそれらの情報が保存されている。ちょっといろいろ未完成だが。
一応デバッグウィンドウ的な感じで、ちゃんと操作を行っているかを確認している。

いやしかしこの動作の挙動を見ていて思ったのだが、十数秒に1回くらい画面がかくかくして1ゲームに数回は数秒間まったく動かないラグが生じるので、このプログラムでもその間にクリックしようとするとそれが通じず、後々の操作もくるってしまう。
こうなれば、もっと快適にゲーム画面を見られるようなPCへの移行が必要ということになる。
ちょっとそれで夜通しやってみるか…?いやしかしまだそこまで堅固でないので怖さはあるが…。

我のUWSCのプログラムへの慣れがなさすぎるせいで500行程度に膨れ上がってしまい、なんかループ対応も汚い。あとでどれとどれがつながっているか見づらい。

おまけに表現方法をあまり知らないので原始的な関数の組み合わせになってしまっているし。

何よりすぐにゲーム画面がかたまるのがもういやでならない。

しかしここまで来れば、我の描いているマクロツールにずいぶん近づいたことになる。

明日にはもっといい線行っているかもしれない。



最適解を実際に自動配置

 かなり苦戦したが、なんとか最適解を実際においてくれるようになった。

この間、赤バルーンの強固な判定を得るにはどうするか、シンキングタイムをどう見分けるか、FREEの配置可能個数をどう判別するかなどかなりいろいろ試行した。

その結果が↓。

たしかに、マウスカーソルが3マス目(18の番号)に行っていることを示そうと思ったが…そうやスクリーンショットはマウスポインタが入らないんや…。
しかし、勝手にマクロが最適解を探知し、しっかりと3マス目においてくれた。cando(感動)

あと一応、初期FREEの個数も取得して、シンキングタイム中にのみこの動作を行う(判定は左下の残り球数が3と表示されているとき)
FREE配置可能個数もやはりchkimgxで行っている。バルーンはchkimgxではうまくいかなかったのでpeekcolorに回帰した。

次のパターン。
今度は、3球終了時点での各種状況。
たしかにFREEの配置可能個数は、数字2を参照できており、2の値をとっている。
さらにINした位置もしっかりと正しい位置を正確に把握している。

ここまでくるといよいよ実用化も近づいてくる。
あとはちゃんとクリックしてくれるプログラムを作り、それをエクセルへとぶち込む。
他には、5球終了時とその後3球がどこに入ったかのデータが欲しい。
ビンゴバルーンにおいては、この5球を境とした前と後ろでは、順不同である。
例えば(1,2,3,4,5)ときて(6,7,8)ときても、(1,2,5,4,3)ときて(8,6,7)ときてもこれは同一。ただし(1,2,3,6,7)と(4,8,5)の組は同一でない。なぜなら5球目まではFREEを任意に配置できるからである。
したがって各ボールの番号を判別する必要はない(入った番号を判別するのは結構面倒なにおいがする)

実際に自動配置した様子は以下。
これは、我が操作したわけでもなく、はたまたおまかせオートをしたわけでもない。
画像データからこれをID化し、それをもとにあらかじめ蓄積した最適解データを取得し、それをuwsc側に戻してきて、その位置をクリックさせたのである。

しかしこのクリック動作、万が一クリックしたが向こうに反映されていないという可能性も考慮し、このクリックの動作の後、FREE配置可能個数が0となればうまく配置できたことになるが、そうでない場合は、配置しきれていないのでもう一度同様の動作を行わせるようにしている。ただしその際自身の置いたバルーンが誤作動しないように最適解配置位置の固定が必要である。

あとはこれらのデータをエクセルに反映し、さらにこれを3ゲームでできるようにし、加えてその精密性を何度も実験して確かめなければならない。

しかしここまで来たら、いよいよ実用化できる段階にまで来ている。
まあいつもFREE1個でHITせずの状態ばっかりなのでたぶん最適解配置をしても大負けすると思うが…。
そこのあたりはもっと後の話となる。

あと入った番号の順番も一応記入しておこうと思う。何か法則があるかもしれないし、はたまた録画の可能性ももしかするとあるかも。

とにかくたくさんのデータが必要なので、6BET3面で18BETを行い、PO70%だったとしても1回あたり5枚程度のロスなのでこれならかなりの試行回数を稼げる。










2020年12月27日日曜日

chkimgに再度挑む

なんかchkimgではうまく画像を読み込めないので、それを拡張しているchkimgxを導入することにした。

さて、我が行いたいのはFREEの設置である。

とりあえず最適解の取得は完了したので、これを座標指定してBTN関数でぶちこむ。

2020年12月26日土曜日

750枚を使ってPO率やFREE個数の推移を検証

 約50ゲームを20BETずつ、3面で計60BETを行い、その様子を見た。

上野グラフは、各面ごとの配当数を表している。一律20BETなのでPO率を表しているといってもよい。(ただしスケールは違うので注意)

20という値を上回っていれば、PO率は100%を超えている、ということになるが…。

このグラフを見てわかることは、50ゲーム、すなわち150ゲームやっているにも関わらず、7個ラインはおろか5倍以上の配当が一度も出ず、星がワンダー数回分しか増えないというもの。全体としては総計3000BETなので、3000BETで通常ゲーム分の☆は0個、ワンダーチャンスはこの間に3回行われており、合計55WIN。

PO率としては50ゲームの区間でおよそワンダーなしが73%、ワンダーありが75%というものである。このPO率は、極めて悲惨というほかはない。

実際、設定PO率が90%程度であるらしいので、これは相当当たっていない、といえる。

具体的に言うならば、もし1万円で4500枚のメダルを購入し、1ゲームごとにビンゴバルーンに100BETずつ、計300BETしたとき、60ゲーム分、すなわち実機ならば1回あたり2,3分なので、2,3時間経過すると4500枚すべてを失う、ということである。

しかし我がやりたいことはこれではなく、この統計で山と谷をうまく把握する方法を得たいというものである。

そこで、ゲーム開始時に配置されるFREEの数とPO率の関係を集計したところ、相関係数は0.28程度で、これは相関がほとんどない、とみてよい。つまり最初に配置されるFREEの個数では、PO率を判定するのは難しいということになる。

一方、配置されたFREEに対するHITしたFREE(取得率と定義する)とPO率の相関係数は0.56もある。これはそこそこ相関があるということになる。

あと、各ゲームごとのPO率の推移をみると、BET数以上WINを得たときの次のゲームでBET以上を得られるのは、17回中わずか4回である。

なお、全体を通じてみると、51回中BET数以上の返却は、17回である。

まだ誤差の範囲であることを否定はできないが、やはり大きく当たった後は次の回でBETを下回るイメージである。


他にも、BETを下回ったWINの4回以内にBETを上回るWINが発生していることもわかる。

この辺りの考察は、まだ50回しか試行していないのでもはや確証性はないが、とりあえずこのような仮説を立ててみて実際にプログラムを動かして、だいたいの場合でうまく行っていればよいわけで、その精密性はここでは問題ではない。


例えば上記の結果から、以下のようなプログラムを組んで、普通にやる場合と比較してみるのもよいのである。

1.毎回5BET3面で賭け続ける

2,毎回5BET3面だが、BET以上のWINを得た場合、その次の回だけは賭けるのをやめ、

BET未満のWINとなったとき、BET以上のWINが出るまで賭けることを続ける

など。

とりあえずは、まずは最適解をコナステに打ち込むプログラムが必要であるから、ここから作っていく。

(いやしかしワンダー込みのPOが75%ではどうやってもこれ勝たれへんのちゃうか疑惑が浮上)



コナステに最適解を入力

 後は最適解をコナステに入力するわけである。すでに各マスの座標は定義してあり、念のためにマスの中心をクリックする、ということにしようと思う。

さらに、そのクリックが確実に行われなければならない。その確実性を高めるための方法の模索がこの記事でのメインとなるだろう。

以前実験したところ、コナステではクリックの動作をしているにも関わらず、クリックした判定にならないということがまれに発生する。

それを避ける方法は以下。

1,複数回クリック信号を送る

2,クリック状態の時間を延長する

このあたりをいろいろいじくって、完璧にクリック判定をしてくれるパターンを探ろうと思う。

チェーンボンバー大辞典について

 ここまで書いているのでなんとなくわかると思うが、我はアニマロッタ初心者などではない。

いずれはとある大きな野望を達成しようとしているが、ここではそれは言わないでおく。

題名にあるように、チェーンボンバー大辞典というものの存在を我は知っている。これを作ったのはみそodenさんで、我がすごいと思う人物の一人である。

彼はアニマロッタ初代、2のころにボール落下位置を予測してアニマロッタで大稼ぎしたり、このようにプレイヤーに有利に働くツールをいろいろ作ったりした大物である。たしかKACに出場までしたという人物である。

我がこのチェーンボンバー大辞典を目にしたのはアニマロッタがまだ初代だったころ、すなわち中学生くらいである。あっ年齢がばれるな…

実際に使うことはなかったが、これはすごいサイトや!と感嘆した記憶がある。

ただ、残念ながらアニマロッタは、まだ確定していないランダム要素が大きすぎて、チェーンボンバーの理論PO率を正確に推量することはできない。なぜなら番号が上に偏ったり、爆弾が1~2個発生したりするからである。しかしそれでも画像認識を用いてあそこまで仕上げたのはやはり非常にすばらしい。我も一度会ってみたい。

なお我のビンゴバルーンの理論PO率は、一応3個ライン7個が判明しておらず、これをたぶん50倍と勝手に仮定していることなど、非常に些細なことを除けば、全パターンから算出しているので極めて正確である。しかし、わざわざ自作のツールを作ってアーケード版でやっていると、周囲から白い目で見られそうな気がする上、なによりそれをしていても楽しくないという問題点がある。

しかしコナステならば、KMPやスターを稼ぎつつ、5BETでも放置しながら延々と行え、かつPC上なのでマクロ操作ができる、という非常に大きな利点を持つ。

マクロを実際に組み込むのは、3日前に初体験でいろいろ苦労も多かったが、とりあえずなんとか機能した。

チェーンボンバーは、実は一応演出付きで自作している。

ちゃんと本家になるべく似せるように、爆弾の出現位置も下4段などにしている。

ただあれ、リーチ処理を各球数ごとにやると処理が重くなるという問題点がある。しかし本家は一瞬でなめらかにリーチを表示する。これはあのゲーム画面以外に何か別のPCがあるやろ…と推測した。

プログラミングは独力で学んだ。というより、RPGエディターでRPGを作っているうちに自然修得した。とにかく何かを作るのが好きなのは小学校のころから変わっていない。



最適解を出力

 とうとう最適解設定までこぎつけた。

PRINTで数字6,7,11,21がHITしたマス。実はこの上に4ともかかれていたはず。

ちゃんと実際の画面を見ても4,6,7,11,21のマスに入っていることが分かる。

しかしなんか、最適解を与える2というものが不穏。

これは3ではないか、と思われるが…。よく見てみると、3の位置(リーチ12となっているところ)に入れると、3個ラインが完成し、さらにもうひとつ3個ラインのリーチができていいように見える。しかしよく考えてみてみるとその左の8番と書かれているマスにバルーンを配置したほうが、3マス目(12番にHIT)すれば3個ラインが一気に2個完成し、かつ14マス目(14番)にも4個ラインのリーチが発生する。したがって2マス目(8番)に配置するのが適当、という判断は正しいと推測できる。

このように、一見最適と見えるような場合でも、そうでないときがあるので、そこのところのPO率を理論上最大にすることにより、PO率の底上げを図るのである。


せっかくなのでほかにも実験してみる。現時点では配置FREEは1個としている。

パターン1 

どうも位置22,23,24,25に入るとテロップによって色相が変化し邪魔になってしまい、判別してくれないという問題が発生する。まあここはこれ以後なんとかしていく。
今回、ちゃんと位置2,6,7,11,18に赤バルーンが存在していることが分かり、さらに最適解は位置3、すなわち19番とかかれたマスであることを示唆している。
どうやら5個ラインを狙いに行くより、確定3個ラインと、3個ラインリーチを2つ作るほうが良いらしい。これを証明するのは容易ではないが、この数値は以降の1140通り(=20C3)すべての倍率を足しあわせて、1140で割った平均PO率なので正確なはず。

パターン2
確かにINした位置は2,8,9,16,19でありそれをID16499に変換して、最適解は4と出ている。ここはやはり4マス目、つまり10番と書かれているところにバルーンを置くのが良いらしい。ほかにも番号でいうと12や24に配置する、という方法もあるが、これは3個ラインの発生率があがるということが考慮されて4マス目なのだろう。
せっかくなので、FREEを3個配置できる場合で遊んでみる。4個にすると7個ラインが成立しやすい気がするので微妙なラインの3個で。

パターン3 フリー配置可能3個
位置は2,14,16,18,19と正しく表示されており、最適解の位置は17,20,21となっている。
これは上の画像でいうと、5個ライン水平(下段)を成立させる組み合わせに相当し、2倍以上の配当が確定する。7個ラインを2個リーチで狙ったり、4個ラインのオッズアップを狙ったりするよりいいらしい。

あとはこの取得した位置を実際にコナステに入力するプログラムを考える。
これは面倒だが、そこまで難しくはないだろう。

いずれはこのプログラムがFREE2個や3個、4個にも対応したらテストプレイを安全な5BETで繰り返し、平均のPOを確認しようと思う。そののち、エクセルへの各ゲームの成績なども反映していき、いずれは山や谷の発生状況からBET制御もできたらすごいと考えている。
なお5BETならば、切り捨てによるPO率の減少は考慮する必要がない。
…と思ったが2.5倍があるのでやはりあかんかった…。
チェーンボンバーは非常に残念なことに、このPO率減少が起きない最低値が10BETなのである。なぜなら0.5nと0.6nと1.5nがすべて整数になるようなnはというと、まず1.5n=0.5n*3に注意すると0.5nが整数ならば1.5nは必ず3の倍数、すなわち整数。よって0.5nと0.6nがともに整数となる自然数nは、まず0.5nは2の倍数。0.6nが5の倍数である。(分数表記すればわかりやすい)したがって2の倍数でもあり、5の倍数でもある最小の自然数nといえば、もちろん10である。(最小公倍数)
なので最低10BETにせざるを得ず、メダルの減りが速い。
どうも手動で出したPO率でも、だいたい90%(ワンダー含む)感じなので、30BETでは平均毎回3枚ずつ減る計算になり、今なら1000円で375枚らしいので125ゲームでなくなる。これは1ゲーム3.5分と仮定すると437.5分、つまり7時間ちょっとで試行が終わってしまう。

しかしビンゴバルーンならばその半分。1000円で875分、つまり14時間も試行できる。
これで十分に処理の安定性を図ることができる。ただ暴発を防ぐためにCREDITは最小限度にするのが吉。

次の記事ではチェーンボンバー大辞典に関する我の所感について記す。


余談だが、最適解はひとつのエクセルデータにまとめてある。mathematicaやエクセルオフラインが使えない状態であるが、なんとか別の方法を使ってすべてのパターンを一つのCSVファイルにまとめた。したがって531300個のセルが存在する。





指定セルの値を召喚

 さて、いよいよ2ndロッタまでのID変換が行われた(未確認)

ではいよいよ、それをエクセルのセルの指定の引数としていく。

まず、とりあえずFREE1個の場合で機能するかどうかを実験する。

この配置可能FREE数の取得は、置けるFREEの数の数字をやはりpeekcolorなどで判断するかが必要だが、それは時間がかかりそうなので後回し。

一応FREE1,2,3,4個で分岐するものは作っておく。

ところで4つの分岐ってどうすんねん…。

どうもifbとelseifを使えばいいらしい。初めて知ったわ…。

あと行は100で、セルをAを指定したいときは+A+100とかいう文字列の結合表記を使うらしい。

とりあえずこれで7142という値がでた。残念ながら結合はできていないらしい。
しかしこの7142は果たしてあっているのか…?
7142のセルを参照すると、「2」とある。確かに上の画像では、2マス目(14の番号)のところにおけば4個ラインのリーチが発生する。ということは、うまく機能している…?

たまたまかもしれないので、ほかにも様子を見てみる。


エクセルの値を取得

 とうとう、指定したエクセルのセルの値を返すことに成功。

このセルの指定は後々していく。今のところ、以下のようなプログラムとなっている。

id = GETID("コナステ クライアント ver.1.0.0")

Hnd = GETCTLHND(id, "CloudClientGameWindow")

DIM baloon[] =0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

DIM Xaxis[] = 442,411,442,473,380,411,442,473,504,349,380,411,442,473,504,535,380,411,442,473,504,411,442,473,442

DIM Yaxis[] = 88,119,119,119,150,150,150,150,150,181,181,181,181,181,181,181,212,212,212,212,212,243,243,243,274

ACW(id,0,0)

while true

for a=1 to 25

x=Xaxis[a-1]

y=Yaxis[a-1]+21

red=peekcolor(x,y,COL_R)

blue=peekcolor(x,y,COL_B)

if red > 99 AND blue < 99 THEN baloon[a-1]=1 ELSE baloon[a-1]=0

next

sleep(2.0)

DIM list[]=0,0,0,0,0

i=-1

for a=1 to 25

IFB baloon[a-1] = 1 THEN

i=i+1 

list[i]=a 

ELSE 

i=i

ENDIF

next

c21=list[0]

c22=list[1]

c23=list[2]

c24=list[3]

c25=list[4]

c26=c21-1

c27=c22-c21

c27=c27-1

c28=c23-c22

c28=c28-1

c33=c24-c23

c33=c33-1

c30=0

c29=0

for a=1 to c26

c29=c29+1

c31=25-c29

c31=c31*(24-c29)

c31=c31*(23-c29)

c31=c31*(22-c29)

c31=c31/24

c30=c30+c31

next

c29=0

for a=1 to c27

c29=c29+1

c32=c29+c21

c31=25-c32

c31=c31*(24-c32)

c31=c31*(23-c32)

c31=c31/6

c30=c30+c31

next

c29=0

for a=1 to c28

c29=c29+1

c32=c29+c22

c31=25-c32

c31=c31*(24-c32)

c31=c31/2

c30=c30+c31

next

c29=0

for a=1 to c33

c29=c29+1

c32=c29+c23

c31=25-c32

c30=c30+c31

next

c30=c30+c25-c24

oExcel = GETACTIVEOLEOBJ("Excel.Application");

value1 = oExcel.ActiveSheet.range("J53130").value;

MSGBOX(value1)

sleep(100.0)

wend

あとは、このJ53130となっているところ(ちなみにこのセルは、位置21,22,23,24,25に赤バルーンが生成したときの、FREE4個が配置可能な場合の4つ目の配置場所となっており、この値は25である。なおその他は9,15,20という番号になっている。

これは、3個ライン3個をとり、かつオッズアップで倍率5倍を確定させているということになる。オッズアップは本来若い番号から入れていく規則であるが、以前のべた通りこの53130通り目は1通り目の180度回転で同一となるため、各マスの置換を考えてそれに基づいている。1マス目は180度回転すれば25であるから、オッズアップの番号に25が組み込まれているのである。もしそうしなければこの53130通り目にもPO率を厳密に計算する処理が発生してしまい、効率が悪い。1と53130通り目が「同一」であるかどうかの判定は以前にやっているので省略。ただそんなに簡単な話ではない。

ではいよいよ、アニマロッタで指定した赤バルーンの位置を取得し、それ先ほどの対象セルとうまくかみあわせて、最適解をたたき出し、そこからコナステに入力する。これを行っていく。

最適解を組へ変換

 以下の画像のように、IDを順番に並べたときの最適解の位置データが明確に示せるようになった。これをするためにウディタ側でプログラムを再構築し、現時点では53130個の出力と並行して記事を書いている。

残念ながらウディタでは各データが10000個しか使えないため、ファイルを6分割する必要がある。ただ、別に分割していても特に支障はないだろう。ただ注意すべきは、どうもウディタの性質で2行目からID1が発生するため、例えばIDが10001番目は、2つ目のCSVファイルの2行目を参照する必要がある。

この参照は、おそらくUWSCのエクセルファイルを参照する関数があったと思うので、それが使える。IDはすでに先ほどの記事で述べたようにこのCSVファイルに都合の良いように変換済みである。

するとあとはその得たデータを実際にコナステに組み込む…というのが現在の状況である。しかし果たしてそう簡単にうまくいくか…。

赤バルーン→IDへの変換

 そうや…最適解のデータは重複のない辞書式組み合わせの昇順に一次元のIDとして並んでいるんやった…。つまり、このIDを配置すべき組に変換する必要がある。

悲しいことに、これを行うプログラムはmathematica上で実行していた。そしてそのmathematicaが現段階では使えないという悲劇。おまけにエクセルもライセンス云々でオンラインのアレでないと使えない。

なんとかエクセルに{1,2,3,4,5}をID1として、{21,22,23,24,25}をID53130とする変換を簡潔にやってくれるコードは存在しないのかなと思っている。

まてよたしかウディタにはCSVファイルとして結果を放出する機能があったはず!

そしてウディタにはこの1次元と5次元の相互変換を行うプログラムを組んでいるのでそれの流用ができるやん!

そのウディタで何をやっていたかというと、ビンゴバルーンの最適解の視覚化。

普通にやるならこれでいいが、やはり自動化を目指しているのでこれでは物足りない。

なお我がウディタで初めてCSV化できるコマンドを使ったのはゴブリンが提供するお楽しみ広場。あの当時はわけもわからずなんとなくしょぼいRPGを作って自分で遊んでたらしい。中学校入って1年くらいと思われる。

CSVの書き換えはライセンスがないためできないが、ウディタ上で計算してそのデータをCSVに移動させることはできる。そして結果はエクセルオンラインのほうに書き込めばいいし、これは最適解を求めるというよりは結果を記録するという少々逸脱した話なので後回しでもよい。

ちなみに、以前作ったビンゴバルーン解析プログラムはウディタ製で、以下。

上記の画像のように、5球後どこにFREEを配置すればよいかを教えてくれるツールである。ちなみに、下2つはFREE2個配置可能な場合である。
中央上の表は、8面バルーンをやっていたときに、各番号に入ったときの期待値を示している。例えば6球目に22という番号に入れば、以降2ゲームの条件付き平均POは162%ということである。この値が高いのは、右上のバルーンで7個ラインがわずかながらでも存在するということに由来する。

実はこのプログラム、mathematicaによって容量の縮小化を図るために最適解の組をIDに変換しており、このウディタでまた別のプログラムを作ってそれを以上の画像のように組へと再変換している。そのシステムをID1~53130などに順次実行させ、その組をエクセルにCSVとして保存させればこの問題は解決されると見た。

余談だが、おそらくビンゴバルーンを最適解(りんごやボールの偏りを考慮しない場合での、FREEを様々な番号に配置した中で最高の期待値を与える配置)として、配置可能FREE個数0,1,2,3,4とすべての場合で網羅したのはたぶんネット上を見たところ現時点では我のみらしい。なにしろこの作業、ものすごく時間を食うからである。CPU100%近くで計算をさせても何週間もかかったような記憶が。これでもmathematicaのカーネルを増やしてそれぞれに並立計算をさせたり、できる限りの処理の簡略化(回転、対称移動で同一となるものはそれ専用の簡易処理を行うなど)をしているんだが…。

さて…。

5つの組からIDへと変換するのは、たしかにCSVにIDと組の対応関係を等しい行に作ればそれでいいのだが、もし位置{21,22,23,24,25}にHITしてしまうと、探索に53130回もの処理が必要となり、非常に効率が悪い。となれば、UWSC上で計算させたほうがIDに関しては手っ取り早いだろう。そしてそのIDに対して、FREE1,2,3,4個のIDを組みに変換して横に並べたCSVを用意し、それの数値を読み取って最適解をコナステ側に入力する、というのが処理速度的に適切かと思われる。
 |■変数操作: CSelf26 = CSelf21 - 1 
 |■変数操作: CSelf27 = CSelf22 - CSelf21 
 |■変数操作: CSelf27 -= 1 + 0 
 |■変数操作: CSelf28 = CSelf23 - CSelf22 
 |■変数操作: CSelf28 -= 1 + 0 
 |■変数操作: CSelf33 = CSelf24 - CSelf23 
 |■変数操作: CSelf33 -= 1 + 0 
 |■変数操作: CSelf30 = 0 + 0 
 |■変数操作: CSelf29 = 0 + 0 
 |■回数付きループ [ CSelf26 ]回
 | |■変数操作: CSelf29 += 1 + 0 
 | |■変数操作: CSelf31 = 25 - CSelf29 
 | |■変数操作: CSelf31 *= 24 - CSelf29 
 | |■変数操作: CSelf31 *= 23 - CSelf29 
 | |■変数操作: CSelf31 *= 22 - CSelf29 
 | |■変数操作: CSelf31 /= 24 + 0 
 | |■変数操作: CSelf30 += CSelf31 + 0 
 | |■
 |◇ループここまで◇◇
 |■変数操作: CSelf29 = 0 + 0 
 |■回数付きループ [ CSelf27 ]回
 | |■変数操作: CSelf29 += 1 + 0 
 | |■変数操作: CSelf32 = CSelf29 + CSelf21 
 | |■変数操作: CSelf31 = 25 - CSelf32 
 | |■変数操作: CSelf31 *= 24 - CSelf32 
 | |■変数操作: CSelf31 *= 23 - CSelf32 
 | |■変数操作: CSelf31 /= 6 + 0 
 | |■変数操作: CSelf30 += CSelf31 + 0 
 | |■
 |◇ループここまで◇◇
 |■変数操作: CSelf29 = 0 + 0 
 |■回数付きループ [ CSelf28 ]回
 | |■変数操作: CSelf29 += 1 + 0 
 | |■変数操作: CSelf32 = CSelf29 + CSelf22 
 | |■変数操作: CSelf31 = 25 - CSelf32 
 | |■変数操作: CSelf31 *= 24 - CSelf32 
 | |■変数操作: CSelf31 /= 2 + 0 
 | |■変数操作: CSelf30 += CSelf31 + 0 
 | |■
 |◇ループここまで◇◇
 |■変数操作: CSelf29 = 0 + 0 
 |■回数付きループ [ CSelf33 ]回
 | |■変数操作: CSelf29 += 1 + 0 
 | |■変数操作: CSelf32 = CSelf29 + CSelf23 
 | |■変数操作: CSelf31 = 25 - CSelf32 
 | |■変数操作: CSelf30 += CSelf31 + 0 
 | |■
 |◇ループここまで◇◇
 |■変数操作: CSelf30 += CSelf25 - CSelf24 
このIDへの変換は四則演算で行うことができる。結構ややこしいが。
この方式は、やはり我がいろいろ紙に書いて探りながら楽な方法を考えた。
昔の我の働きのおかげで助かるわ…。
これをuwsc用に単純に変換したものがこれ。
c21=list[0]
c22=list[1]
c23=list[2]
c24=list[3]
c25=list[4]
c26=c21-1
c27=c22-c21
c27=c27-1
c28=c23-c22
c28=c28-1
c33=c24-c23
c33=c33-1
c30=0
c29=0
for a=1 to c26
c29=c29+1
c31=25-c29
c31=c31*(24-c29)
c31=c31*(23-c29)
c31=c31*(22-c29)
c31=c31/24
c30=c30+c31
next
c29=0
for a=1 to c27
c29=c29+1
c32=c29+c21
c31=25-c32
c31=c31*(24-c32)
c31=c31*(23-c32)
c31=c31/6
c30=c30+c31
next
c29=0
for a=1 to c28
c29=c29+1
c32=c29+c22
c31=25-c32
c31=c31*(24-c32)
c31=c31/2
c30=c30+c31
next
c29=0
for a=1 to c33
c29=c29+1
c32=c29+c23
c31=25-c32
c30=c30+c31
next
c30=c30+c25-c24
これで赤バルーン5つが1~53130までのIDに変換されたことになる。
あとはCSVを作ってそこの最適解(組)を参照し、再びUWSC側に舞い戻り、あとはそれをコナステに入力する。




2020年12月25日金曜日

バルーンの位置を取得完了

 いよいよ、所定のプログラムを組むことにより、以下のような場合においてバルーンの位置を取得することができるようになった。例えば以下の場合では、マスの順番の定義に従って、9,10,12,15,18という5つの値をリストに格納している。

これにより、存在するバルーンの5つの数字を特定できるようになったので、ここからは以前保存しておいたエクセルの最適解との参照を以後は行っていくことになるだろう。

なお、上記の画像判定が強固なものかどうかはまだ怪しいので、しばらく様子を見る必要がある。

ようやくここでかつて我が行ったビンゴバルーン最適解が来るのか…。



peekcolor関数を使ってみる

 まずは、画像認識が必要である。そして幸いなことに、アニマロッタの画像認識はかなり楽である。というのも、あるマスにバルーンがあるかどうかは、そのマスが赤っぽいかどうかで判別がつくからである。とはいえ、それを実践するのは一瞬ではない。

そこで、ちょっと練習を兼ねてみる。

下のような画像を作って、ちゃんと色の取得が行われているかをチェック。

関数によると、
peekcolor(X,Y,オプション)という形でいいらしい。
これは=で結ぶと戻り値をそのまま変数に代入できる。
今回、赤色に近いかどうかの判定が必要なので、使うオプションはCOL_Rというものらしい。
また、出力されるのが16進数らしい。
16進数については、小学校のころからその存在と変換方法は改造コードの知識で知っているので問題ない。UWSCの語法では、前に$をつけるらしい。

while true
X=G_MOUSE_X
Y=G_MOUSE_Y
red=peekcolor(X,Y,COL_R)
test=$FF
MSGBOX(abs(red-test))
sleep(3.0)
wend

こんな感じで組んでみたところ、赤領域は18、オレンジ領域は0、青領域は192という値になった。いつの間にか16進数が10進数に変換されている。まあええか…。
なお画面外の白色は0とでた。

本来は赤色がもっとも0に近い値になるべきだが、こうなってしまうのは色の組み合わせによるものだろう。白はもっともかけ離れているが、RGBが全部MAX値だからだろう。

そういうわけで、このままでは純粋な紫色なども赤と判定されるので、一応青も取得して、青の割合が高く、赤が低いものが未HITとすることができる。

とりあえず実際にバルーンの画像判定ができるかを実践したい。
しかしそのためにはウィンドウを固定しなければいけないので、
ACWというコマンドで指定のウィンドウを動かせるらしいのでそれを行う。
ウィンドウの取得は確かGETIDでいけたはず。

実際に以下のコマンドでいけた。
id = GETID("コナステ クライアント ver.1.0.0")
Hnd = GETCTLHND(id, "CloudClientGameWindow")
ACW(id,0,0)
while true
sleep(3.0)
wend
実際にウィンドウを取得してACWというコマンドで左上にウィンドウを移動。
whiletrue以降は現時点では意味はない。

で、(442,88)という座標がウィンドウを固定したときの1マス目の中心の上のほうの座標。この位置を取得する理由は、中心だと番号がかぶって黄色っぽくなったり、そうかと思えば番号11などは中心がバルーンの赤色になったりなど判別しづらい。そして、座標が(31,31)分動けば別のマスに移動する、と考えてよいだろう。
すると、2マス目の判定の座標は1マス目から左下に移動するので(411,119)となる。
これら各25マスに対して色判定を行い、赤バルーンが存在するかどうかを特定する。

同じ作業を戻値(返り値)なしで行うため、functionというユーザー定義関数を使わないのかもしれないが、まあええか…。
返り値はresultというものをfunctionの関数の中で作るらしい。
functionが終了したことを明示するためにfendというものを最後に使用するらしい。
functionの後には引数を使用できるらしい。ここには各マスの座標を2つの引数とする。
あと、なんか関数の宣言は後ろのほうにしてもよいらしい…?がそうする理由はないので最初に定義することにする。
あと条件に関するのはたぶん慣例的にifなのでそれも初使用、ということで書式を確認しておく。不等号はそのまま使用可能らしい。ええやん
論理記号はどうすんねんと調べたら、ANDやORでいいらしい。
次に、25個のマスにバルーンがあるかどうかの判定を行いたいので、この25個の状況を一挙にまとめてくれるいわばベクトル的なものが欲しい。
これはdimのあとの[※]で、ここに配列数マイナス1を記入し、そのあと等号で結んで各要素を代入する感じらしい。
あと、集合の要素をどう扱うかは以下のテンプレで実践的に判別する。

//---シャッフル関数
Procedure shuffle(var list[])
 Dim n = length(list)   //配列の要素数
 Dim i, r, tmp
 for i = 0 to n -1
  r = random(n)
  tmp = list[r]     //ランダムに選ばれたr番目の配列の値を取得
  list[r] = list[i] //配列i番目の値をr番目に入れる
  list[i] = tmp     //入替え完了
 next
Fend
どうもシャッフルを行っているらしい。我も自作アニマロッタで番号配置をランダム化するとき、退避の変数を一つ用意して入れ替えを行っている。この操作は山ほどしてきたので、やりたいことがわかった。どうやらまず変数を持ってきてそのあとの[※]で位置を把握できるらしい。ただ、どうも0番目が最初になるらしいのでここ注意。


すると以下のような感じか…。よし名前をchkcorに使用
dim baloon[24]=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
X=442
Y=88
function chkcol(X,Y)
red=peekcolor(X,Y,COL_R)
blue=peekcolor(X,Y,COL_B)
if red>100 AND blue<100
then 
baloon[0]=1
else
baloon[0]=0
fend
これで、R値が100より大きく(赤っぽく)、B値が100より小さい(青っぽくない)場合に、
そこには赤バルーンがあるとして25個のリストをもつbaloonという変数に1つ目の値として1を代入する、という操作になるはず。
あとはこれを25回繰り返す。これはおそらくforだろう。
とりあえず今の段階では各マスの判定に使う座標も手動で入力しておくか…。
するとこうか。

dim
X[24]=442,411,442,473,380,411,442,473,504,349,380,411,442,473,504,535,380,411,442,473,504,411,442,473,442
dim Y[24]=88,119,119,119,150,150,150,150,150,181,181,181,181,181,181,181,212,212,212,212,212,243,243,243,274

for a=1 to 25
dim baloon[24]=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
chkcol(X[a-1],Y[a-1])
next
MSGBOX(baloon)

これでどうや。この辺りのものをまとめてやっていくと…。

id = GETID("コナステ クライアント ver.1.0.0")
Hnd = GETCTLHND(id, "CloudClientGameWindow")

ACW(id,0,0)

dim X[24]=442,411,442,473,380,411,442,473,504,349,380,411,442,473,504,535,380,411,442,473,504,411,442,473,442
dim Y[24]=88,119,119,119,150,150,150,150,150,181,181,181,181,181,181,181,212,212,212,212,212,243,243,243,274
dim baloon[24]=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

function chkcol(X,Y)
red=peekcolor(X,Y,COL_R)
blue=peekcolor(X,Y,COL_B)
if red>100 AND blue<100
then 
baloon[0]=1
else
baloon[0]=0
fend

for a=1 to 25
dim baloon[24]=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
chkcol(X[a-1],Y[a-1])
next
MSGBOX(baloon)

sleep(5.0)
while true
というプログラムでいざ実験。なお現在はシングルの1つのゲームのみ対応。

あっ文法エラーや
if red>100 AND blue<100
THEN
baloon[0]=1
ELSE
baloon[0]=0
fend
の部分がだめらしい。どうも1行で書かなければいけないらしい。
あとresultがないと言われた。これはprocedureか…。
他にはwendがないとでる。
どうも、procedureは最後におかなければいけないらしい…?


このようにいろいろやっているうちに、なんかいろいろ問題が発生したので結局は以下に落ち着いた。





悲しい

 確かにチェーンボンバーの配列や配当を記録し、ついでに番号もしっかりと記入できるプログラムの性能が高まってうまく作れたのは良いが…。 この前スーパーJP4500とダイレクトJP10000が立て続けにきてクレジットが15000になって有頂天になっていたがKMPが100%から動かない...