Day_10 單例設(shè)計(jì) 撲克游戲

總說(shuō)

今天學(xué)習(xí)的內(nèi)容主要就一個(gè)——設(shè)計(jì)一個(gè)撲克游戲,
實(shí)現(xiàn)的功能有游戲顯示頁(yè)面曹仗,玩家信息頁(yè)面(包括玩家姓名 編號(hào) 所持有的資金)碉纳,生成一副撲克牌并隨機(jī)發(fā)給玩家一張溅蛉,玩家可選擇棄牌货邓,下注秆撮,跟注,具體功能可自己完善换况。

餓漢式以及懶漢式單例設(shè)計(jì)模式

  • 餓漢式
    保證一個(gè)類僅有一個(gè)實(shí)例职辨,并提供一個(gè)訪問(wèn)它的全局訪問(wèn)點(diǎn)盗蟆。
    優(yōu)點(diǎn):
    類加載時(shí)就去初始化,沒(méi)有線程安全問(wèn)題舒裤,不能通過(guò)new創(chuàng)建實(shí)例
    缺點(diǎn):
    類加載時(shí)就創(chuàng)建好對(duì)象喳资,可能會(huì)創(chuàng)建出來(lái)用不到的實(shí)例對(duì)象,這樣對(duì)內(nèi)存是種浪費(fèi)
    代碼示例
public class Text {
    public static  void main(String[] args){
        //1.正常情況下創(chuàng)建一個(gè)對(duì)象
      Poker.shared.text();
      

     
    }
}
class Poker{
    //default sharedInstance腾供,manager
    //2.定義一個(gè)靜態(tài)的成員變量 記錄這個(gè)單例對(duì)象
    //餓漢式
    public static final Poker shared = new Poker();
    //1.默認(rèn)構(gòu)造函數(shù)
    private Poker(){}
    public void text(){

    }
  • 懶漢式
    優(yōu)點(diǎn):
    不需要不占用空間仆邓,靈活性更高
    缺點(diǎn):
    安全性不強(qiáng),多線程運(yùn)行可能出現(xiàn)錯(cuò)誤
    代碼示例
 //懶漢式台腥,需要時(shí)在創(chuàng)建
    public static player getInstance() {
        //為了確保線程安全宏赘,需要加鎖
        Object b = new Object();
        synchronized (b) {
            if (shared == null) {
                shared = new player();
            }
            //提供給外部一個(gè)返回方法
            return shared;
        }
    }

封裝游戲界面

創(chuàng)建一個(gè)Utils類绒北,在里面封裝所需要的輸入語(yǔ)句黎侈。

public class Utils {
    //如果不需要保存數(shù)據(jù) 沒(méi)有成員變量
    //提供靜態(tài)方法 訪問(wèn)方便
    public static void showText(boolean hasStar,boolean lineBreak,String... contents){
        //判斷是否需要分隔符
        System.out.print(hasStar?"**********************\n":"");
        //判斷輸出的內(nèi)容是多行還是一行
        if(contents.length == 1){
            System.out.print(contents[0]);
            //有分割線的時(shí)候要進(jìn)行換行
            System.out.print(hasStar?"\n":"");
        }else {
            //輸出帶編號(hào)的多行數(shù)據(jù)
            for(int i = 0;i < contents.length; i++){
                System.out.println((i+1)+". "+contents[i]);
            }
        }
        System.out.print(hasStar?"**********************\n":"");
        //判斷是否需要換行
        System.out.print(lineBreak?"\n":"");

    }
}

創(chuàng)建Poker類

Poker類用于定義牌的點(diǎn)數(shù)和類型

public class Poker {
    private  String dot;
    private PokerType type;

    public Poker(){}
    public Poker(String dot,PokerType type){
        this.dot = dot;
        this.type = type;
    }
    //setter/getter方法
    public void setDot(String dot) {
    this.dot=dot;
    }
    public String getDot(){
        return dot;
    }
    public PokerType getType() {
        return type;
    }

