2013年8月16日金曜日

打線シュミレーターを作ろうとする

using System;
class Player
{
    public string name;
    public int pa, ab, hit, single, two, three, hr, bb;
    public double avg, obp, slg, ops;

    public void data(string name, int pa, int hit, int two, int three, int hr, int bb)
    {
        this.name = name;
        this.pa = pa;
        this.ab = pa - bb;
        this.hit = hit;
        this.single = hit-two-three-hr;
        this.two = two;
        this.three = three;
        this.hr = hr;
        this.bb = bb;
        this.avg = (double)(single + two + three + hr) / this.ab;
        this.obp = (double)(hit + bb) / this.pa;
        this.slg = (double)(single + two * 2 + three * 3 + hr * 4) / this.ab;
        this.ops = this.obp + this.slg;
        Console.Write("Name: {0}, Avg: {1}, OBP: {2}, SLG: {3}, OPS: {4}\n", this.name, (avg).ToString("#.###"), (obp).ToString("#.###"), (slg).ToString("#.###"),(ops).ToString("#.###"));
    }

    public void data(){
        Console.Write("Name: {0}, Avg: {1}, OBP: {2}, SLG: {3}, OPS: {4}\n", this.name, (this.avg).ToString("#.###"), (this.obp).ToString("#.###"), (this.slg).ToString("#.###"),(this.ops).ToString("#.###"));
    }
}

class StartingMenber : Player
{
    public int l_pa, l_ab, l_hit, l_single, l_two, l_three, l_hr, l_bb, l_daten;
    public double l_avg,l_obp,l_slg,l_ops;

    public StartingMenber()
    {
        this.l_pa = 0;
        this.l_ab = 0;
        this.l_hit = 0;
        this.l_single= 0;
        this.l_two = 0;
        this.l_hr = 0;
        this.l_bb = 0;
        this.l_three = 0;
        this.l_daten = 0;
    }
    public void ShowLogData()
    {
        this.l_ab = this.l_pa - this.l_bb;
        this.l_avg = (double)(this.l_single + this.l_two + this.l_three + this.l_hr) / this.l_ab;
        this.l_obp = (double)(this.l_single + this.l_two + this.l_three + this.l_hr + this.l_bb) / this.l_pa;
        this.l_slg = (double)(this.l_single + this.l_two * 2 + this.l_three * 3 + this.l_hr * 4) / this.l_ab;
        this.l_ops = this.l_obp + this.l_slg;
        Console.Write("Name: {0:0.000}, Avg: {1}, OBP: {2}, SLG: {3}, OPS: {4} 打点: {5}\n", this.name, (this.l_avg).ToString("#.###"), (this.l_obp).ToString("#.###"), (this.l_slg).ToString("#.###"), (this.l_ops).ToString("#.###"),this.l_daten);
    }
     
}

class Baseball
{
    public static int[] baseph = { 0, 0, 0, 0 };
    public static int outcount = 0;
    public static int gamenum = 200;
    public static bool kai = true;
    static void Main()
    {
        Player kikuchi = new Player();
        kikuchi.data("廣瀬", 252, 62, 8, 1, 7, 41);
        Console.Write("試合数を入力してください :");
        gamenum = int.Parse(Console.ReadLine());
     
        StartingMenber[] team1 = new StartingMenber[9];
        for (int i = 0; i < 9; i++)
        {
            team1[i] = new StartingMenber();
            Console.Write("{0}番", i + 1);
            team1[i].data("廣瀬", 252, 62, 8, 1, 7, 41);
        }
        int seed = Environment.TickCount;
        for (int k = 0; k < gamenum; k++)
        {
            outcount = 0;
            seed +=2;
            for (int num = 0; outcount < 27; num++)
            {
                if (kai)
                {
                    Console.Write("{0}回の攻撃\n", outcount / 3 + 1);
                    kai = false;
                }
                getdageki(ref team1[num % 9], ref baseph, seed++);
            }
        }
        Console.Write("得点:{0} 平均得点{1}\n", baseph[3], ((double)baseph[3] / gamenum).ToString("#.000"));
        for (int i = 0; i < 9; i++)
        {
            team1[i].ShowLogData();
        }
     
    }

