Java小项目实训——扑克牌

项目要求:

一个窗口实现无序发放52张扑克牌;另一个窗口实现记录打出的扑克牌


 

 Poke类


public class Poke {
	String name[] = { "fang", "hong", "mei", "hei" };
	String a[] = new String[52];
	String b[] = new String[52];
	String c[] = new String[13];
	String d[] = new String[13];
	String e[] = new String[52];

	public void 生成牌() {
		int k = 0;
		for (int i = 0; i < 4; i++) {
			for (int j = 1; j <= 13; j++) {
				a[k] = name[i] + j;
				k++;
			}
		}
	}

	public void 打印牌(String[] p) {
		int cout = 0;
		for (int i = 0; i < p.length; i++) {
			System.out.print(p[i]+"	");
			cout++;
			if (cout % 13 == 0 && cout != 0) {
				System.out.println(" ");
			}
		}
	}

	public void 打乱牌() {
		int m, n;
		String flag[]= {"0"};
		System.arraycopy(a, 0, b, 0, a.length);
		for (int i = 0; i < 100; i++) {
			m = (int) (Math.random() * 52);
			n = (int) (Math.random() * 52);	
			//生成随机数
			flag[0] = b[m];
			b[m] = b[n];
			b[n] = flag[0];
			//交换两个值
		}
	}

	public void 抽取牌(int startnum,int endnum) {
		for(int i=startnum,k=0;i<=endnum&&k<=12;i++,k++) {
			c[k]=b[i];
			//k的定义是为了覆盖原来c数组的内容,因为c数组的长度只有13
		}
	}

	public void 排序牌() {
		int flagk=0;
		for(int i=0;i<52;i++) {
			for(int j=0;j<13;j++) {
				if(a[i]==c[j]) {
					d[flagk++]=a[i];
				}	
			}
		}
	}
	
	public String[] 组合牌() {
        int flag1=0;
        int flag2=0;
        int flag3=0;
        int flag4=0;
        //因为d数组长度只有13,所以每次调用需要覆盖原来的数组
        
		抽取牌(0,12);
		排序牌();
		for(int i=0;i<=12;i++) {
			e[i]=d[flag1++];
		}
		//第一次
		
		抽取牌(13,25);
		排序牌();
		for(int i=13;i<=25;i++) {
			e[i]=d[flag2++];
		}	
		//第二次
		
		抽取牌(26,38);
		排序牌();
		for(int i=26;i<=38;i++) {
			e[i]=d[flag3++];
		}	
		//第三次
		
		抽取牌(39,51);
		排序牌();
		for(int i=39;i<=51;i++) {
			e[i]=d[flag4++];
		}
		//第四次
		return e;//返回数组
	}
	
	public static void main(String[] args) {
		Poke poke = new Poke();
		poke.生成牌();
		poke.打乱牌();
		poke.组合牌();
		poke.打印牌(poke.e);
	}
}

 PokeFrame类


