ウマ娘のちょっとしたツールを作ってみた  ―『ウマ娘レースプランナー』

おはようございます、@aya_seと申します。今回は**『ウマ娘 プリティダービー』**のちょっとしたツールを作って遊んでみたので、その紹介になります！
>注)：『ウマ娘 プリティダービー』のゲームシステムに関する基本的な説明は割愛します。

# 『ウマ娘レースプランナー』
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487606/1638cb3b-5154-6067-9dc3-4b61f77b9e19.png)

(レース中盤で疲れにくく)なりません。そのかわり、ウマ娘の育成スケジュールの決定を少しだけ手助けしてくれます！とりわけ
#### 固有スキルLvアップやレジェンド達成できる効率的なレース出走スケジュールが知りたい！
#### ファン数稼ぎ(ファン活)の際にどれぐらいのファン数が稼げるか見積もりたい！
というようなときに利用できるサイトを目指しました。
つまりは、本来の意味での**『レースプランナー』**というわけです。具体的には、以下のようなことができます。
![image.png ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487606/ee5f3a48-3c3c-bb39-9c8e-56062ac8b8d3.png)
▲見るだけで 肌荒れしそうな スケジュール (575)

# レース計画
- シナリオ・キャラクターを指定して、**「ノルマ達成効率重視」「ファン数最大化」**の2つの基本戦略からおすすめの出走スケジュールをレコメンドすることができます。
- 特定の期間までに達成すべき**ファン数やレース勝利数のノルマ**を考慮することができます(固有スキルLvUP・キャラの育成目標など)。
- レコメンドされたスケジュールをもとに、個別に出走レースを編集してプランをカスタマイズすることができます。

## レース一覧表
- シナリオ固有のレース・メイクデビュー戦等を除いた全てのレースの一覧を表形式で見ることができます。
- アカウントごとに重賞レースのトロフィー獲得状況を管理することができます(※Googleアカウントでログイン済の場合のみ)。

# サイトにアクセス
[**こちらのURL**](https://umamusume-trophies.vercel.app/)にアクセスします。Googleアカウントによるログイン機能を利用することもできます(※今のところトロフィー管理機能以外はログインの必要無し)。
>注)：多少レスポンシブも意識しているつもりですが、スマートフォンではサイトの動作がやや重い可能性があります。できればタブレット端末やPCでの利用をおすすめします。

# レース計画機能について
サイトのうち、**レース計画機能**について少し詳しく紹介します。

## ①作成するスケジュールの内容を設定しよう！
作成対象のシナリオ・キャラクターをはじめ、出来る限り現実的なプランとするために、細かな項目を「詳細設定」から設定できます。それぞれの項目の内容は以下の通り(サイト内のヘルプでも同等の内容が確認できます)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487606/b08a7b15-37b3-6e6e-cd33-a46fc97a329a.png)

### シナリオ・キャラクター・戦略選択
**『シナリオ・キャラクター・戦略選択』**では、スケジュール作成のための基本情報を設定できます。これらの項目を変更すると**自動的におすすめのスケジュールが再設定**されます(※レースカレンダーで個別に編集した内容は上書きされるので注意してください)。

#### シナリオ
育成シナリオを選択できます。

#### キャラクター
育成するキャラクターを選択できます。

#### 戦略
おすすめスケジュールの作成における基本方針が設定できます。**「ファン数最大化」・「ノルマ達成効率重視」**の2つの戦略が利用可能です。「ファン数最大化」ではシナリオ等の制約下で可能な限りファン数を稼ぐためにレースに出場します(ファン活・金策向け)。「ノルマ達成効率重視」ではシナリオ上達成すべきファン数のノルマをなるべく少ない出走数で満たすことを目標とします。

### 詳細設定
『詳細設定』では、スケジュール作成に関わる細かな項目を設定できます。

