ダーツにおける狙い目を検証してみた！

こんにちは。今回のブログでは、ダーツボードのどこを狙うと一番得点が稼げるか検証していきたいと思います。実際の計算にはPythonを用いました。結果のみが知りたい方は途中を読み飛ばしてまとめだけ読んでください。
#ダーツのルール
基本的にDARTSLIVEさんのルールに準拠して解説します。主なルールには、01,CRICKETの2つがありますが、どちらも基本的に得点を稼ぐことが最重要となります。得点に絞って解説すれば下図の通りです。
![Darts_value_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/713550/aca4eed0-42fe-6b94-5864-8206e436529e.png)
![Darts_value_CRICKET.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/713550/94562021-5ef8-26b2-b35b-9f9d739e606f.png)
以下ではブルの中心を原点に取る座標系を考え、上図を2次元平面上の関数$F(x,y),G(x,y)$として定義します(当然ですが、ボードの外は0点です)。
#期待値の計算モデル
どんなに上手い人でも、狙ったポイントからのブレが0にはなりません。今回は、このブレによる確率的な広がりを2次元正規分布と仮定して計算してゆきます。

```math
確率密度関数:P(r)=\frac{1}{2\pi\sigma^2}\exp\left(-\frac{r^2}{2\sigma^2}\right)
```

$r$は狙うポイントからの距離、パラメータ$\sigma$はブレの度合いをそれぞれ表します。
ある点$(x_0,y_0)$を狙った時の点数の期待値を計算するには、以下の計算をすればOKです。

```math
E(x_0,y_0)=\int_{-\infty}^{\infty}\int_{-\infty}^{\infty}F(x,y)P\left(\sqrt{(x-x_0)^2+(y-y_0)^2}\right)dxdy
```

点$(x_0,y_0)$を様々に動かして多くの点についてこの計算を行い、そのうち点数が最大となる点が狙い目となるわけです。しかしながらコンピュータに実際の積分計算をやらせるためには、離散化して近似計算する必要があります。重積分をするために、まずは座標上に代表点をとります。
![Darts_samplepoint.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/713550/75930cb3-19d9-f3c1-e09c-9d66428ebe7b.png)
この$N$個の代表点は、極座標的な対称性を意識しながら、点の密度がおよそ一定になるように取りました。各点はその周囲の領域を代表しており、$n$番目の点が代表する領域の面積を$S_n$とします。すると、$E(x_0,y_0)$は以下のように近似できます。

```math
E(x_0,y_0)=\sum_{n=1}^N F(x_n,y_n)P\left(\sqrt{(x_n-x_0)^2+(y_n-y_0)^2}\right)S_n
```

この計算を点$(x_0,y_0)$のみならず多くの点について行うわけですが、ここではカラーマップ作成のため、下図の通り格子点を用意して計算することにしました。
![Darts_gridpoint.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/713550/6c0bc603-0ddb-d339-e354-16f2b11656df.png)
計算精度を考慮し、この密度は代表点の密度とおよそ一致するようにしました。

#計算結果、考察
01について、各$\sigma$に対応した計算結果は以下の通りです。
![Darts_01_table.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/713550/a70e6f3f-d3fc-03f6-d236-54526ce6e9d2.png)
CRICKETについては以下の通りです。
![Darts_CRICKET_table.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/713550/b51bbc66-07ef-73c8-2ba7-55cb1eac545e.png)

ちなみに、01statsの$\sigma$依存性は以下の通りです。
![Darts_sigma_stats.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/713550/43d3517d-7cbb-709b-22b4-090ea2f8cc8c.png)

ブル(中心)を狙った場合の期待値については極座標的な対称性により厳密解が求まるため、上図ではその値を用いました。上図より読み取れるフライトと$\sigma$の関係は、およそ以下の通りです。
![Darts_flight_sigma.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/713550/654aeda6-c592-ff89-1e27-4cc1a458de65.png)