    public void setType(PokerType type) {
        this.type = type;
    }
}

定義一個(gè)Constant類(常量類,用于保存常量 數(shù)字 花色闷游,人數(shù)等等常數(shù)

public class Constant {
    //用數(shù)組保存牌的點(diǎn)數(shù)
    public static final String[] DOTS = {"2","3","4","5","6","7","8","9","10","J","Q","K","A"};
    //保存固定的幾個(gè)花色
    public static final PokerType[] TYPES = {PokerType.SPADES,PokerType.HEARTS,PokerType.CLUBS,PokerType.DIAMANDS};

    //保存默認(rèn)的玩家姓名
    public static final String[] DEFAULT_NAMES = {"劉德華","周潤(rùn)發(fā)","張家輝","周星馳"};
    //默認(rèn)的資金
    public static final int MONEY = 1000;
    //每局消耗的金幣
    public  static  final  int BASE = 10;
}
}

定義PokerType類 管理理 牌的花色和id號(hào)

public class PokerType {
    public static final PokerType SPADES = new PokerType("?",4);
    public static final PokerType HEARTS = new PokerType("?",3);
    public static final PokerType CLUBS = new PokerType("?",2);
    public static final PokerType DIAMANDS = new PokerType("■",1);
    private String pic;
    private  int id;

    public PokerType(){}
    //提供一個(gè)自定義的構(gòu)造方法
    //默認(rèn)的構(gòu)造方法就被屏蔽了
    public PokerType(String pic, int id){
        this.pic = pic;
        this.id = id;
    }
    public String getPic() {
        return pic;
    }

