じゃんけんバトルゲーム

プログラム同士が対戦する「じゃんけんバトルゲーム」を作成します。
あなたも強いプログラムを作成してバトルに参加しませんか?

紅の対戦プログラム

  1. じゃんけんバトルゲームで対戦する「紅 Class」「白 Class」から説明します。
    紅の対戦プログラム(Object Class) を定義した R_Class.cs ファイルです。
    // R_Class(紅) のプログラム
    using System;
    
    class R_Class
    {
        Random  rand;
    
        public R_Class()
        {
            rand = new Random();    //時間に応じて決まるシード値で初期化
            Console.WriteLine("紅 Class 1,20,8 を組み込む");
        }
    
        // 紅の手を出す
        public int R_Think()
        {
            return WeightRand(1,20,8);
        }
    
        // 情報の収集
        public void R_Info(int you, int my)
        {
        }
        
        // グー・チョキ・パーをパラメータの確率で出す
        public int WeightRand(int g, int c, int p)
        {   int x = rand.Next(g+c+p);
            if (x<g)        return 0;
            else if (x<g+c) return 1;
            else            return 2;
        }
    }
    
  2. 必ず必要な関数(メソッド)は R_Think() と R_Info() だけです。
    R_Think() では、グー・チョキ・パー を 1:20:8 の確率で出します。
    R_Info() 関数は、必要なければ枠だけでOKです。
        // 紅の手を出す
        public int R_Think()
        {
            return WeightRand(1,20,8);
        }
        
        // グー・チョキ・パーをパラメータの確率で出す
        public int WeightRand(int g, int c, int p)
        {   int x = rand.Next(g+c+p);
            if (x<g)        return 0;   //グー・チョキ・パー
            else if (x<g+c) return 1;   //チョキ
            else            return 2;   //パー
        }
    
        // 情報の収集(you:対戦相手の手)
        public void R_Info(int you, int my)
        {
        }
    
  3. 乱数を使うので、コンストラクタで乱数を初期化します。
    またこのプログラムが起動されたことを確認するために Console.WriteLine() でメッセージを印字します。
        public R_Class()
        {
            rand = new Random();    //時間に応じて決まるシード値で初期化
            Console.WriteLine("紅 Class 1,20,8 を組み込む");
        }
    

白の対戦プログラム

  1. 白の対戦プログラム(Object Class) を定義した W_Class.cs ファイルです。
    紅が白に変わるだけで同じ要領です。
    // W_Class(白) のプログラム
    using System;
    
    class W_Class
    {
        Random  rand;
    
        public W_Class()
        {
            rand = new Random();    //時間に応じて決まるシード値で初期化
            Console.WriteLine("白 Class 5,33,21 を組み込む");
        }
    
        // 白の手を出す
        public int W_Think()
        {
            return WeightRand(5,33,21);
        }
    
        // 情報の収集(you:対戦相手の手)
        public void W_Info(int you, int my)
        {
        }
        
        // グー・チョキ・パーをパラメータの確率で出す
        public int WeightRand(int g, int c, int p)
        {   int x = rand.Next(g+c+p);
            if (x<g)        return 0;
            else if (x<g+c) return 1;
            else            return 2;
        }
    }
    

