LoginSignup
0
0

More than 3 years have passed since last update.

[ゲーム] 野球のバッターとピッチャーの勝負について

Last updated at Posted at 2019-05-12

[1]概要

ピッチャーの投げるボールと、バッターのバッティングの勝負についてです。

ピッチャーの能力(球速、コントロール、変化球、実際に投げられるコース)
バッターの能力(ミート、パワー)
などの能力があり、
どの球種を投げるか? コースはどこに投げるか?
結果(ボール、ストライク、ファール、ゴロ、ヒット、ホームラン…)はどうなるか?
などの一連の流れについて記載します。

ゲームはCPU同士の対戦を想定しています。
なのでユーザーの意志介入は、代打など監督の指示だけです。

守備と走塁はこちら↓
[ゲーム] 野球の守備と走塁について


[2]能力値について

○バッター
・ミート(0~1000)
・パワー(0~1000)

○ピッチャー
・球速(0~1000)→表示は100km~160kmにする
・コントロール(0~1000)
・変化球(0~1000)+変化球別の能力

のようにすべて0~1000で管理します。


[3]球種の決定

○その1:ストレートか変化球か
能力値で選択割合を変えます
球速が高い→ストレート多め
変化球が高い→変化球多め

(詳細)
ストレートの選択率は15%~85%の値をとります。
球速のパラメータが変化球のパラメータの2倍ある場合は85%
変化球のパラメータが球速のパラメータより2倍ある場合は15%
両方の値が同じ場合は50%
のような幅をとって計算します。

○その2:変化球の場合の球種決定
ランダムにしました…。
自分の変化球の球種の能力によって選択割合を変えてもいいと思います。
カウントの影響も入れてもいいと思います。(決め球にフォークなど)

球種決定とは関係ないですが、見逃しストライクと空振りストライクにする確率は球種別に所持させました。


[4]コースの決定

設定イメージ
20180623_コースゾーン01.png

・要素①:ストライクゾーンとボールゾーンとの設定について

20180623_コースゾーン00.png
図のように0~200で考えます。
100のきわどいコースを狙って、ストライクをとるのが理想です。

この数値はバッティングの勝負にも影響するようにしています。
200だと強い当たりになりやすくて、
100以下だと打ち損じが多くなるようにします。

・要素②:コントロールの幅がある

20180623_コースゾーン02.png

コントロールの幅は③を狙って投げて、実際に捕球される位置の範囲です。
投手のコントロール値が高いほど、この幅を小さくなるようにして、コントロールが安定するようにします。

※補足1
球速や変化球の能力が上がると、より大きなコントロール値も必要になるようにしています。
このおかげで序盤はコントロール値が低くても、球速や変化球の能力も低いので、コントロールが悪い(毎回コースが悪い)という現象は起きにくくなります。

※補足2
実際のゲームでは、コントロールの幅を複数用意しています。
正常のコントロール幅(60%)、1.5倍のコントロール幅(30%)、全範囲(10%)など、
投げるコースに幅が出るようにしています。

・要素③:カウントによってどこを狙うか決める

ストライクが多い→ボールでもOK
ボールが多い→ストライクを狙いたい

int[][] カウントごとのコースの狙う場所   = 
{   //ストライク数  0,    1,  2
    new int[]{ 80,  70, 60 },       //ボール数0
    new int[]{ 90,  80, 70 },       //ボール数1
    new int[]{ 100, 90, 80 },       //ボール数2
    new int[]{ 120, 100, 90 },      //ボール数3
};

数値はそのまま①の位置情報です。
基本100を狙いますが、ストライクカウントに余裕がある場合はボール寄り(0に近い方)、ストライクがとれない場合はストライク寄り(200に近い方)を狙います。

②のコントロールの幅の影響で、ボールゾーンを狙ってもストライクゾーンに投げる可能性もあります。


・捕球位置を決定する

20180623_コースゾーン03.png
上の①~③で、ストライクゾーンかボールゾーンと、コースの厳しさが決定します。
あとは内角か外角か(左右の情報)と、低めか高めか(上下の情報)を決定して捕球位置を決定します。

同じ「きわどいコース」(ストライクゾーンの外角)でも、内角か外角、低めか高めかで、全然違ってくるので設定に注意が必要です。

(詳細は保留です。この部分は作ってないので書けません!)


[5]バッティング勝負

[5-1]評価値と重み情報を用意します

eva:評価値
w:重み
とします

○バッター評価

・eva_ミート
・eva_パワー
・w_ミート:球種によって変化します(難しい変化球ほどミート値が要求される)
・w_パワー:球種によって変化します

