交互にプレイする

人間とプレイヤーが交互にプレイします。

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

プログラムの作成

  1. メモ帳などでタイプして miyama.java の名前で保存して下さい。
    //★ 交互にプレイする    前田 稔
    import java.applet.*;
    import java.awt.*;
    import javax.swing.*;
    import java.io.*;
    import javax.imageio.ImageIO;
    import java.util.*;
    import java.net.URL;
    import java.awt.event.*;
    
    public class miyama extends JApplet implements MouseListener
    {   miyamacls   obj;
        // 0:初期  1:ManPlay  2:CompPlay  3:CompWin  4:CompLoss
        int         state= 0;
    
        // Initialize
        public void init()
        {   obj = new miyamacls(getDocumentBase(),"jewel.gif");
            addMouseListener(this);
            setBackground(new Color(200,200,200));
            state= 1;
        }
    
        // Paint
        public void paint(Graphics g)
        {
            Dimension  size = getSize();
            g.setColor(getBackground());
            g.fillRect(0, 0, size.width, size.height);
            obj.View(g);
        }
    
        // Mouse Click
        public void mouseClicked(MouseEvent e)
        {   int     ans;
            switch(state)
            {   case 0:
                    System.out.println("ゲームを開始します");
                    obj.SetT();
                    state= 1;
                    break;
                case 1:     // ManPlay
                    if (obj.ManPlay(e.getX(),e.getY())==false)
                        System.out.println("エラーです");
                    else
                    {   state= 2;
                        System.out.println("私の手番です");
                    }
                    break;
                case 2:     // CompPlay
                    ans= obj.Play();
                    switch(ans)
                    {   case 0:
                            state= 1;
                            System.out.println("あなたの手番です");
                            break;
                        case 1:
                            System.out.println("私の勝ちです");
                            state= 0;
                            break;
                        case 2:
                            System.out.println("私の負けです");
                            state= 0;
                            break;
                    }
            }
            repaint();
        }
    
        public void mousePressed(MouseEvent e){}
        public void mouseReleased(MouseEvent e){}
        public void mouseEntered(MouseEvent e){}
        public void mouseExited(MouseEvent e){}
    }
    
    //★ 三山くずし Object Class
    class miyamacls extends JApplet
    {   Image       Img;
        Random      Rand;
        int         T[] = new int[3];
        int         Yama,Num;
        int         i,j,x,y;
    
        // Constructor
        miyamacls(URL url, String file)
        {
            Img= null;
            try
            {   URL u = new URL(url, file);
                Img = ImageIO.read(u);
            }
            catch (IOException e)
            {   System.out.println("Image File Load Error");
            }
            Rand = new Random();        //乱数の初期化
            SetT();
        }
    
        // 山の石を描画
        public void View(Graphics g)
        {
            if (Img!=null)
            {   for(i=0; i<3; i++)
                    for(j=0; j<T[i]; j++)
                    {   x= (i*200)+j/5*60+40;
                        y= 260-(j%5)*60;
                        g.drawImage(Img,x,y,this);
                    }
            }
        }
    
        // 乱数で山に石を設定
        public void SetT()
        {   while(true)
            {   for(i=0; i<3; i++)  T[i]= Rand.nextInt(15)+1;
                if (T[0]!=T[1] && T[0]!=T[2] && T[1]!=T[2]) return;
            }
        }
    
        // Player がプレイする
        public boolean ManPlay(int xp, int yp)
        {
            if (ItemNo(xp,yp)==false)   return false;
            if (T[Yama]<=Num)   return false;
            T[Yama]= Num;
            return true;
        }
    
        // クリック位置から山,石を計算する
        public boolean ItemNo(int xp, int yp)
        {   if (xp<40 || xp>600)    return false;
            if (yp<20 || yp>300)    return false;
            Yama= (xp-40)/200;
            Num= (300-yp)/60+(((xp-40)%200)/60)*5;
            return true;
        }
    
        // コンピュータがプレイする
        public int Play()
        {   int     n1;         //石が残っている山の数
            int     n2;         //石が一個だけの山の数
            int     w;          //石が一番多い山の番号
            int     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.nextInt(3)]==0);
                n=Rand.nextInt(T[i]);
            }
            else if (n1==3 && Rand.nextInt(4)==0 && T[0]+T[1]+T[2]>4)
            {   while(T[i=Rand.nextInt(3)]<=1);
                n=Rand.nextInt(T[i]-1)+1;
            }
            T[i]= n;
            return(0);
        }
    }
    
  2. Java Applet を起動する HTMLファイル(miyama.htm)は前回と同じです。

