Alpha 版

三山くずしゲームの Alpha 版です。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プログラムの説明

  1. 人間側の先手で、コンピュータと対戦します。
    /*************************************/
    /*★ 三山くずし Alpha版    前田 稔 ★*/
    /*************************************/
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    
    public class MyForm : Form
    {
        Miyama   App;
        int      Teban;
        int[]    WT = new int[3];   //一手前の人間側の状態
    
        public MyForm()
        {
            Text = "三山くずしゲーム";
            Width = 600;
            Height = 400;
            App = new Miyama(@"c:\data\test\jewel.gif");
            App.Settbl();
            Teban = 1;
            Paint += new PaintEventHandler(MyHandler);
            MouseDown += new MouseEventHandler(OnMyMouseDown);
        }
    
        private void MyHandler(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            if (App.bmp == null)    Application.Exit();
            App.View(g);
        }
    
        private void OnMyMouseDown(object sender, MouseEventArgs e)
        {   Point   pt = new Point();
            DialogResult rc;
            if (e.Button == MouseButtons.Left)  //マウスの左ボタン
            {   if (Teban==1)                   //人間側の手番
                {   WT[0] = App.T[0];
                    WT[1] = App.T[1];
                    WT[2] = App.T[2];
                    pt.X = e.X;
                    pt.Y = e.Y;
                    if (App.ManPlay(pt)==false)
                    {   MessageBox.Show("エラーです。もう一度クリックして下さい。");
                        return;
                    }
                    else    Teban = 0;
                }
                else                            //コンピュータの手番
                {   switch(App.Play())
                    {   case 0: break;
                        case 1: rc= MessageBox.Show("私の勝ちです。再挑戦しますか?","選択",
                                    MessageBoxButtons.YesNo,MessageBoxIcon.Question);
                                if (rc==DialogResult.Yes)
                                {   App.Settbl();  }
                                else    Application.Exit();
                                break;
                        case 2: rc= MessageBox.Show("私の負けです。再挑戦しますか?","選択",
                                    MessageBoxButtons.YesNo,MessageBoxIcon.Question);
                                if (rc==DialogResult.Yes)
                                {   App.Settbl();  }
                                else    Application.Exit();
                                break;
                   }
                   Teban = 1;
               }
            }
            if (e.Button == MouseButtons.Right) //マウスの右ボタンで待った
            {   App.T[0] = WT[0];
                App.T[1] = WT[1];
                App.T[2] = WT[2];
                Teban = 1;
            }
            Invalidate();
        }
    
        // Title Var Message
        public void VerMsg(int v1, int v2)
        {   string wstr;
            wstr = "v1=" + v1.ToString() + "  v2=" + v2.ToString();
            this.Text = wstr;
        }
    }
    
    //☆ 三山 Object Class
    class Miyama
    {
        public  Bitmap  bmp;
        public  int[]   T = new int[3];         //山の石数
        Random  rand = new Random();
        static  Point bas = new Point(50, 240); //石の左上座標
        static  int   xsiz = 180;               //山の横幅
    
        // Constructor
        public Miyama(string file)
        {
            try
            {   bmp= new Bitmap(file);   }
            catch
            {   MessageBox.Show("イメージが取得できません", "Error");  }
        }
    
        // 山の石を表示
        public void View(Graphics g)
        {   int     i,j,x,y;
            if (bmp==null)  return;
            for(i=0; i<3; i++)          // 山番号
                for(j=0; j<T[i]; j++)   // 山の石数
                {   x= i*xsiz+(j/5)*50+bas.X;
                    y= bas.Y-(j%5)*50;
                    g.DrawImage(bmp,x,y);
                }
        }
    
        // 山に乱数で石を設定
        public void Settbl()
        {   int     i;
            while(true)
            {   for(i=0; i<3; i++)  T[i]= rand.Next(15)+1;
                if (T[0]!=T[1] && T[0]!=T[2] && T[1]!=T[2])  return;
            }
        }
    
        // Player がプレイする
        public bool ManPlay(Point pt)
        {   int wy,wn;
            wy = Yama(pt);
            wn = Num(pt);
            if (wy<0 || wy>2)  return false;
            if (wn<0 || wn>14) return false;
            if (T[wy] <= wn)   return false;
            T[wy] = wn;
            return true;
        }
    
        // コンピュータがプレイする
        public int Play()
        {   int     n1;         //石が残っている山の数
            int     n2;         //石が一個だけの山の数
            int     w;          //石が一番多い山の番号
            int     i,n=0;
    
            for(i=n1=n2=0,w=0; i<3; i++)
            {   if (T[i]!=0)
                {   n1++;
                    if (T[i]==1)    n2++;
                    if (T[i]>T[w])  w= i;
                }
            }
            switch(n1)
            {   case 0: return(1);                  //三個の山が空(コンピュータの勝ち)
                case 1: //石が残っている山は一個
                        if (n2==1)                  //最後の石(コンピュータの負け)
                        {   T[w] = 0;
                            return(2);
                        }
                        //一個を残して全て取り除く
                        T[w] = 1;
                        return(0);                  //一個だけ残す
                case 2: //石が残っている山は二個
                        if (n2==0)  break;
                        T[w] = 0;
                        return(0);                  //一個だけ残す
                case 3: //石が残っている山は三個 
                        if (n2!=2)  break;
                        T[w] = 1;                   //1,1,1
                        return(0);
            }
            w= T[0]^T[1]^T[2];
            for(i=0; i<3; i++)
            {   n=T[i]^w;
                if (n<T[i]) break;
            }
            if (i>2)    //人間側の勝ち筋に入っている
            {   while(T[i=rand.Next(3)]==0);
                n= rand.Next(T[i]);
            }
            T[i] = n;
            return(0);
        }
    
        // 座標の山番号(0,1,2)
        public int Yama(Point pt)
        {   int wk;
            wk = (pt.X-bas.X)/xsiz;
            return wk;
        }
    
        // 座標の石の数(0 ~ 14)
        public int Num(Point pt)
        {   int wk,wx;
            wx = (pt.X-bas.X)%xsiz;
            wx = (wx/50)*5;
            wk = (bas.Y-pt.Y+50)/50+wx;
            return wk;
        }
    }
    
    class form01
    {
        public static void Main()
        {
            MyForm mf = new MyForm();
            Application.Run(mf);
        }
    }
    
  2. 通常では人間側が勝てないので、一手だけ「待った」機能を設定します。
    本当は一手だけ待ったをしても、どうにもならないのですが。 (^_^;)
    Teban は、どちらの手番かの識別です。
        int[]    WT = new int[3];   //一手前の人間側の状態
        int      Teban;
        
  3. マウスの左ボタンで、プレイします。
    コンピュータの手番のときは、適当にクリックして下さい。
            if (e.Button == MouseButtons.Left)  //マウスの左ボタン
            {   if (Teban==1)                   //人間側の手番
                {   ・・・
                    if (App.ManPlay(pt)==false)
                    {   MessageBox.Show("エラーです。もう一度クリックして下さい。");
                        return;
                    }
                    else    Teban = 0;
                }
                else                            //コンピュータの手番
                {    ・・・
                }
        
  4. マウスの右クリックで一手だけ「待った」が出来ます。
            if (e.Button == MouseButtons.Right) //マウスの右ボタンで待った
            {    ・・・
            }
        

[Previous Chapter ↑] クリック座標

前田稔(Maeda Minoru)の超初心者のプログラム入門