バッター評価 = (w_ミート*eva_ミート + w_パワー*eva_パワー)/(w_ミート+w_パワー);

○ピッチャー評価

・eva_球速
・eva_コントロール(コースの算出で使用されてるのでここでは必要ないかも)
・eva_変化球
・w_球速:球種によって変化します(速度の速い球種で要求される)
・w_変化球:球種によって変化します(難しい変化球ほど能力が要求される)

+[3]の投球コースの補正(コースが最高→×1.2, コースが最低→×0.5)

ピッチャー評価 = (w_球速*eva_球速+ w_変化球*eva_変化球)/(w_球速+w_変化球);
ピッチャー評価 *= (0.5~1.2) //コースの補正


[5-2]上のバッター評価とピッチャー評価の勝負結果の評価値を算出します。

○勝負結果の評価値 = バッター評価 - ピッチャー評価
(高いほどバッターが勝ってる)

※注意
差で評価していますが、序盤と終盤でパラメータの大きさで差と評価値の取りうる値が変わるようにしましょう。
※例
序盤 Aさん70、Bさん10 評価値の差=60→勝敗評価100点(MAX)
終盤 Aさん7000、Bさん6940 評価値の差=60→勝敗評価100点?→50点くらいになるようにする


[5-3]バッターとピッチャーの勝負の結果を、動作に当てはめます。

[5-3-1]まず結果動作について、大まかに5つに分けます

・見送りボール
・ストライク
・ゴロ(内野フライ含む)
・ヒット
・ホームラン

▼見送りボールについて
・ボールがボールゾーンに来る場合
見送ります。バットは振りません。

・ボールがストライクゾーンに来る場合
この「見送りボール」は選択されません。

▼ストライクについて
・ボールがボールゾーンに来た場合
必ずスイングして空振りストライクにします。

・ボールがストライクゾーンに来た場合
見逃しストライクか、空振りストライクにします。これは球種ごとに確率で判断します。
(フォークは9割型空振り。手が出せない高速ストレートなどストレートは見逃しストライクの確率が高め。)

▼ゴロ、ヒット、ホームランについて
どれもバッターは必ずスイングして、バットにボールを当てます。
飛び方がそれぞれ異なります。
・ゴロ:本来のパワーの5%~30%
・ヒット:本来のパワーの40%~70%
・ホームラン:本来のパワーの90%~100%
「ゴロ」といっても内野安打になったり、「ヒット」が外野フライになることがあります。
正しくはゴロ性の当たり、ヒット性の当たり、ホームラン性の当たり です。
ファウルもそれぞれあります。

※補足
・なぜ5つの結果動作に分けたか?
打球のスピード、落下位置などを全て管理したかったためです。
分けない場合、ヒット率、ホームラン率などの調整が非常に難しくなります。


[5-3-2]5つの動作に選択割合値を設定して、動作を決定します

int[][] バッティング勝負の結果の割合データ      = 
{   //見送りボール ストライク  ゴロ  ヒット   ホームラン
        new int[]{130,  60,  100,  10,  1, },//eva_lose
        new int[]{160,  30,  50,  80,  25, },//eva_win
};

勝敗結果の評価値は0~1000でとっていました。
使用するパラメータは
勝敗結果の評価値=0のとき →index0(//eva_lose)
勝敗結果の評価値=1000のとき →index1(//eva_win)
のパラメータを利用します。
0,1000の間のパラメータは、それぞれindex0とindex1の値で補完します。
5つの動作の選択割合値が決定したら、それぞれの割合から動作を決定します。

(参考1:能力と勝敗評価値の例)
バッター:1000,ピッチャー:800のとき、評価値=400
バッター:1000,ピッチャー:500のとき、評価値=800

(参考2:5つの動作の選択割合値の計算)
評価値300のとき
・見送りボールの選択割合値 = バッティング勝負の結果の割合データ[0][0]×(1.0f-0.3f) + バッティング勝負の結果の割合データ[1][0]×0.3f;
・ストライクの選択割合値 = バッティング勝負の結果の割合データ [0][1]×(1.0f-0.3f) + バッティング勝負の結果の割合データ[1][1]×0.3f;
・ゴロ、ヒット、ホームランも同様

(参考3:選択割合値から動作の決定)

int sum = 5つの選択割合値の和
int rand = Random(sum);
for ( int i = 0; 5つ; i++  ){
    if ( rand < 選択割合値[i] ){
        動作の決定!!
        break;
    }
    rand -= 選択割合値[i];
}

動作が決まったら、あとはそれに沿って処理を加えましょう。
バッター→スイングする or しない
ボール→バッティングの軌道計算 or キャッチャーミット


以上で完了です!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0