カードをシャッフル

カードをシャッフルして、並べて描画します。
Windows(C++)でも シャッフルして表示 を作成しています。

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

カードをシャッフル

  1. カードをシャッフルするメソッドを追加して、神経衰弱のように並べて描画します。
    事前に @"c:\data\test\hanafuda.gif" を格納しておいて下さい。
    /*************************************/
    /*★ シャフルして並べる    前田 稔 ★*/
    /*************************************/
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    
    public class MyForm : Form
    {
        Card    App;
        int[]   T = new int[48];
        Point   bas = new Point(20,20);     //描画の左上座標
        Point   siz = new Point(54,80);     //Sprite の表示間隔
    
        public MyForm()
        {
            Text = "カードゲーム";
            Width = 700;
            Height = 400;
            App = new Card(@"c:\data\test\hanafuda.gif",51,75);
            Paint += new PaintEventHandler(MyHandler);
            App.Shuffle(T,48);
        }
    
        private void MyHandler(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            if (App.bmp == null)    Application.Exit();
            for(int i=0; i<48; i++)
                App.View(g,T[i],(i%12)*siz.X+bas.X,(i/12)*siz.Y+bas.Y);
        }
    }
    
    //☆ Card Object Class
    class Card
    {
        public  Bitmap  bmp;
        public  int     W;      //Sprite の幅
        public  int     H;      //Sprite の高さ
        public  int     N;      //横の枚数
        Random  rand = new Random();
    
        public Card(string file, int w, int h)
        {
            try
            {   bmp= new Bitmap(file);   }
            catch
            {   MessageBox.Show("イメージが取得できません", "Error");
                return;
            }
            W= w;
            H= h;
            N = bmp.Width / w;
        }
    
        // Sprite を描画
        public void View(Graphics g, int n, int x, int y)
        {
            Rectangle des = new Rectangle(x, y, W, H);
            Rectangle sou = new Rectangle((n%N)*W,(n/N)*H,W,H);
    
            if (bmp != null)
                g.DrawImage(bmp,des,sou,GraphicsUnit.Pixel);  
        }
    
        // カードをシャッフルする
        public void Shuffle(int[] t, int n)
        {   int     i,j;
            for(i=0; i<n; i++)     t[i]= -1;
            for(i=0; i<n; i++)
            {   for(j=rand.Next(n); t[j]!=-1; j=(j+1)%n);
                t[j]= i;
            }
        }
    }
    
    class form01
    {
        public static void Main()
        {
            MyForm mf = new MyForm();
            Application.Run(mf);
        }
    }
    
  2. T[48] はカードをシャッフルする配列です。
    bas はカードを表示する左上の座標で、siz は表示する一枚あたりの幅と高さです。
    カードのサイズは 51*75 ですが、表示幅はすこし間隔を置いて 54*80 で表示します。
        int[]   T = new int[48];
        Point   bas = new Point(20,20);     //描画の左上座標
        Point   siz = new Point(54,80);     //Sprite の表示間隔
    
        App.Shuffle(T,48);                  //Shuffle() メソッドでシャッフルする
        
  3. T[48] に設定されたカードを bas, siz で指示する座標から並べて描画します。
        private void MyHandler(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            if (App.bmp == null)    Application.Exit();
            for(int i=0; i<48; i++)
                App.View(g,T[i],(i%12)*siz.X+bas.X,(i/12)*siz.Y+bas.Y);
        }
        
  4. カードをシャッフルする Shuffle() メソッドです。
        // カードをシャッフルする
        public void Shuffle(int[] t, int n)
        {   int     i,j;
            for(i=0; i<n; i++)     t[i]= -1;
            for(i=0; i<n; i++)
            {   for(j=rand.Next(n); t[j]!=-1; j=(j+1)%n);
                t[j]= i;
            }
        }
        

クリックで裏返す

  1. 神経衰弱ゲームのように、全てのカードを裏向けに表示して、マウスのクリックで裏返します。
    VT[48] はカードの表示テーブルで、最初全てのカードを裏向けに表示します。
        int[]   T = new int[48];            //シャフルテーブル
        int[]   VT = new int[48];           //カードの表示テーブル
    
            App.Shuffle(T,48);
            for(int i=0; i<48; i++) VT[i] = 48;
        
  2. マウスでクリックされたカードを裏返します。
    CardNo() はクリックされた座標からカードを特定するメソッドです。
        // クリックでカードの表を表示
        private void OnMyMouseDown(object sender, MouseEventArgs e)
        {   int num;
            num= CardNo(e.X,e.Y);
            VT[num]= T[num];
            Invalidate();
        }
        
  3. 座標からカードを特定する CardNo() メソッドです。
        // カード番号の計算
        private int CardNo(int x, int y)
        {   int wk,wy;
            wy = ((y-bas.Y)/siz.Y)*12;
            wk = (x-bas.X)/siz.X+wy;
            return wk;
        }
        

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