import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class PokeFrame extends JInternalFrame {

    JLayeredPane jp;
    JLabel jl;
    Toolkit tk;
    JButton[] jb = new JButton[13];
    JButton cp;
    int xx, yy;
    int ps = 13;
    int ceng = 2;
    int ph, pw, px, py, zw, pxd;
    String[] s = new String[52];
    String s1;
    PlayBuffer pb1;
    int index;

    public PokeFrame(int w, int h, int k, String[] f, PlayBuffer pb) {
        ImageIcon bj;
        tk = Toolkit.getDefaultToolkit();
        bj = new ImageIcon("img/bj.jpg");
        JLabel jl = new JLabel(bj);
        jl.setSize(w, h);
        jp = this.getLayeredPane();
        jp.add(jl, new Integer(-100));
        this.添加牌(w, h, 0.8, 0.6, 0.2, k, f);
        System.arraycopy(f, 0, s, 0, f.length);
        pb1 = pb;
        index = k;//记录窗口对应的玩家
    }

    public void 添加牌(int cw, int ch, double r1, double r2, double r3, int k, String[] f) {
        //r1为13张扑克牌所占窗口比例
        //r2为扑克牌的显示部分占单个牌的比例
        //r3为扑克牌上端至窗口上端的高度占窗口的比例

        double r = 134d / 201d;
        zw = (int) (cw * r1);//扑克牌占窗口的长度
        pw = (int) (zw / (r2 * 12 + 1));//单个扑克牌的宽度
        ph = (int) (pw / r);
        px = (int) (cw * (1 - r1) / 2);
        py = (int) (ch - ph - ch * r3);
        pxd = (int) (pw * r2);
        xx = (int) (cw / 2);
        yy = (int) (ch / 2);

        监听器 jt = new 监听器();
        cp = new JButton("出牌");
        cp.setBounds(50, yy - 100, 80, 50);
        jp.add(cp, new Integer(1));
        cp.setVisible(false);
        cp.addActionListener(jt);
        for (int i = 0; i < 13; i++) {
            Image img = tk.getImage("img/" + f[k * 13 + i] + ".jpg");//从MyFrame类传入参数k
            img = img.getScaledInstance(pw, ph, Image.SCALE_SMOOTH);
            ImageIcon pkimg = new ImageIcon(img);
            jb[i] = new JButton(pkimg);
            jb[i].setBounds(px + pxd * i, py, pw, ph);
            jb[i].setName(f[k * 13 + i]);
            jp.add(jb[i], new Integer(i));
            jb[i].addActionListener(jt);
        }
    }

    class 监听器 implements ActionListener {

        JButton clickButton, selectButton = null;
        int n;
        int x, y, w, h;
        int x1, y1;

        public void actionPerformed(ActionEvent e) {

            if (e.getSource() == cp) {
                selectButton.setBounds(xx, yy - h, w, h);
                jp.add(selectButton, new Integer(ceng));
                selectButton = null;
                for (int i = n; i < ps - 1; i++) {
                    jb[i] = jb[i + 1];
                    jb[i].setBounds(px + pxd * i, py, pw, ph);
                }
                ps--;
                ceng++;
                System.out.println("index=" + index);
                pb1.reciverPlayerNum(index);//必须先传入玩家的序号即index,若与下列reciver函数调换顺序则会出现错误
                pb1.reciver(clickButton.getName());//将点击的牌传回PlayeBuffer中
                pb1.compareNum();//比较当前回合四张牌的大小
            } else {
                if (pb1.returnNum() == index) {
                    点击牌(e);
                }//当窗口玩家与轮到的玩家相对应时才能点牌
            }
        }

        public void 点击牌(ActionEvent e) {

            for (int i = 0; i < 13; i++) {
                if (e.getSource() == jb[i]) {
                    n = i;
                    clickButton = jb[i];
                    break;
                }
            }
            x = clickButton.getX();
            y = clickButton.getY();
            w = clickButton.getWidth();
            h = clickButton.getHeight();
            if (clickButton == selectButton) {
                clickButton.setBounds(x, y + 30, w, h);
                selectButton = null;
                cp.setVisible(false);
            } else {
                if (selectButton == null) {
                    clickButton.setBounds(x, y - 30, w, h);
                    selectButton = clickButton;
                    cp.setVisible(true);
                } else {
                    clickButton.setBounds(x, y - 30, w, h);
                    x1 = selectButton.getX();
                    y1 = selectButton.getY();
                    selectButton.setBounds(x1, y1 + 30, w, h);
                    selectButton = clickButton;
                    cp.setVisible(true);
                }
            }
        }
    }
}

PlayBuffer类