#### 余裕のあるノルマ達成計画(+%)
予想獲得ファン数は基本的に出走レース全てで1着を取ることが前提となっています(「負けイベント」を除く)が、実際には一部で1着を取り逃すことを想定し、**本来のファン数ノルマよりも一定の余裕を持ったスケジューリング**を行うことができます。例えば「10%」に設定し、「レジェンド達成(320000人)」のファン数ノルマを有効にした場合、育成終了時に352000人以上のファンを獲得できるようにします(※レースカレンダーから個別に出走レースを編集した場合でもこのノルマ目標を達成できない場合にはアラートが表示されます)。

#### 出走適正下限
出走するレースの適正下限を設定します。適正を満たさないレースは、おすすめのスケジュールの目標外出走対象レースとして選択されないほか、レースカレンダーにも表示されません(ただし、シナリオで目標となっているレースや既に選択中のレースはそのまま表示されます)。

#### ファンボーナス
サポートカードの編成によって変化するファンボーナスの値を設定できます。

#### 最大連続出場レース数
おすすめのスケジュール作成における最大連続出場レース数を設定できます。『レース疲れ』回避のため、基本的にはこの値を**「2」以下に設定することを推奨**します。なお目標外レースの後にシナリオで目標となっているレースに連続出走する場合は、『レース疲れ』のペナルティが発生しないため、この設定は無視されます。

#### 夏合宿中は目標外レースに出場しない
この項目を有効にすると、おすすめのスケジュール作成において夏合宿期間中は目標外レースに出走しなくなります。

#### 適正調節
因子継承等で適性を補正する場合に対応できます。この項目を変更すると、出走適正下限の設定と合わせて、おすすめのスケジュールでの目標外出走対象やレースカレンダーに表示されるスケジュールが変更されます。また、シナリオで目標となっているレースのうち、ウマ娘の適正に合致していないレース(※フィールド・距離適正がA・Aを合計2段階以上下回っている)は「負けイベント」と扱いファン数に加算しませんが、この項目を変更することによりその判定にも影響が出る場合があります。

#### クラス
おすすめのスケジュール作成における目標外出走レース対象や、レースカレンダ―に表示するレースのクラスを設定できます(シナリオで目標となっているレースや既に選択中のレースはそのまま表示されます)。おすすめのスケジュール作成のアルゴリズムでは基本的にファン数の多いGⅠやGⅡのレースが選択されやすい為、一般的な目的であれば、この項目を変更する必要はあまりありません。

### ファン数ノルマ一覧
**『ファン数ノルマ一覧』**では、達成すべきファン数ノルマの一覧を確認したり、各ノルマの有効/無効を切り替えることができます。

####全体シナリオの目標
URAシナリオ等で固有スキルレベルアップなどに必要なファン数ノルマです。

#### ウマ娘のシナリオ目標
一部のウマ娘にはファン数の目標などが設定されています。これらのノルマは必ず達成する必要があるため、無効化することができません。なお、目標人数が「(レース)」となっているものはレース勝利数目標です。

## ②スケジュールを作成しよう！
これらの設定を適切に設定したところで、「おすすめのスケジュールを作成」ボタンをクリックすることで、条件に合ったスケジュールが作成されます。作成されたスケジュールは**レースカレンダー**や**出走スケジュール**に反映されます。

## ③スケジュールを確認・編集しよう！
**『レースカレンダー』**では、各時期に開催される適正内のレースやシナリオの目標となっているレース、目標外として出走するレースを確認できます。また、目標外のレースにおいては個別に出走/非出走を編集することができます。

### シナリオの目標となっているレース
シナリオの目標となっているレースは**赤色**で表示されます。同時期のその他のレースは全て非表示になります。

### 現在のスケジュールで出走予定の目標外レース
現在のスケジュールで出走予定の目標外レースは**青色**で表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487606/ae97f33c-c1f3-e9a3-0848-88d09deb6fe0.png)

**出走スケジュール**ボタンをクリックすると、出走するレースのみを時系列順で確認することができます(※ノルマが達成できない場合はこのボタンは非常時になります)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487606/cc48f714-3c82-6e9e-3514-13f554b951b7.png)