バトルゲームのメインプログラム

  1. じゃんけんバトルゲームのメインプログラム JyankenBattle.cs です。
    // じゃんけんバトルの MAIN プログラム
    // csc JyankenBattle.cs R_Class.cs W_Class.cs
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    
    public class MyForm : Form
    {
        R_Class r_cls = new R_Class();
        W_Class w_cls = new W_Class();
    
        Bitmap  score_img, gu_img, ti_img, pa_img;
        TextBox textBox1;
        int     red, white;             //紅と白の手
        int     r_score, w_score;       //紅と白の得点
        int     game_cnt;               //ゲームカウント
        int[,]  rw_cnt= new int[2,3];   //紅白のグー,チョキ,パーをカウント
        Timer   timer1;
        System.ComponentModel.IContainer components;
    
        public MyForm()
        {
            InitializeComponent();
            Paint += new PaintEventHandler(MyHandler);
            MouseDown += new MouseEventHandler(OnMyMouseDown);
            components = new System.ComponentModel.Container();
            timer1 = new System.Windows.Forms.Timer(this.components);
            timer1.Interval = 100;
            timer1.Tick += new System.EventHandler(this.timer1_Tick);
            try
            {
                score_img = new Bitmap("C:\\DATA\\Test\\score2.gif");
                gu_img    = new Bitmap("C:\\DATA\\Test\\jyanken0.gif");
                ti_img    = new Bitmap("C:\\DATA\\Test\\jyanken1.gif");
                pa_img    = new Bitmap("C:\\DATA\\Test\\jyanken2.gif");
            }
            catch
            {
                MessageBox.Show("画像ファイルが読めません!", "C:\\DATA\\Test\\");
                return;
            }
            r_score= 0;
            w_score= 0;
            for(int i=0; i<2; i++)
                for(int j=0; j<3; j++)
                    rw_cnt[i,j] = 0;
        }
    
        private void InitializeComponent()
        {
            // textBox1
            textBox1 = new System.Windows.Forms.TextBox();
            textBox1.Location = new System.Drawing.Point(20, 420);
            textBox1.Size = new System.Drawing.Size(360, 40);
    
            this.ClientSize = new System.Drawing.Size(400, 460);
            this.Controls.Add(this.textBox1);
            this.Name = "MyForm";
            this.ResumeLayout(false);
            this.PerformLayout();
        }
    
        private void MyHandler(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.DrawImage(score_img, 20, 20);
            switch(red)
            {   case 0: g.DrawImage(gu_img, 60, 280);
                        break;
                case 1: g.DrawImage(ti_img, 60, 280);
                        break;
                case 2: g.DrawImage(pa_img, 60, 280);
                        break;
            }
            switch(white)
            {   case 0: g.DrawImage(gu_img, 200, 280);
                        break;
                case 1: g.DrawImage(ti_img, 200, 280);
                        break;
                case 2: g.DrawImage(pa_img, 200, 280);
                        break;
            }
        }
        
        private void OnMyMouseDown(object sender, MouseEventArgs e)
        {
    /*
            red = r_cls.R_Think();
            white = w_cls.W_Think();
            Judge(red, white);
            r_cls.R_Info(white, red);
            w_cls.W_Info(red, white);
            Invalidate();
    */
            if (e.Button == MouseButtons.Left)
            {   timer1.Start();
                return;
            }
            if (e.Button == MouseButtons.Right)
            {   timer1.Stop();
                Console.WriteLine("\nゲームカウント {0}", game_cnt);
                Console.Write("紅:グー・チョキ・パー");
                for(int j=0; j<3; j++)
                    Console.Write("  {0}", rw_cnt[0,j]);
                Console.Write("\n白:グー・チョキ・パー");
                for(int j=0; j<3; j++)
                    Console.Write("  {0}", rw_cnt[1,j]);
            }
        }
    
        private void timer1_Tick(object sender, EventArgs e)
        {
            red = r_cls.R_Think();
            white = w_cls.W_Think();
            Judge(red, white);
            r_cls.R_Info(white, red);
            w_cls.W_Info(red, white);
            Invalidate();
        }
    
        // 勝敗の判定と得点の計算
        private void Judge(int red, int white)
        {   string  str= "";
            int w;
    
            game_cnt++;
            rw_cnt[0,red]++;        //紅白のグー,チョキ,パーをカウント
            rw_cnt[1,white]++;
            w = ((red+3)-white)%3;
            switch(w)
            {   case 1:
                    str= "白の勝ちです        ";
                    switch(white)
                    {   case 0: //グーで勝ち
                            w_score += 5;
                            break;
                        case 1: //チョキで勝ち
                            w_score += 2;
                            break;
                        case 2: //パーで勝ち
                            w_score += 15;
                            r_score -= 5;
                            break;
                    }
                    break;
                case 2:
                    str= "赤の勝ちです        ";
                    switch(red)
                    {   case 0: //グーで勝ち
                            r_score += 5;
                            break;
                        case 1: //チョキで勝ち
                            r_score += 2;
                            break;
                        case 2: //パーで勝ち
                            r_score += 15;
                            w_score -= 5;
                            break;
                    }
                    break;    
                default:
                    str= "あいこです          ";
                    switch(white)
                    {   case 0: //グー
                            r_score += 3;
                            w_score += 3;
                            break;
                        case 1: //チョキ
                            r_score += 1;
                            w_score += 1;
                            break;
                    }
                    break;
            }
            str= str + "紅の得点:" + r_score.ToString() +
                       "                    白の得点:" + w_score.ToString();
            textBox1.Text = str;
        }
    }
    
    class form03
    {
        public static void Main()
        {
            MyForm mf = new MyForm();
            Application.Run(mf);
        }
    }
    
  2. スタートメニューから[すべてのプログラム][Visual C++ 2005 Express Edition][Visual Studio Tools] [Visual Studio 2005 コマンド プロンプト] から起動します。
    C:\Data\C#\Jyanken のフォルダーに移動して、直接 csc コマンドを叩きます。
    JyankenBattle.cs と R_Class.cs と W_Class.cs を同時にコンパイルして下さい。
    コンパイルが終われば *.exe を実行して下さい。
    (事前に画像ファイルを格納して下さい)
    >CD C:\Data\C#\Jyanken
    >CSC JyankenBattle.cs R_Class.cs W_Class.cs
    >JyankenBattle          
    
  3. R_Class, W_Class を new で生成して、メインプログラムに組み込んで紅白でじゃんけんバトルを実行します。
        R_Class r_cls = new R_Class();
        W_Class w_cls = new W_Class();
    
  4. 連続対戦するときは、左クリックで開始して右クリックで停止します。
    停止したときにゲームの回数と、紅白それぞれの「グー・チョキ・パー」のカウントを印字します。
    連続対戦では実行の詳しい確認(デバッグ)が出来ないので、クリックで1度だけ対戦出来るようにコメントアウトしています。
        private void OnMyMouseDown(object sender, MouseEventArgs e)
        {
    /*
            red = r_cls.R_Think();
            white = w_cls.W_Think();
            Judge(red, white);
            r_cls.R_Info(white, red);
            w_cls.W_Info(red, white);
            Invalidate();
    */
            if (e.Button == MouseButtons.Left)
            {   timer1.Start();
                return;
            }
            if (e.Button == MouseButtons.Right)
            {   timer1.Stop();
                Console.WriteLine("\nゲームカウント {0}", game_cnt);
                Console.Write("紅:グー・チョキ・パー");
                for(int j=0; j<3; j++)
                    Console.Write("  {0}", rw_cnt[0,j]);
                Console.Write("\n白:グー・チョキ・パー");
                for(int j=0; j<3; j++)
                    Console.Write("  {0}", rw_cnt[1,j]);
            }
        }
    
  5. タイマー関数で、右クリックされるまで連続してプレイします。
    紅白のクラスで情報を収集するために Info() 関数を呼び出します。
        private void timer1_Tick(object sender, EventArgs e)
        {
            red = r_cls.R_Think();
            white = w_cls.W_Think();
            Judge(red, white);
            r_cls.R_Info(white, red);
            w_cls.W_Info(red, white);
            Invalidate();
        }
    

[Next Chapter ↓] じゃんけん RW Battle
[Previous Chapter ↑] じゃんけん Class

超初心者のプログラム入門(C#)