プログラムの説明

  1. miyama.class を作成して、インターネットブラウザで miyama.htm を起動して下さい。
    state がゲームの進行を制御する領域です。
        // 0:初期  1:ManPlay  2:CompPlay  3:CompWin  4:CompLoss
        int         state= 0;
    
  2. マウスがクリックされたとき、state に従ってゲームを進行します。
    人間側の手番では obj.ManPlay() メソッドでクリックされた座標に従って石を取り除きます。
    obj.ManPlay() のリターン値が false のときはエラーです。
    コンピュータ側の手番では obj.Play() メソッドで石を取り除きます。
    obj.Play() のリターン値が 1 のときはコンピュータ側の勝ちで、2 ときはコンピュータ側の負けです。
        // Mouse Click
        public void mouseClicked(MouseEvent e)
        {   int     ans;
            switch(state)
            {   case 0:
                    System.out.println("ゲームを開始します");
                    obj.SetT();
                    state= 1;
                    break;
                case 1:     // ManPlay
                    if (obj.ManPlay(e.getX(),e.getY())==false)
                        System.out.println("エラーです");
                    else
                    {   state= 2;
                        System.out.println("私の手番です");
                    }
                    break;
                case 2:     // CompPlay
                    ans= obj.Play();
                    switch(ans)
                    {   case 0:
                            state= 1;
                            System.out.println("あなたの手番です");
                            break;
                        case 1:
                            System.out.println("私の勝ちです");
                            state= 0;
                            break;
                        case 2:
                            System.out.println("私の負けです");
                            state= 0;
                            break;
                    }
            }
            repaint();
        }
    
  3. ItemNo() がクリックされた座標から山と石を計算するメソッドです。
    Yama に山の番号を、Num に石の数を設定します。
    正しいプレイか否かは ManPlay() で調べます。
        // クリック位置から山,石を計算する
        public boolean ItemNo(int xp, int yp)
        {   if (xp<40 || xp>600)    return false;
            if (yp<20 || yp>300)    return false;
            Yama= (xp-40)/200;
            Num= (300-yp)/60+(((xp-40)%200)/60)*5;
            return true;
        }
    
  4. Play() がコンピュータがプレイするメソッドです。
    石が残っている山の数, 石が一個だけの山の数, 石が一番多い山の番号を計算します。
    三個の山が空(最後の石を人間側が取らされた)ときは、コンピュータの勝ちです。
    石が残っている山が一個で、山の石が一個(最後の石を取らされる)のときは、コンピュータの負けです。
    石が残っている山が一個で、山の石が二個以上(一個にして渡せる)ときは、コンピュータの勝ちです。
    コンピュータが強すぎると面白くないので (n1==3 && Rand.nextInt(4)==0 && T[0]+T[1]+T[2]>4) の確率で乱数で取り除きます。
        // コンピュータがプレイする
        public int Play()
        {   int     n1;         //石が残っている山の数
            int     n2;         //石が一個だけの山の数
            int     w;          //石が一番多い山の番号
            int     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.nextInt(3)]==0);
                n=Rand.nextInt(T[i]);
            }
            else if (n1==3 && Rand.nextInt(4)==0 && T[0]+T[1]+T[2]>4)
            {   while(T[i=Rand.nextInt(3)]<=1);
                n=Rand.nextInt(T[i]-1)+1;
            }
            T[i]= n;
            return(0);
        }
    

[Next Chapter ↓] α版の完成です
[Previous Chapter ↑] 乱数で石を設定する

Java Game Program