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