CARD をシャッフルして描画

CARD Class に Shuffle() メソッドを追加します。

前田稔の超初心者のプログラム入門

プログラムの作成

  1. ゲームプログラムは今まで説明したことの集大成です。欲張らずに基礎から学んで下さい。
    前回までの説明は CARD Class で画像を切り分ける を参照して下さい。
  2. メモ帳などでタイプして Card_02.java の名前で保存して下さい。
    //★ CARD シャッフルする    前田 稔
    import java.awt.*;
    import javax.swing.*;
    import java.io.*;
    import javax.imageio.ImageIO;
    import java.util.*;
    
    class Card_02 extends JFrame
    {   CARD    card;
        int     T[] = new int[48];  //シャッフルの配列
    
        // Main
        public static void main(String args[])
        {   new Card_02();
        }
    
        // Constructor
        public Card_02()
        {   super("Image View");
            card = new CARD("c:\\data\\test\\hanafuda.gif",51,75);
            card.Shuffle(T,48);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setSize(720,400);
            setVisible(true);
        }
    
        // Paint Method
        public void paint(Graphics g)
        {   super.paint(g);
            for(int i=0; i<48; i++)
                card.view(g,T[i],(i%12)*56+20,(i/12)*80+46);
        }
    }
    
    class CARD extends JFrame 
    {   private Image   Img;
        private int Height,Width,Hnum,Wnum;
        int     frameNum;
        Random  rand;
    
        // Constructor
        CARD(String filename, int ws, int hs)
        {   Width= ws;
            Height= hs;
            Wnum=Hnum= 1;
            //画像ロード
            File infile = new File(filename);
            Img = loadImage(infile);
            Wnum= Img.getWidth(null)/Width;
            Hnum= Img.getHeight(null)/Height;
            frameNum = Wnum*Hnum;
            if (Wnum<1 || Hnum<1)
                System.out.println("Image File Error" + filename);
            rand = new Random();    //乱数の初期化
        }
    
        // Sprite View
        public void view(Graphics g, int n, int dx, int dy)
        {   int sx, sy;
            if (n >= frameNum)
            {   System.out.println("Sprite Number Error" + n);
                return;
            }
            sx = (n % Wnum) * Width;
            sy = (n / Wnum) * Height;
            if (Img != null)
            {   g.drawImage(Img,dx,dy,dx+Width,dy+Height,sx,sy,sx+Width,sy+Height,this);
            }
        }
    
        // Load Image
        public static Image loadImage(File f)
        {   try
            {   Image img = ImageIO.read(f);
                return img;
            }
            catch (IOException e)
            {   throw new RuntimeException(e);
            }
        }
    
        // n 枚のカードをシャッフルする
        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.nextInt(n); t[j]!=-1; j=(j+1)%n);
                t[j]= i;
            }
        }
    }
    
  3. 画像ファイル("c:\\data\\test\\hanafuda.gif")をパスで指定したフォルダーに格納して下さい。
    hanafuda.gif は「横=51ドット,縦=75ドット」の花札が5段10列に並んだ画像です。

プログラムの説明

  1. T[] = new int[48] がシャッフルする領域です。
    配列の基礎は 配列を割り当てる を参照して下さい。
    card.Shuffle(T,48) でカードをシャッフルするメソッドを呼び出します。
    48 はカードの枚数(配列のサイズ)です。
        int     T[] = new int[48];  //シャッフルの配列
    
        // Constructor
        public Card_02()
        {   ・・・
            card = new CARD("c:\\data\\test\\hanafuda.gif",51,75);
            card.Shuffle(T,48);
            ・・・
        }
        
  2. 花札を描画する paint() メソッドでは T[] に格納されている順にカードを表示します。
    T[i] がカードの番号で (i%12)*56+20 がX座標で (i/12)*80+46 がY座標です。
        // Paint Method
        public void paint(Graphics g)
        {   super.paint(g);
            for(int i=0; i<48; i++)
                card.view(g,T[i],(i%12)*56+20,(i/12)*80+46);
        }
        

CARD Class の説明

  1. CARD Class で乱数を使うので java.util.* をインポートします。
    Constructor で乱数をインスタンス化します。
    乱数は 乱数の説明 を参照して下さい。
        import java.util.*;
    
        // Constructor
        CARD(String filename, int ws, int hs)
        {   ・・・
            rand = new Random();    // 乱数の初期化
        }
        
  2. カードをシャッフルするメソッドです。
    配列 t[n] に 0〜n-1 の値をランダムに格納します。
    シャッフルでは、同じ値が二度以上現れてはいけません。
    どのようなテクニックでシャッフルしているか、ロジックを解析して下さい。
        // n 枚のカードをシャッフルする
        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.nextInt(n); t[j]!=-1; j=(j+1)%n);
                t[j]= i;
            }
        }
        

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