### 目標外出走レースの編集
**「選択中」もしくは「未選択」と表示されているボタンをクリックすることで各レースごとに個別に出走するかどうかを編集することができ、変更内容はただちに「予想獲得ファン数」や「出走スケジュール」へと反映されます**。これらの個別編集は「詳細設定」における「最大連続出場レース数」や「夏合宿中は目標外レースに出場しない」といった設定を無視して行うことができます。なお、キャラクターを変更したり、おすすめのスケジュールを再作成した場合、これらの編集内容は全て上書きされるので注意してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487606/9c8fafec-b690-9aa6-8ebe-9d9f748f3d2d.png)
▲先ほどのスケジュールから一部を編集。サマースプリントシリーズ(函館スプリントS・キーンランドS・セントウルS)を出走レースに追加し、京王杯スプリングSを出走レースから除外した。

## 細かな仕様
- 予想獲得ファン数の値は**「出走レースに全て勝利した場合のファン数最低値」**です。実際には獲得ファン数はある程度ランダムであり、出走レースに全て勝利した場合の実際のファン数は予測値の**1.00倍~1.09倍**の範囲まで変動します。
- 一部ウマ娘において、適正の合わないレースに出走する場合(いわゆる**「負けイベント」**)ではファン数をカウントしない(0人扱い)ように配慮し、現実的に達成可能なプランとします。「負けイベント」であるかどうかはフィールドと距離の適正がAから合計で**2段階**以上下回っているかで判定しており、「詳細設定」から適正調節を行うことで判定が変更となる場合があります(例：マルゼンスキーの有馬記念は通常「負けイベント」扱いになりますが、長距離適性を上げることで判定が変更されます)。
- オグリキャップ・スマートファルコンなどのシナリオにおける「特定のクラスのレースで○回○着」という形式の目標にもある程度対応しています。ただし着順を考慮していません。つまり、「条件を満たすクラスのレースに○回以上出走する」と解釈してプランを作成しています。
- URAシナリオにおいて、メイクデビュー戦およびURAファイナルズのファン数は固定値として加算しています(メイクデビュー戦で1着を取れなかった場合のジュニア未勝利戦には対応していません)。
- URAシナリオにおいて、ダート系のウマ娘は固有スキルレベルアップに必要なファン数条件が緩和される仕様に対応済です。
- サイト上に明記していませんが、各レースの**出走に必要なファン数条件**を考慮したプランニングになっています(「メイクデビュー戦の次に皐月賞」などというようなプランは排除されているはずです、またファン数ボーナスが低すぎるとメイクデビュー戦の次にホープフルS等に出られなくなるはずです)。
- 最大連続出場レース数は目標外レースに関する設定です。例えば値を2に設定した場合、「目標外・目標外・目標外」「目標外・目標・目標外」というパターンは制限しますが、「目標外・目標外・目標」というようなパターンは制限しません。なお体力0によるレース疲れのリスクは考慮していません。
- 特にダートや短距離系のウマ娘は、初期設定では条件を満たすプランを作成できない場合があります。この場合はファン数ノルマの一部を無効にしたり、ファン数ボーナスをより高い値にするなど、条件を緩和することで実現可能なプランを作成可能です。
- マチカネフクキタルの第2・7目標レースはランダムに決定されますが、こちらは毎日杯・函館記念に固定しています。
- フジキセキのシナリオにおける目標分岐は三冠路線に固定しています。
- ダイワスカーレットのシナリオにおける目標分岐はオークスに固定しています(改善の余地あり)。

# 制作に使ったもの
詳しい説明は割愛しますが、使用したものは主に以下です。

- Vue.js
- Firebase
- Vercel
- 便利プラグイン各種(vue-modal-js・element-ui・vue-mqなど)
- 動的計画法
- 『ウマ娘』攻略wiki各所様
- **地道なjsonデータ作成作業を遂行する心**

# おわりに
UI等、諸問題はありますが、ファン数見積計算的な用途など、ある程度実用的なツールになったかな……(??)と信じています(そうでもなかったらごめんなさい)。今後も必要に応じて更新していきたいと思います(キャラとかシナリオはどんどん増えますし……)。不具合などまだまだありそうなので、もしお気づきのことがあればご報告いただけると助かります！