    public static void getdageki(ref StartingMenber batter, ref int[] b, int seed)
    {
        Random r = new Random(seed);
        int d_kekka = r.Next(batter.pa);
        int t = 0;
        batter.l_pa++;
        if (d_kekka <= batter.bb)
        {
            Console.Write("フォアボール\n");
            batter.l_bb++;
            if(b[0]==0){
                b[0] = 1;
            }
            else if (b[1] == 0)
            {
                b[1] = 1;
            }
            else if (b[2] == 0)
            {
                b[2] = 1;
            }
            else
            {
                t++;
            }
        }
        else if (d_kekka <= batter.bb + batter.hr)
        {
            Console.Write("ホームラン!\n");
            batter.l_hr++;
            t += b[0] + b[1] + b[2] + 1;
            for (int k = 0; k < 3; k++)
            {
                b[k] = 0;
            }
        }
        else if (d_kekka <= batter.bb + batter.hr + batter.three)
        {
            Console.Write("スリーベース!\n");
            batter.l_three++;
            t += b[0] + b[1] + b[2];
            b[0] = 0;
            b[1] = 0;
            b[2] = 1;
        }
        else if (d_kekka <= batter.bb + batter.hr + batter.three + batter.two)
        {
            Console.Write("ツーベス\n");
            batter.l_two++;
            t += b[1] + b[2];
            if (b[0] == 0)
            {
                b[1] = 1;
                b[2] = 0;
                b[0] = 0;
            }
            else if (b[0] == 1)
            {
                b[2] = 1;
                b[1] = 1;
                b[0] = 0;
                int rand2 = r.Next(100);
                if (outcount % 3 == 0 && rand2 <= 15)
                {
                    t++;
                    b[2] = 0;
                }
                else if (outcount % 3 == 1 && rand2 <= 25)
                {
                    t++;
                    b[2] = 0;
                }
                else if (outcount % 3 == 2 && rand2 <= 50)
                {
                    t++;
                    b[2] = 0;
                }
            }
        }
        else if (d_kekka <= batter.bb + batter.hit)
        {
            Console.Write("ヒット\n");
            batter.l_single++;
            t += b[2];
            b[2] = b[1];
            b[1] = b[0];
            b[0] = 1;
            int rand1 = r.Next(100);
            if (b[2] == 1)
            {
                if (outcount % 3 == 0 && rand1 <= 30)
                {
                    t++;
                    b[2] = 0;
                }
                else if (outcount % 3 == 1 && rand1 <= 50)
                {
                    t++;
                    b[2] = 0;
                }
                else if (outcount % 3 == 2 && rand1 <= 70)
                {
                    t++;
                    b[2] = 0;
                }
            }
            else if (b[1] == 1 && b[2] == 0 && rand1 <= 20)
            {
                b[2] = 1;
                b[1] = 0;
            }
        }
        else
        {
            outcount++;
            Console.Write("凡打\n");
            if (outcount % 3 == 0)
            {
                if (outcount != 27)
                {
                    Console.Write("チェンジ\n");
                    Console.Write("{0}回の攻撃\n", outcount / 3 + 1);
                }
                else { Console.Write("GameSet\n"); }
                b[0] = b[1] = b[2] = 0;
            }
            else if (b[2] == 1 && r.Next(100) >= 50)
            {
                t++;
                b[2] = 0;
            }
            else if (b[2] == 0 && b[1] == 1 && r.Next(100) <= 25)
            {
                b[2] = 1;
                b[1] = 0;
            }
            else if (b[1] == 0 && b[0] == 1 && r.Next(100) < 5)
            {
                b[1] = 1;
                b[0] = 0;
            }
        }
        tokuten(ref b[3], ref batter.l_daten, t);
    }

    public static void tokuten(ref int g_tokuten, ref int b_daten, int t)
    {
        g_tokuten += t;
        b_daten += t;
        if (t > 0)
        {
            Console.Write("{0}点得点!\n", t);
        }
    }
}

なんかいやってもゴミ2割打者廣瀬と3割後半神廣瀬が交互に並ぶ打線になってシュミレーターの意味を成さない!
おそらくrandomつくってるところがおかしいんだけど,何がおかしいのかさっぱりわからないから困ったぞ~

2013年8月11日日曜日

WHIPの扱い

WHIPの解釈と応用
http://baseballconcrete.web.fc2.com/alacarte/whip.html

最近良く聞くWHIP,あんまり有用じゃないっていうのを何処かで見たような気がしてたんだけど多分これですね.
めっちゃ綺麗にまとめられてる上に論理的ですっきり頭に入るのが良い.実験レポートでもこんな綺麗な文章書きたいね.
これを読んでると,野球の指標って人によって分かりやすさと正確さとどっちを求めるかが違うっていうのをちゃんと頭に入れて考えないといけないなって思う.
複雑すぎても一部のマニアックな人しかわからないし,かと言って打率とか出塁率,防御率みたいな簡単な指標だけで選手のすべてを判断できるかって言うとそうでもないし,正解は無いのかも.