import javax.swing.*;
import java.awt.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PlayBuffer {

    JFrame jf1;
    JButton[][] jb = new JButton[14][4];
    int Player;
    int player1 = 1, player2 = 1, player3 = 1, player4 = 1;
    int flag = 0;
    int num[][] = new int[14][4];
    int rand = 0;
    boolean pd = false;

    public PlayBuffer() {
        jf1 = new JFrame("记录窗口");
        jf1.setExtendedState(JFrame.MAXIMIZED_BOTH);
        jf1.setLayout(new GridLayout(14, 4));
        jf1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Font f = new Font("宋体", Font.BOLD, 36);
        for (int i = 0; i < 14; i++) {
            for (int j = 0; j < 4; j++) {
                jb[i][j] = new JButton();
                jb[i][j].setFont(f);
                jf1.add(jb[i][j]);
            }
        }
        for (int j = 0; j < 4; j++) {
            jb[0][j].setText("玩家" + (j + 1));
        }
        jf1.setVisible(true);
    }

    public void reciverPlayerNum(int index) {//得到当前对应的玩家
        Player = index;
        System.out.println("Player=" + Player);
    }

    public void reciver(String s) {

        if (Player == 0) {
            jb[player1++][Player].setText(s);
            System.out.println("reciverPlayer=" + Player);
        } else if (Player == 1) {
            jb[player2++][Player].setText(s);
            System.out.println("reciverPlayer=" + Player);
        } else if (Player == 2) {
            jb[player3++][Player].setText(s);
            System.out.println("reciverPlayer=" + Player);
        } else if (Player == 3) {
            jb[player4++][Player].setText(s);
            System.out.println("reciverPlayer=" + Player);
        }
        this.PokeNum(s);
        if (Player == 3) {
            pd = true;
            System.out.println("pd=" + pd);
            rand++;
        }
        flag = (flag + 1) % 4;
    }

    public int returnNum() {
        return flag;
    }

    public int PokeNum(String poke) {//将牌中的数字提取出来
        String k;
        int x;
        String regEx = "[^0-9]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(poke);
        k = m.replaceAll("").trim();
        x = Integer.parseInt(k);
        return x;
    }

    public void compareNum() {//比较四张牌的大小
        int max = 0;
        int maxNum = 0;
        int minNum = 0;
        if (pd == true) {
            System.out.println("rand=" + rand);
            for (int i = 0; i < 4; i++) {
                System.out.print(PokeNum(jb[rand][i].getText()) + " ");
                minNum = PokeNum(jb[rand][i].getText());
                if (maxNum < minNum) {
                    maxNum = minNum;
                    max = i;
                }
            }
            jb[rand][max].setBackground(Color.PINK);
            System.out.println(" ");
        }
        pd = false;
    }
}

Mframe类

//主类
import java.awt.*;
import javax.swing.*;

public class MyFrame {

    JFrame jf;
    Toolkit tk;
    int w, h;
    int sw, sh;
    PokeFrame[] jif = new PokeFrame[4];
    String a[] = new String[52];
    String b[] = new String[13];
    PlayBuffer pb = new PlayBuffer();

    public void 得到牌() {
        Poke pk = new Poke();//同包不同类的调用
        pk.生成牌();
        pk.打乱牌();
        a = pk.组合牌();
        pk.打印牌(a);
        System.arraycopy(a, 0, b, 0, 13);
    }

    public MyFrame() {
        this.得到牌();//在主函数内调用得到牌函数,避免对象重复调用
        jf = new JFrame("扑克窗体");
        tk = Toolkit.getDefaultToolkit();
        w = tk.getScreenSize().width;
        h = tk.getScreenSize().height;
        sw = (int) (w / 2);
        sh = (int) (h / 2);
        jf.setSize(w, h);
        jf.setLayout(new GridLayout(2, 2));
        for (int i = 0; i < 4; i++) {
            jif[i] = new PokeFrame(sw, sh, i, a, pb);
            jif[i].setTitle("玩家" + (i + 1));
            jif[i].setVisible(true);
            jf.add(jif[i]);
        }

        jf.setVisible(true);
    }

    public static void main(String[] args) {
        MyFrame mf1 = new MyFrame();
    }
}

效果实现:

 

扑克牌及背景图片链接:

phttps://pan.baidu.com/s/1I7uo6T_eryZwpoDfD7XMqw

提取码:1a1a