用swing實現簡單撲克牌21點
阿新 • • 發佈:2018-12-09
效果圖:
點選開始
首次雙方各發兩張牌
點選要牌,玩家新增一張牌,電腦通過演算法,自動進行要牌
點選開牌時,加了提示框防止誤點
彈框顯示結果
點選重新開始,雙方進行初始化
這裡寫的規則比較簡單,只是作為一個簡單例項,能力比較強的,可以嘗試實現更加複雜規則。
開發工具: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);//設定關閉該窗體時,程式沒有被關閉
...
}