スプラ神経衰弱アプリを公開しました - 10月 07, 2020 こんにちは、ぐぐりら(@guglilac)です。 趣味で作った[スプラ神経衰弱](https://guglilac.pythonanywhere.com/)を公開したので、アプリの紹介も兼ねて、実装の一部を解説したりしていきたいと思います。 数学っぽい内容については別記事に切り出したので、興味があるかたはそちらもどうぞ! スプラ神経衰弱で学ぶ!グラフ理論 - Qiita スプラトゥーンと神経衰弱を組み合わせたら面白そう、という単純な思いつきから始まり、簡単にできるかと思いきやいろいろ考えるべき部分も多くて作るのが楽しそうだと思い、勢いで作りました。 せっかくなので公開したので、ぜひ遊んでみてください。 スプラ神経衰弱 ## ルール 基本的には通常の神経衰弱と同じルールです。 ただ、一人で神経衰弱をしても面白くないので、少しルールを変えてみます。 通常の神経衰弱では、同じ数字のカードがペアになり、そのペアの個数が得点になりますが、一人で遊ぶとどうやっても同じ点数になり、面白くありません。 スプラ神経衰弱では、スプラトゥーンのブキが書かれた各カードをめくって、ペアにしていきます。 スプラトゥーンには多くのブキが存在し、各ブキはメインウェポン、サブウェポン、スペシャルウェポンが設定されています。 上図だと、左にメインウェポンが、サブウェポンとスペシャルウェポンが右側に表示されています。 スプラ神経衰弱では、ブキのメインウェポン、サブウェポン、スペシャルウェポンのうちいずれかが一致していたらペアになります。 また、ペアになったときの得点もペアの種類によって変わるようにします。 珍しいペアを手に入れたときは高得点が入り、ペアにしやすいようなカードの組であれば低い得点になるようにします。 得点の設定については後述します。 このようにすることで、一人でも楽しめる神経衰弱になります。 (もちろん対戦ゲームにもできますが、面倒だったので一人用にしました) ## 得点の計算方法 出現確率の逆数の対数をとってメイン,サブ,スペシャルそれぞれで計算し足しあわせたものを素点としました。 こうすると確率の積の逆数のlogをとっているので、珍しいペアに対してより大きな値になります。 確率の積にしている点が、メイン、サブ、スペシャルの出現頻度が独立であることを仮定してしまっているのですが、多分独立ではないので厳密には正しい定量化にはなってないです。 (追記:) 独立性について気になったので、サブとスペシャルについてクロス表における独立性検定を行ってみました。 `pd.crosstab`でクロス表を作って、`scipy.stats`の`chi2_contingency`を使って独立性検定をすると、次のように 検定量(カイ2乗値)、P値、自由度、期待度数がかえってきます。 ```python import pandas as pd import scipy.stats as st cross=pd.crosstab(df['subweapon'], df['special']) x2, p, dof, e = st.chi2_contingency(cross,correction=False) ``` 結果 ``` p値 = 0.890 カイ2乗値 = 145.91 自由度 = 168 ``` 各返り値を簡単に説明すると、 * P値 : 独立だとしたとき、この標本程度またはこれより独立じゃなさそうな標本が得られる確率 * 期待度数 : 独立だとしたときに期待されるクロス表 * カイ2乗値 : (ざっくりと) 期待度数と実測値のずれ * 自由度 : クロス表の`(縦の個数-1)*(横の個数-1)` です。 有意水準0.05とすると、P値=0.89>0.05なので、サブとスペシャルが独立であるという帰無仮説が採択されました。 独立じゃないだろうと思っていましたが、そこまで有意な偏りはないみたいですね。 (追記ここまで) また、得点の計算を大元のグラフ全体で行うのではなく、取ってきた部分グラフに対して行うのが厳密には正しいレア度の定量化ですが、そこまで真面目にやらなくてもいいかなと思ってやっていないです。 ちなみに、素点そのままだとスケールが小さく、実際にプレイしたときにスコアの違いがわかりづらいので、偏差値になおしたものを得点としています。(すなわちこれがグラフのエッジの重みになっています。) ## 高得点のコツ 基本的に運ゲーですが、なるべく高い点数になる珍しいペアを選びたいです。 高得点のペアになりうるブキを覚えておいて、それが出たら慎重にペアを探していくのが良いかもしれないです。 例えばレプリカと名前のつくブキ(ヒーロー種)は、全く同じメインサブスペシャルのブキが存在するので、そのブキとペアになれば高得点が期待できます。 また、(スプリンクラー,イカスフィア) や(キューバンボム, マルチミサイル)のようなサブとスペシャルのどちらも共通しているブキも高得点になります。 加えて、サブやスペシャルよりもメインが共通しているほうが珍しいので、メインが揃うならメインでペアにしてしまうのが高得点になりやすいでしょう。 * ヒーロー種 * サブスペが一緒 * メインが一緒 あたりを揃えるようにしてみると、高得点が期待できる(かもしれません。基本運ゲーですが) 満点が出た方いましたら、ぜひ教えてください。 以下、実装の話になります。 ## グラフ関連 ブキをノード、ペアになりうるかをエッジ、得点を重みとすると重み付き無向グラフと見なせるので、様々なグラフ理論まわりの処理を用いています。 こちらについては、詳細をQiitaの記事に書いたので、そちらをお読みいただければと思います。 スプラ神経衰弱で学ぶ!グラフ理論 - Qiita グラフを描画するのはこちらを参考にしました。 [Python上でGraphvizを使って綺麗なグラフを描く - プログラミング原人の進化論](https://programgenjin.hatenablog.com/entry/2019/02/26/075121) こんなかんじで表示できます。 内部のロジックをデバッグするときなどに役立ちました。 ## SweetAlert2 [【使い方】 JS Sweet Alert 2 | Kinchan's Blog](https://lmn-blog.com/sweet_alert2/) これでフッターにTwitterシェアボタンをいれました。終了時にシェアボタンが出るのがよいですね(ずっとボタンがあるとごちゃごちゃするので) ## Twitter周り Twitterシェアボタンは自前で作りました(公式のは読み込みが重いので) この辺りを参考に。 [オリジナルのシェアボタンを作ろう!各種SNSのボタン設置用URLまとめ | Web Design Trends](https://webdesign-trends.net/entry/3632) ツイッターカード周りはこれで設定。 [【2020年版】Twitterカードとは?使い方と設定方法まとめ](https://saruwakakun.com/html-css/reference/twitter-card) (面倒で横着してファビコンの画像をtwitter cardに設定したらだめだったのでちゃんとpngとかjpgにする) 参考 : [Twitterカードの設定は正しいのに画像が表示されない原因 | あぱーブログ](https://blog.apar.jp/web/9844/) ## PythonAnywhereでFlaskアプリを公開 基本的にこれを参考にすれば大丈夫. [PythonAnywhere に Flask アプリをデプロイ - techium](https://techium.hatenablog.com/entry/2018/02/01/214332) コンソールからgit cloneしてきて、PythonAnywhere上で仮想環境を作成し、必要な依存パッケージをインストールします。 パッケージのインストールは`requirements.txt`をリポジトリに入れておいて、それを利用すれば簡単です。 仮想環境は一度作れば大丈夫なはず。アプリを修正した場合には最新版を`git pull`してくる必要があり、必要ならパッケージが増えたら再度pipで入れ直します。 あとはWeb上でぽちぽちすればいけます。 Webタブから遷移して各項目を修正します。 仮想環境を指定する部分は、Virtualenvの項目にパスを指定します。 `/home/username/.virtualenvs/仮想環境名` WSGIファイルの編集は、編集画面にいってFlaskの部分を自分のアプリの起動ファイルの内容に合わせます。 `manage.py`の中で`app.run()`などとしている場合は、 ``` from manage import app as application ``` とします。 デバッグは`Log files`の部分にエラーログファイルがあるので、そこを見ながら行いました。 自分は`requirements.txt`に記入漏れがあってパッケージが足りない問題と、アプリの中で読み込むjsonファイルのパスが見つからない問題の二つで少し詰まったけれど、このようにデバッグして解決しました。 ちなみにファイルが見つからない問題は、公式にヘルプがあるほどよくある問題らしいです。 [No such file or Directory? | PythonAnywhere help](https://help.pythonanywhere.com/pages/NoSuchFileOrDirectory/) beginnerプランなので無料だけれど、3ヶ月に一回ダッシュボードにある黄色いボタンを押さないとdisabledになるらしい。まあ仕方ないですね。 ## はまりポイントいろいろ 細かいはまりポイントをまとめて供養します。 ### getElementsByclassNameでforEachがうまくいかなかった javascriptの話です。 こちらの記事で書かれていました。 [getElementsByClassNameでforEachがうまくいかなかった - Qiita](https://qiita.com/naos_taira/items/929f9bbf46d4f61819ac) `getElementsByclassName`で取得すると、動的に変化してしまうので、for文でループしている間に要素が変わってしまうのでおかしいことになるみたい。 (配列の要素数が変わってインデックスがずれたり、とか) `getElementsByclassName`で取得できるのは厳密には配列ではないことが原因らしい。 ### bootstrap,xsがなくなってた 4から、書き方が変わっているようでした。 [Grid system · Bootstrap](https://getbootstrap.com/docs/4.1/layout/grid/#grid-options) ### Pythonで見かけ同じ文字なのに一致しない 見かけ上同じなのに一致しない文字列に出会って苦労しました。 こちらで解決。 [[Python] 結合文字を使用した濁点や半濁点を直前の仮名と結合させる方法(ウ゛→ ヴ) - Qiita](https://qiita.com/syamamura/items/13c0825282415e2e360d) ## おわりに 趣味で作ったスプラ神経衰弱の紹介でした。 [スプラ神経衰弱で学ぶ!グラフ理論](https://qiita.com/guglilac/items/9652f210baf68c0b3c1d)の方もよろしくお願いします! 最後までお読みいただきありがとうございました。 この記事をシェアする Twitter Facebook Google+ B!はてブ Pocket Feedly コメント
コメント
コメントを投稿