    public void setPic(String pic) {
        this.pic = pic;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

創(chuàng)建PokerManager類來(lái)管理牌的相關(guān)操作 發(fā)牌洗牌

import java.util.ArrayList;
import java.util.Collections;

/**
 * 管理牌的相關(guān)操作
 * 生成一副牌 洗牌 發(fā)牌 牌的比較
 */
public class PokerManager {

    //保存一副牌
    private ArrayList<Poker> pokers = new ArrayList<>();
    //創(chuàng)建靜態(tài)的變量
    public static final PokerManager manager = new PokerManager();
    //私有化 構(gòu)造方法
    private PokerManager(){

    }
    //生成一副牌
    public void deal(){
        for(int i = 0; i< Constant.DOTS.length; i++){
            String dot = Constant.DOTS[i];
            //生成四種花色
            for(int j = 0;j<Constant.TYPES.length;j++){
                //創(chuàng)建一張牌
                Poker poker = new Poker(dot,Constant.TYPES[j]);
                //將這張牌保存起來(lái)
                pokers.add(poker);


            }

        }
        //洗牌
        Collections.shuffle(pokers);
    }


    //顯示一副牌(測(cè)試)
    public void show(){
        for(Poker poker: pokers){
           System.out.print(poker.getDot()+poker.getType().getPic()+" ");

        }
        System.out.println();

    }

    /**
     * 給每個(gè)玩家發(fā)牌
     * @param players 所有參與的玩家
     */
    public void dealCards(ArrayList<Player> players){
        for(int i = 0 ; i < players.size();i++){
            Player player = players.get(i);
            //將數(shù)組里面對(duì)應(yīng)的撲克牌給對(duì)應(yīng)的玩家
            player.poker = pokers.get(i);
            //
        }
}
}

接下來(lái)整理玩家信息

創(chuàng)建Player類用于管理玩家信息峻汉。

···
/**

  • 管理玩家的信息

*/
public class Player {
public String name;
public int id;
public int money;
public Poker poker;
public boolean hasDiscard;//是否棄牌

public Player(){

}
public Player(String name, int id, int money){
    this.name = name;
    this.id = id;
    this.money = money;
}

@Override
//當(dāng)打印一個(gè)對(duì)象的時(shí)候 就會(huì)默認(rèn)去調(diào)用對(duì)象的toString方法
//如果當(dāng)前類里面沒(méi)有實(shí)現(xiàn)這個(gè)方法 就到父類里面去查找
//object里面默認(rèn)實(shí)現(xiàn)就是打印對(duì)象的首地址
public String toString() {
    //一號(hào)玩家:xxx 金幣 1000

    return id+"號(hào)玩家: "+name+" 金幣"+money ;
}
public String getPokerString(){
    String pkString = "";
    if(poker != null){
        pkString = poker.getDot() +poker.getType().getPic();
    }
    return pkString;
}
//下注
public int bet(int count){
    //判斷自己的金幣是否大于下注金額
    if(money >= count){
        money-=count;
        return count;
    }else{
        return -1;
    }
}
 public void add(int count){
        money += count;
 }
}

創(chuàng)建PlayerManager管理 玩家的相關(guān)操作

import java.util.ArrayList;
import java.util.Collections;

/**
 * 管理牌的相關(guān)操作
 * 生成一副牌 洗牌 發(fā)牌 牌的比較
 */
public class PokerManager {

    //保存一副牌
    private ArrayList<Poker> pokers = new ArrayList<>();
    //創(chuàng)建靜態(tài)的變量
    public static final PokerManager manager = new PokerManager();
    //私有化 構(gòu)造方法
    private PokerManager(){

    }
    //生成一副牌
    public void deal(){
        for(int i = 0; i< Constant.DOTS.length; i++){
            String dot = Constant.DOTS[i];
            //生成四種花色
            for(int j = 0;j<Constant.TYPES.length;j++){
                //創(chuàng)建一張牌
                Poker poker = new Poker(dot,Constant.TYPES[j]);
                //將這張牌保存起來(lái)
                pokers.add(poker);


            }

        }
        //洗牌
        Collections.shuffle(pokers);
    }


    //顯示一副牌(測(cè)試)
    public void show(){
        for(Poker poker: pokers){
           System.out.print(poker.getDot()+poker.getType().getPic()+" ");

        }
        System.out.println();

    }

    /**
     * 給每個(gè)玩家發(fā)牌
     * @param players 所有參與的玩家
     */
    public void dealCards(ArrayList<Player> players){
        for(int i = 0 ; i < players.size();i++){
            Player player = players.get(i);
            //將數(shù)組里面對(duì)應(yīng)的撲克牌給對(duì)應(yīng)的玩家
            player.poker = pokers.get(i);
            //
        }
}

}

創(chuàng)建PlayerManager管理 玩家的相關(guān)操作

import java.util.ArrayList;

public class PlayerManager {
    //記錄當(dāng)前下注的玩家編號(hào)
    public int currentPlayerIndex = 0;
    //保存所有的玩家
    public  ArrayList<Player> players = new ArrayList<>();
    public static final PlayerManager manager = new PlayerManager();
    private PlayerManager(){

    }

    //初始化玩家
    public void initPlayer(int count){
        for(int i = 0; i<count; i++){
            //創(chuàng)建玩家
            String name = Constant.DEFAULT_NAMES[i];
            Player player = new Player(name,i+1,Constant.MONEY);
            //保存玩家
            players.add(player);
        }
    }
    //輸出玩家的信息
    public void show(){
        for(Player player:players){
            System.out.println(player);
        }
    }
    //底注 count 每局消耗的金幣  -1:失敗 》0成功
    public int betAll(int count){

        for(Player player: players){
            int result = player.bet(count);
            if(result == -1){
                return -1;
            }
        }
        //返回總共下注的金額
        return count * players.size();
    }

    /**
     * 獲取當(dāng)前下注的玩家
     * @return 玩家對(duì)象
     */
    public Player currentPlayer(){

      return  players.get(currentPlayerIndex);

    }

    /**
     * 當(dāng)前剩余玩家數(shù)
     * @return
     */
    public int leftPlayerCount(){
        int total = 0;
        for(int i = 0; i < players.size();i++){
            Player player = players.get(i);
            if(player.hasDiscard == false &&player.money > 0){
                total++;
            }
        }
        return total;
    }

    /**
     *
     * 查找下一個(gè)下注的人
     */
    public void changeNext(){
        int i = currentPlayerIndex;
        if(i == players.size()-1){
            i =0;
        }else{
            i++;
        }

        //查找下一個(gè)可以參與的玩家
        for(;i < players.size();i++){
            Player player = players.get(i);
            if(player.hasDiscard == false &&player.money > 0){
               currentPlayerIndex = i;
               return;
            }

        }
    }
    public void awardWinner(int total){
        Player winner;
        int available = leftPlayerCount();
        if(available == 1){
            changeNext();
            winner = currentPlayer();
        }else{
            Player w1 = null;
            Player w2 = null;
            for(int i = 0; i< players.size();i++){
                Player player = players.get(i);
                if(player.hasDiscard == false){
                    if(w1 == null){
                        w1 = player;
                    }else{
                        w2 = player;
                    }
                }
            }
            boolean result = w1.poker.bigerThan(w2.poker);
            if(result == true ){
                winner = w1;
            }else{
                winner = w2;
            }
        }
        System.out.println(winner.id+"號(hào)玩家贏得"+total+"金幣");
        winner.add(total);
    }
}

創(chuàng)建GameCenter類 管理游戲進(jìn)行的相關(guān)操作

public class GameCenter {
    //記錄這局的籌碼
    public int totalMoney;
    public void start(){
        System.out.println("游戲開(kāi)始 請(qǐng)下底注");

        //扣除底注
        PlayerManager.manager.betAll(Constant.BASE);
        PlayerManager.manager.show();
        //發(fā)牌
        System.out.println("開(kāi)始發(fā)牌");
        PokerManager.manager.dealCards(PlayerManager.manager.players);
        PlayerManager.manager.show();
        int time = 0;//如果是兩個(gè)人的次數(shù)
        boolean isFirst = true;
        int betMoney = 0;
        while(true){
            //獲取當(dāng)前玩家信息
            Player player = PlayerManager.manager.currentPlayer();
            //提示選擇操作
            System.out.println("請(qǐng)"+player.id+"號(hào)玩家選擇操作:");
           Utils.showText(true,true,new String[]{"看牌","棄牌",isFirst?"下注":"跟注"});
           int choice = Utils.getInput();
           boolean flag = false;
           switch (choice){
               case 1:
                   System.out.println(player.getPokerString());
                   flag = true;
                   break;
               case 2:
                   System.out.println(player.id+"號(hào)玩家棄牌!");
                   player.hasDiscard = true;
                   break;
               default:
                   //下注

                   if(isFirst){
                       while(true) {
                           System.out.print("請(qǐng)輸入下注金額:");
                           betMoney = Utils.getInput();
                           int result = player.bet(betMoney);
                           if (result == -1) {
                               System.out.print("余額不足 ");
                           }else{
                               isFirst = false;
                               totalMoney += betMoney;
                               break;
                           }
                       }

                   }else{
                       //跟注
                       int result = player.bet(betMoney);
                       if(result == -1){
                           player.hasDiscard = true;

                       }else{
                           System.out.println("下注成功脐往!");
                           totalMoney+=betMoney;
                       }
                   }
                   break;
           }
           if(flag == false){
               //計(jì)算多少人還可以參與
               int available = PlayerManager.manager.leftPlayerCount();
               if(available ==1){
                   break;
               }
               if(available == 2){
                   time++;
                   if(time == 4){
                       //兩個(gè)回合結(jié)束
                       break;
                   }
               }
               //切換到下一個(gè)人
               PlayerManager.manager.changeNext();
           }
        }
        PlayerManager.manager.awardWinner(totalMoney);
    }

接口類

public class Myclass {
    public static void main(String[] args){
    //歡迎界面
        Utils.showText(true,true,new String[]{"歡迎加入游戲"});


        PokerManager.manager.deal();
        //顯示一副牌
        PokerManager.manager.show();

        //輸入玩家人數(shù)
        Utils.showText(false,false,new String[]{"輸入玩家人數(shù)"});

        int count = Utils.getInput();
        //初始化玩家
       PlayerManager.manager.initPlayer(count);
        //顯示玩家信息
        PlayerManager.manager.show();

        GameCenter center = new GameCenter();
        center.start();
  }
}
```.
#總結(jié)
今天不是很懂
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末休吠,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子业簿,更是在濱河造成了極大的恐慌瘤礁,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梅尤,死亡現(xiàn)場(chǎng)離奇詭異柜思,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)巷燥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門赡盘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人缰揪,你說(shuō)我怎么就攤上這事陨享。” “怎么了钝腺?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵抛姑,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我艳狐,道長(zhǎng)途戒,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任僵驰,我火速辦了婚禮喷斋,結(jié)果婚禮上唁毒,老公的妹妹穿的比我還像新娘。我一直安慰自己星爪,他們只是感情好浆西,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著顽腾,像睡著了一般近零。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上抄肖,一...
    開(kāi)封第一講書(shū)人閱讀 51,208評(píng)論 1 299
  • 那天久信,我揣著相機(jī)與錄音,去河邊找鬼漓摩。 笑死裙士,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的管毙。 我是一名探鬼主播腿椎,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼夭咬!你這毒婦竟也來(lái)了啃炸?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤卓舵,失蹤者是張志新(化名)和其女友劉穎南用,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體掏湾,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡裹虫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了忘巧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恒界。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖砚嘴,靈堂內(nèi)的尸體忽然破棺而出十酣,到底是詐尸還是另有隱情,我是刑警寧澤际长,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布耸采,位于F島的核電站,受9級(jí)特大地震影響工育,放射性物質(zhì)發(fā)生泄漏虾宇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一如绸、第九天 我趴在偏房一處隱蔽的房頂上張望嘱朽。 院中可真熱鬧旭贬,春花似錦、人聲如沸搪泳。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)岸军。三九已至奋刽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間艰赞,已是汗流浹背佣谐。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留方妖,地道東北人狭魂。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像吁断,于是被迫代替她去往敵國(guó)和親趁蕊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子坞生,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容