ケイバハック

競馬ソフトは自分で作ろう!

オッズを計算するアプリ

有馬記念の単勝オッズから票数を計算するコンソールアプリ

有馬記念の単勝オッズから票数を計算するコンソールアプリ

今回は、競馬ソフトを開発してみたいプログラミング未経験者のうち、.NET Core環境での開発手順の基本が分かっている人に向けての情報です。

「.NET Core環境での開発手順って何?」という方は、まずは、次の記事から読み進め、.NET Core環境での開発手順の基本を学んでください。

.NET Core環境でのコンソールアプリを作るときの基本手順

では、本題です。今回は、有馬記念の単勝オッズから票数を計算するコンソールアプリを作ります。で、先にそのアプリを実際に動かした動画を見て、そのイメージを掴んでください。

この動画から分かる通り、このアプリを実行すると、有馬記念2016の馬名、単勝のオッズ、その票数の一覧が表示されます。

で、JRAのレース結果において、公開されるデータでは、勝馬の票数しかわかりませんよね。それ以外の馬については、オッズのみがわかり、具体的な票数がわかりません。

「その票数をオッズから計算してみよう」というのが、今回作るアプリの趣旨です。ただ、今回作るアプリで計算される票数は、あくまで大よその値となります。というのも、オッズはそれが求まるにあたり、払戻金の10円未満の額が切り捨てられるからです。

それによって、オッズから票数を逆算しようとすると、正確な票数にならないんですね。そのため、あくまで、おおよその票数しか求めることができません。

有馬記念2016の単勝オッズと勝馬の発売票数

では、まず、今回のアプリを作るために必要なデータの準備から始めます。今回のアプリのために必要なデータは、次の3点です。

  1. 有馬記念2016の全馬の単勝オッズ
  2. 単勝の勝馬の発売票数
  3. 単勝の勝馬のオッズ

その値は、JRAの公式サイトの年度別全成績 2016年のページで確認できます。調べると次の通りです。

  1. 有馬記念2016の全馬の単勝オッズ: 下の表に記載
  2. 単勝の勝馬の発売票数: 8,055,932票
  3. 単勝の勝馬のオッズ: 2.6倍
馬番 馬名 単勝オッズ
1 キタサンブラック 2.7
2 ゴールドアクター 7.9
3 ムスカテール 202.3
4 ヤマカツエース 32.6
5 サムソンズプライド 180.3
6 サウンズオブアース 8.7
7 マルターズアポジー 83.1
8 ミッキークイーン 21.9
9 ヒットザターゲット 189.6
10 アドマイヤデウス 51.5
11 サトノダイヤモンド 2.6
12 サトノノブレス 155.2
13 デニムアンドルビー 71.0
14 シュヴァルグラン 16.2
15 アルバート 68.0
16 マリアライト 19.3

では、このデータを使って、単勝オッズからその票数を計算するプログラムを作ります。

ソースコード

では、今回作るアプリのソースコードを次に示します。

Program.cs

using System;

namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            //単勝の勝馬の発売票数
            int kachiumaHyosu = 8055932;

            //単勝の勝馬のオッズ
            double kachiumaOdds = 2.6;

            //有馬記念2016の馬名リスト
            string[] bameiList = new string[]{
                "キタサンブラック",
                "ゴールドアクター",
                "ムスカテール",
                "ヤマカツエース",
                "サムソンズプライド",
                "サウンズオブアース",
                "マルターズアポジー",
                "ミッキークイーン",
                "ヒットザターゲット",
                "アドマイヤデウス",
                "サトノダイヤモンド",
                "サトノノブレス",
                "デニムアンドルビー",
                "シュヴァルグラン",
                "アルバート",
                "マリアライト"
            };

            //有馬記念2016の単勝オッズのリスト
            double[] oddsList = new double[]{
                2.7,
                7.9,
                202.3,
                32.6,
                180.3,
                8.7,
                83.1,
                21.9,
                189.6,
                51.5,
                2.6,
                155.2,
                71,
                16.2,
                68,
                19.3
            };

            //馬名リストの項目数回繰り返す(iは0〜15の値となる)
            for(var i=0; i<bameiList.Length; i++){
                
                //該当番号の馬名を設定
                string bamei = bameiList[i];

                //該当番号のオッズを設定
                double odds = oddsList[i];

                //オッズから票数を計算する
                double hyousu = Math.Floor(kachiumaOdds / odds * kachiumaHyosu);

                //結果を出力する
                Console.WriteLine($"{i+1}.{bamei}({odds}倍): {hyousu}票");
            }
 
        }
    }
}