結果を元に、色々と考えて行きたいと思います。
まず、01においては、Bフライト($\sigma=29.2 \rm mm$)未満の初心者は7のトリプルを狙うのが最適戦略のようです。割と非自明な結果ですよね。練習になるかはさておき、絶対勝ちたい場面ではこの戦略も悪くないように感じます。およそBフライト以上になって初めて、ブルを狙う正攻法が最適解になるようです。
CRICKETについても、Bフライトボーダー付近に最適解の転移点があり、Bフライト未満では19のトリプル,Bフライト以上では20のトリプル周辺を狙うのが良いようです。加えて、最適な狙い目の位置についてですが、どの$\sigma$の値に関しても、事前にイメージしていたよりもかなり内側(トリプル寄り)でした。この知見は今後にも役立ちそう。
ところで、今回持ち出したブレのパラメータ$\sigma$についてですが、実はDARTSLIVE3にも同様にプレイヤーのスロー精度を示す、RANGEという指標があります。DARTSLIVE3には矢の刺さった位置をミリ単位で計測する機能(つよい)があり、RANGEはその情報を元に算出されているようです。

>DARTSLIVE HPより引用
>>ダーツを始めた頃は思ったところに投げられなくても偶然トリプルやダブルに入って得点が高くなることがあります。上達してきてBULL付近に狙って投げることができるようになると、偶然トリプルやダブルなどの高得点エリアに入ることが少なくなるため、01 STATS、ひいてはRATINGが一時的に下がったり変動しなくなったりして、上達していることがわかりにくくなる時期があります。
そのような時期でも、BULLの中心にグルーピングが集まっていけばRANGEの値は変動するため、上達を意識して練習することができます。

01statsの$\sigma$依存性の図を見ると、確かに45~75mmの範囲でstatsの停滞期が見て取れます。RANGEの指標があればその期間にも成長が感じられるので、モチベーションアップにも役立ちそうですね。
ところでこの停滞期の領域ですが、最適戦略(7のトリプルを狙う戦略)を取ることで解消できそうです。$\sigma=30\sim75 \rm mm$について、最適戦略を取った場合のstatsを加筆すると下図のようになります。
![Darts_sigma_stats_imp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/713550/28fcb9b2-d32e-40a6-33a9-b2d91b4b80ed.png)
トリプル7を狙う戦略の場合、上達度に応じてstatsが伸びてくれるので、成長の恩恵をしっかりと受けられそうですね。

#計算量の話
代表点、格子点の間隔の目安を 5 mm に設定し、結果として代表点の個数は$N=4360$、格子点の個数は$M=6561$となりました。計算量は$O(NM)$であり、$NM\simeq3*10^7$なので、Pythonで動かすと出力までに1分くらいかかります(重い)。$N,M$ともに間隔の2乗に反比例するので、全体の計算量は間隔の4乗に反比例して増えます。それゆえ、これ以上間隔を狭めるのは厳しいとの結論に至りましたが、$\sigma$が大きい場合に関しては、ある程度の精度は担保されていると思います。

#問題点
今回の内容では2投目以降に起こる、既に刺さっているダーツとの相互作用が考慮されていないという問題があります。また、計算精度に関して、今回のアルゴリズムでは、$\sigma$が小さい時に代表点の密度が相対的に不足し、誤差が増大するという問題点もあります。これに関しては、狙う点の近傍において代表点の密度を高めるようなアルゴリズムを組めば解消しますが、精度が危うくなる $\sigma\leq10$ 程度の領域(神レベルに上手い)では正直解析するまでもないのでここでは省略します。

#まとめ
Bフライト未満の初心者層は、01ではトリプル7,CRICKETではまずトリプル19を狙おう。
Bフライト以上のプレイヤーは一般的な戦略で問題ないが、CRICKETではシングル狙いでなく、しっかりトリプルを狙うようにしよう。

まずはダーツを楽しむのが一番大事なんですが、参考までに。では。
#参考文献
[RANGEとは-DARTSLIVE](https://dlapp.zendesk.com/hc/ja/articles/1500000345642-RANGEとは-)