用swing实现简单扑克牌21点
程序员文章站
2024-02-26 17:19:43
...
效果图:
点击开始
首次双方各发两张牌
点击要牌,玩家新增一张牌,电脑通过算法,自动进行要牌
点击开牌时,加了提示框防止误点
弹框显示结果
点击重新开始,双方进行初始化
这里写的规则比较简单,只是作为一个简单实例,能力比较强的,可以尝试实现更加复杂规则。
开发工具:eclipse
需要安装插件:WindowsBuilder
这是我的包下实现类,命名有点中国化,哈哈
1、首先先把3个界面做出来,都用JFrame创建新类。
首页
开始界面
规则界面
接下来上代码
(1)创建牌类
public class Pai {
private String name;//花色名称(黑桃 红桃 黑梅花 红方块)
private String value;//牌面值(2-10 J Q K A )
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
(2)创建玩家类
public class Player {
private List<Pai> list=new ArrayList<>(); //存放牌
private int sum=0; //总点数
public List<Pai> getList() {
return list;
}
public void setList(List<Pai> list) {
this.list = list;
}
public int getSum() {
return sum;
}
public void setSum(int sum) {
this.sum = sum;
}
}
(3)创建工具类
public class Util01 {
//工具类
/**
* 生成52张牌,除去大小王
*/
public List<Pai> getPai(){
String[] name={"黑桃","红桃","黑梅花","红方块"};
String[] value={"2","3","4","5","6","7","8","9","10","A","J","Q","K"};
List<Pai> list=new ArrayList<Pai>();
for(int i=0;i<name.length;i++){
for(int j=0;j<value.length;j++){
Pai pai=new Pai();
pai.setName(name[i]);
pai.setValue(value[j]);
list.add(pai);
}
}
return list;
}
/**
* 随机生成一张牌
*/
public int getOnePai(List<Pai> list){
int num=list.size();//长度为52
Random random=new Random();
int index=random.nextInt(num);//只会随机获取0-51数字,这里数字作为集合下标
return index;
}
/**
* 首次发两张牌
*/
public void getTwoPai(List<Pai> list,Player player){
int index=getOnePai(list);
player.getList().add(list.get(index));//得到第一张牌
list.remove(index);//并且把该牌从52张牌组中删除
index=getOnePai(list);
player.getList().add(list.get(index));//得到第二张牌
list.remove(index);//并且把该牌从52张牌组中删除
}
/**
* 继续发牌(1张)
*/
public void getContinuePai(List<Pai> list,Player player){
int index=getOnePai(list);
player.getList().add(list.get(index));
list.remove(index);
}
/**
* 玩家当前牌展示
*/
public String getShowPai(Player player){
String str="";
for(Pai pai:player.getList()){
str+=pai.getName()+pai.getValue()+" ";
}
return str;
}
/**
* 计算总点数
*/
public void getSum(Player player){
List<Pai> list=player.getList();
int num=0;
int a=0;
String[] str={"J","Q","K"};
for(Pai pai:list){
boolean bool=Arrays.asList(str).contains(pai.getValue());
if(pai.getValue()=="A"){
++a;
continue;
}else if(bool){
num+=10;
}else{
num+=Integer.parseInt(pai.getValue());
}
}
if(num<=10){
if(a==1){
num+=11;
}
}else{
num+=a;
}
player.setSum(num);
}
/**
* 判断是否黑杰克
*/
public boolean isBlackJack(Player player){
boolean bool=false;
if(player.getList().size()==2){
if(player.getList().get(0).getValue()=="A"||player.getList().get(1).getValue()=="A"){
String[] str02={"A","J","Q","K","10"};
boolean bool01=Arrays.asList(str02).contains(player.getList().get(0).getValue());
boolean bool02=Arrays.asList(str02).contains(player.getList().get(1).getValue());
if(bool01&&bool02)bool=true;
}
}
return bool;
}
/**
* 开牌计算
*/
public String getWin(Player computer,Player player){
String str="";
String str02="电脑是黑杰克获胜! ";
String str03="您是黑杰克获胜! ";
if(computer.getSum()>player.getSum()&&computer.getSum()<=21){ //两边都没有爆牌情况下
if(!isBlackJack(computer)){
str02="电脑获胜!";
}
str=str02+"电脑开牌为:"+getShowPai(computer)+"总点数:"+computer.getSum();
}else if(computer.getSum()<player.getSum()&&player.getSum()<=21){
if(!isBlackJack(player)){
str03="恭喜您获胜!";
}
str=str03+"电脑开牌为:"+getShowPai(computer)+"总点数:"+computer.getSum();
}else if(computer.getSum()==player.getSum()){
if(isBlackJack(computer)&&isBlackJack(player)){
str="双方都是黑杰克平手!电脑开牌为:"+getShowPai(computer)+"总点数:"+computer.getSum();
}else if(isBlackJack(computer)&&!isBlackJack(player)){
str=str02+"电脑开牌为:"+getShowPai(computer)+"总点数:"+computer.getSum();
}else if(!isBlackJack(computer)&&isBlackJack(player)){
str=str03+"电脑开牌为:"+getShowPai(computer)+"总点数:"+computer.getSum();
}else{
str="双方平手!电脑开牌为:"+getShowPai(computer)+"总点数:"+computer.getSum();
}
}else if(computer.getSum()>21&&player.getSum()>21){
str="双方爆牌平手!电脑开牌为:"+getShowPai(computer)+"总点数:"+computer.getSum();
}else if(computer.getSum()>21&&player.getSum()<=21){ //一方爆牌,另外一方没有爆牌
if(!isBlackJack(player)){
str03="恭喜您获胜!";
}
str=str03+"电脑开牌为:"+getShowPai(computer)+"总点数:"+computer.getSum();
}else if(player.getSum()>21&&computer.getSum()<=21){
if(!isBlackJack(computer)){
str02="电脑获胜!";
}
str=str02+"电脑开牌为:"+getShowPai(computer)+"总点数:"+computer.getSum();
}
return str;
}
/**
* 重新开始
* @param textComputer 电脑文本输入框
*
*/
public List<Player> getRestart(Player computer,Player player,List<Pai> list,JTextField textComputer,JTextField textPlayer,JTextField textSum){
List<Player> listPlayer=new ArrayList<>();
player=new Player();
computer=new Player();
list=getPai();
getTwoPai(list, computer);
getSum(computer);
getTwoPai(list, player);
getSum(player);
textComputer.setText("牌1 牌2");
textPlayer.setText(getShowPai(player));
textSum.setText(String.valueOf(player.getSum()));
listPlayer.add(computer);
listPlayer.add(player);
return listPlayer;
}
}
(4)首页界面Dian21JF.java类按钮添加鼠标点击监听,功能实现如下:
public Dian21JF() {
...
this.setLocationRelativeTo(null);//设置显示居中
//开始按钮
JButton button = new JButton("\u5F00\u59CB");
button.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
BeginJF begin=new BeginJF();
begin.setVisible(true);
}
});
//规则按钮
JButton button_1 = new JButton("\u89C4\u5219");
button_1.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
RuleJF rulejf=new RuleJF();
rulejf.setVisible(true);
}
});
...
}
(5)开始界面BeginJF
public BeginJF() {
...
this.setLocationRelativeTo(null);//窗口居中显示
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);//设置关闭该窗体时,程序没有被关闭
//开始游戏
String str01="牌1 牌2";
util.getTwoPai(list, computer);//电脑开始时得到两张牌
util.getSum(computer);//计算总数
textComputer.setText(str01);
//玩家
util.getTwoPai(list, player);//玩家开始时得到两张牌
textPlayer.setText(util.getShowPai(player));
util.getSum(player);//计算总点数
textSum.setText(String.valueOf(player.getSum()));//得到总点数
//要牌
JButton button_1 = new JButton("\u8981\u724C");
button_1.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
//玩家继续发牌要求
int sum=player.getSum();
if(sum<21){
util.getContinuePai(list, player);
util.getSum(player);//计算总点数
textPlayer.setText(util.getShowPai(player));
textSum.setText(String.valueOf(player.getSum()));
}else{
JOptionPane.showMessageDialog(null, "当前总点数大于或大于21点,不能继续发牌!");
}
//电脑自动要牌规则
if(computer.getSum()<15){
util.getContinuePai(list, computer);
util.getSum(computer);;//计算总点数
textComputer.setText(str01+" "+"牌"+paiNum);
++paiNum;
}
}
});
//开牌
JButton button = new JButton("\u5F00\u724C");
button.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
int bool=JOptionPane.showConfirmDialog(null, "是否开牌");//选择是为0,否为1
if(bool==0){
String str=util.getWin(computer, player);
JOptionPane.showMessageDialog(null, str);
}
}
});
//重新开始
JButton button_2 = new JButton("\u91CD\u65B0\u5F00\u59CB");
button_2.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
List<Player> listPlayer=util.getRestart(computer, player, list,textComputer,textPlayer,textSum);
computer=listPlayer.get(0);
player=listPlayer.get(1);
paiNum=3;
}
});
...
}
(6)规则界面
public RuleJF(){
...
this.setLocationRelativeTo(null);//窗口居中显示
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);//设置关闭该窗体时,程序没有被关闭
...
}