このプログラムのソースコードを解説します。まず、このプログラムの最初では、単勝の勝馬の発売票数と単勝の勝馬のオッズを変数として定義しています。

続いて、有馬記念2016の馬名リストと単勝オッズのリストを変数として定義しています。で、このリストを定義するにあたり、「配列」という概念を利用しています。

「配列」とは、このように、同じ型の変数をまとめて定義するために使います。このプログラムでは、馬名リストでは、文字列型(string)の変数を16個、オッズのリストでは、浮動小数点数型(double)の変数を16個まとめて定義しています。

このプログラムで、なぜ配列を使うのかというと、その方が便利だからです。もしこれを配列を使わなければ、次のように、16個の変数を個別に用意することになります。

string bamei1 = "キタサンブラック";
string bamei2 = "ゴールドアクター";
string bamei3 = "ムスカテール";
string bamei4 = "ヤマカツエース";
string bamei5 = "サムソンズプライド";
string bamei6 = "サウンズオブアース";
string bamei7 = "マルターズアポジー";
string bamei8 = "ミッキークイーン";
string bamei9 = "ヒットザターゲット";
string bamei10 = "アドマイヤデウス";
string bamei11 = "サトノダイヤモンド";
string bamei12 = "サトノノブレス";
string bamei13 = "デニムアンドルビー";
string bamei14 = "シュヴァルグラン";
string bamei15 = "アルバート";
string bamei16 = "マリアライト";

これを見るだけで、16個の変数を用意するのが面倒なことがわかりますよね。

for文で繰り返し処理を定義

また、配列には、この「まとめて変数を定義できる」ということ以外にも、便利な特徴があります。その特徴とは、「配列の中身を1つずつ取り出して、繰り返し処理をする」ということを行えることです。

このソースコードでは、「for文」と呼ばれる繰り返し処理を利用して、それを実際に行なっています。具体的には、次の行ですね。

for(var i=0; i<bameiList.Length; i++){

このfor文のポイントは、「var i=0」で用意している、変数iにあります。このiは、0から始まり、処理を1回繰り返すごとに1ずつ増えます。

そして、繰り返す回数の上限は、「i<bameiList.Length」で定義されています。bameiListの配列の要素の数は、16ですので、「i<16」ということになります。

「i++」は、「繰り返し処理を一度行ったら、iを1増やす」ということを意味しています。

つまり「iを0から始め、1ずつ増やし、16になる前まで繰り返し実行して」というのが、このfor文の意味です。そして、この場合は、計16回、処理を繰り返して行うことになります。

配列は添え字を使って中身を取り出せる

そして、0〜15までの値をとるiを利用すると、馬名リストやオッズのリストから、1つずつ、その要素を取り出すことができます。例えばですが、次のイメージです。

bameiList[0]; //キタサンブラック
bameiList[5]; //サウンズオブアース
bameiList[15]; //マリアライト;

この例では、配列の添字として、0、5、15など、具体的な数字を入れています。この具体的な数値の代わりに、iを利用するというわけですね。

そして、iは0から15までの値を取りますので、次のようにすることで、馬名リストのすべての要素を取り出すことができます。

string bamei = bameiList[i];

ちなみに、プログラミング言語のC#において、配列の添え字は、0から始まります。1から始まりませんので、ご注意ください。

同様に、その添え字に対応する馬の単勝オッズも、次のように取り出せます。

double odds = oddsList[i];

あとは、この取り出した単勝オッズと、勝馬のオッズの比を求め、その逆数を勝馬の発売票数にかければ、そのオッズの大よその票数が求まります。

次に読むべき記事: 有馬記念の過去3年分の単勝の発売票数を表示するコンソールアプリ

Return Top