import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Card implements ActionListener
{
private char ch;//用于判断输入框是否数字的判断
public boolean bs = true;//是否发完牌
private int i = 0;//当前第i张牌
private boolean []bPlayers = new boolean[54];//所有玩家线程初始为runnable状态
private boolean bSender;//控制发牌线程的状态
private int n = 0;//参与娱乐人数
private int minCard,maxCard;//发牌最小、最大数
JFrame jf = new JFrame("发牌1.0");
JPanel jpNorth = new JPanel();
JPanel jpInput = new JPanel(new GridLayout(2,3));
JLabel jlMin = new JLabel("最小牌:");
JLabel jlMax = new JLabel("最大牌:");
JLabel jlGamNum = new JLabel("玩家人数:");
JTextField jtfMin = new JTextField("1",12);
JTextField jtfMax = new JTextField("54",12);
JTextField jtfGamNum = new JTextField("3",12);
JButton jb = new JButton("发牌");
JPanel jpGambler = new JPanel();
JLabel []gams = new JLabel[54];//所有玩家接牌显示信息
JLabel curGam = new JLabel("准备发牌",JLabel.CENTER);//显示当前发牌信息
JLabel ls = new JLabel("就绪");//状态栏
public Card()
{
jtfGamNum.addActionListener(this);
jb.addActionListener(this);
jpInput.add(jlMin);jpInput.add(jlMax);jpInput.add(jlGamNum);
jpInput.add(jtfMin);jpInput.add(jtfMax);jpInput.add(jtfGamNum);
jpNorth.add(jpInput);jpNorth.add(jb);
jpGambler.add(curGam);
curGam.setForeground(Color.blue);
ls.setForeground(Color.red);
jf.getContentPane().add("North",jpNorth);
jf.getContentPane().add("Center",jpGambler);
jf.getContentPane().add("South",ls);
jf.setLocation(200,150);
jf.pack();
jf.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == jb || e.getSource() == jtfGamNum)
{
if(isDigital(jtfMin.getText()) && isDigital(jtfMax.getText()) && isDigital(jtfGamNum.getText()))
{
n = Integer.parseInt(jtfGamNum.getText());//得到当前玩家人数
minCard = Integer.parseInt(jtfMin.getText());
maxCard = Integer.parseInt(jtfMax.getText());
if(minCard <= maxCard && minCard > 0 && n > 0)
{
i = 0;//初始为没发牌
bs = true;//表示可以开始发牌
curGam.setText("发牌就绪");
JPanel jpGambler = new JPanel(new GridLayout(n + 1,1));
jpGambler.add(curGam);
for(int j = 0;j < n; j++)//初始所有玩家状态
{
gams[j] = new JLabel("玩家" + (j + 1) + ":");
jpGambler.add(gams[j]);
}
jf.getContentPane().add("Center",jpGambler);
jf.pack();
jf.setVisible(true);
for(int j = 0;j < 54; j++)//初始所有玩家线程状态为false,即Runnable状态
{
bPlayers[j] = false;
}
bSender = true;//初始发牌线程为运行状态
Distribute d = new Distribute();
Sender s = new Sender(d);
s.start();
Gambler []players = new Gambler[n];
for(int j = 0;j < n; j++)
{
players[j] = new Gambler(d);
players[j].start();
}
}
else
{
JOptionPane.showMessageDialog(jf,"请输入合法的数字");
}
}
else
{
JOptionPane.showMessageDialog(jf,"请输入合法的数字或者不能为空");
}
}
}
class Distribute //共享类
{
public synchronized void deal() throws Exception
{
if(i <= maxCard - minCard)
{
if(bSender)
{
ls.setText("发牌中...");
jb.setEnabled(false);
Thread.sleep(300);
i++;
bPlayers[(i-1) % n] = true;
bSender = false;
notify();
wait();
}
}
else
{
ls.setText("发牌完毕");
jb.setEnabled(true);
bs = false;
}
}
public synchronized void getCard() throws Exception
{
if(bPlayers[(i - 1) % n]) //表示第((i - 1) % n + 1)个玩家线程启动
{
Thread.sleep(300);
String str = gams[(i-1) % n].getText() + " ";
gams[(i-1) % n].setText(str + (i + minCard - 1));
if(i % n == 0){curGam.setText("当前接牌:" + "玩家" + n + " 当前牌:" + (i + minCard -1));}
else{curGam.setText("当前接牌:" + "玩家" + (i % n) + " 当前牌:" + (i + minCard -1));};
bPlayers[(i-1) % n] = false;
bSender = true;
notify();
wait();
}
}
}
class Sender extends Thread //生产类
{
Distribute d;
public Sender(Distribute d)
{
this.d = d;
}
public void run()
{
while(bs)
{
try
{
d.deal();
}catch(Exception e)
{
e.printStackTrace();
}
}
}
}
class Gambler extends Thread //消费类
{
Distribute d;
public Gambler(Distribute d)
{
this.d = d;
}
public void run()
{
while(bs)
{
try
{
d.getCard();
}catch(Exception e)
{
e.printStackTrace();
}
}
}
}
//判断输入框的内容是否为数字或者是否输入信息
public boolean isDigital(String s)
{
if(s.length() == 0)
{
return false;
}
for(int i = 0;i < s.length() ; i++)
{
ch = s.charAt(i);
if(!Character.isDigit(ch))
{
return false;
}
}
return true;
}
public static void main(String[] g)
{
new Card();
}
}