ケイバハック

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

オッズを計算するアプリ

有馬記念の過去3年分の単勝オッズを計算するコンソールアプリ

有馬記念の過去3年分の単勝オッズを計算するコンソールアプリ

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

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

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

では、本題です。今回は、有馬記念の過去3年分の単勝オッズを計算するコンソールアプリを作ります。まずは、次の動画で、そのアプリが動作する様子を確認し、そのイメージをつかんでください。

ご覧いただくとわかる通り、今回のアプリは、有馬記念の2014年〜2016年の単勝の発売票数と勝馬の発売票数を元に、そのオッズを計算するためのアプリです。

このような終わったレースのオッズは、JRAの公式サイトで、過去の成績データを確認すると確認できるものです。ですが、それをあえて、「単勝の発売票数と勝馬の発売票数から、自分で計算してみよう」と言う趣旨のアプリです。

ちなみに、今回のアプリですが、以下3つの記事で学んだ内容を総合したものとなっています。

ですので、これらの記事をまだ試していない方は、先にこの3つの記事を試してください。と言うのも、今回の記事では、この3つの記事で学んだ内容を知っている前提で解説するからです。

ソースコード

では、今回のアプリのソースコードをご紹介すると、次の通りです。

Program.cs

using System;

namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            //有馬記念2014〜2016までのデータを配列で定義
            ArimaKinen[] arimaList = new ArimaKinen[]
            {
                new ArimaKinen(){Year=2014, 
                    HatsubaiHyosu=21338682, KachiumaHyousu=1946714 },
                new ArimaKinen(){Year=2015, 
                    HatsubaiHyosu=23783595, KachiumaHyousu=1114668 },
                new ArimaKinen(){Year=2016, 
                    HatsubaiHyosu=27140062, KachiumaHyousu=8055932 }
            };

            //配列の中身を繰り返しの出力
            foreach(var arima in arimaList)
            {
                Console.WriteLine(arima);
            }
        }
    }

    //有馬記念の単勝の発売票数を表現するためのクラス
    public class ArimaKinen
    {
        //開催年
        public int Year { get; set; }

        //単勝の発売票数
        public long HatsubaiHyosu { get; set; }

        //単勝の勝馬の発売票数
        public long KachiumaHyousu { get; set; }

        //自分のデータを文字列として出力するメソッド
        public override string ToString()
        {
            return $"[{Year}]発売票数(勝馬/全体): {KachiumaHyousu}/{HatsubaiHyosu}, {Odds()}倍";
        }

        //オッズを計算するメソッド
        public double Odds()
        {            
            //W(当該勝馬に対する勝馬投票券の総券面金額)
            double W = KachiumaHyousu * 100;

            //D(出走した馬であって勝馬以外のものに対する勝馬投票券の総券面金額)
            double D = (HatsubaiHyosu - KachiumaHyousu) * 100;

            //P(勝馬の数)
            double P = 1; //単勝なので1

            //R(JRAが投票法ごとに定めた率)
            double R = 0.8; //単勝なので80%

            //払戻対象総額を求める計算式:(W+D/P)×R
            double haraiModoshi = ( W + D / P) * R;

            //1票の払戻対象額
            double haraiModoshi1 = haraiModoshi / KachiumaHyousu;

            //1票の払戻対象額(10円未満切り捨て)
            // 10で割って小数を切り捨ててから10倍している
            double haraiModoshi1Kirisute = Math.Floor(haraiModoshi1 / 10) * 10;

            //オッズ
            return haraiModoshi1Kirisute / 100;
        }
    }
}

では、このソースコードについて解説します。今回のアプリでは、2014年から2016年までの有馬記念のデータを、ArimaKinenクラスの配列として、定義しています。

有馬記念の過去3年分の単勝の発売票数を表示するコンソールアプリのソースコードでは、この定義を3つの変数を使って定義していましたよね。ですが、このソースコードのように、クラスの配列として定義する方が、より便利です。

なぜかと言うと、配列として定義すると、繰り返し処理をすることができるようになるからです。例えば、このプログラムに、将来、2017年の有馬記念のデータを追加することを考えて見てください。

その場合、「arimaList」の配列に、そのデータを追加するだけで、済むことがわかりますよね。そして、結果を出力する部分は、プログラムを変更する必要がなくなります。

foreach文でも配列の中身を取り出せる

さて、配列に対して、そのような繰り返し処理を行う方法として、有馬記念の単勝オッズから票数を計算するコンソールアプリの記事では、「for文」を使いました。

一方で、今回のアプリでは、「foreach文」を利用しています。具体的には、次の行の箇所ですね。

foreach(var arima in arimaList)

「foreach文」は、このように配列の中から1つずつ要素を取り出して、繰り返し処理を行えます。この例では、「arimaList」が配列で、その配列から1つずつ取り出された変数が「arima」となります。

つまり、配列からこのように1つずつデータを取り出す方法として、「for文」でも、「foreach文」でも、どちらでも使えます。

プログラミングをするときには、このように同じ目的のことを、違う表現で行えることが、よくあります。ので、難しく考えず、まずは、色々な表現方法を学んでください。

色々とプログラムを書いていくうちに、「この場合は、for文だな」、「この場合は、foreach文だな」と言う使い所がわかってくるようになります。

クラスには処理(メソッド)も定義できる

このソースコードにおいても、有馬記念の情報は、ArimaKinenクラスで表現しています。そして、このクラスが持っている変数としては、有馬記念の過去3年分の単勝の発売票数を表示するコンソールアプリのソースコードと変わっていません。

一方で、今回のソースコードで変更した点は、オッズを計算する処理(メソッド)をクラスに追加したことです。具体的には、次の箇所ですね。

public double Odds()

このオッズを計算する処理で行なっている内容は、有馬記念の単勝オッズを計算するコンソールアプリの記事で紹介したものと同じです。

単勝の全体の販売票数と勝馬の販売票数から、JRAが公開している(W+D/P)×Rの式を使って、そのオッズを計算しています。ただ、その計算において、単勝の発売票数と単勝の勝馬の発売票数は、クラスに定義した変数を利用するように変更しています。

クラスには、このように変数だけではなく、処理(メソッド)を定義できると言うことを押さえておいてください。

Return Top