目的
學(xué)習(xí)和了解單例設(shè)計(jì)模式票编,明白其作用和使用方法,完善Java知識(shí)基礎(chǔ)學(xué)習(xí)卵渴;深入理解數(shù)組知識(shí)慧域,學(xué)好Java基礎(chǔ)知識(shí)中最重要的一部分;經(jīng)過(guò)四天對(duì)Java基礎(chǔ)的學(xué)習(xí)浪读,已經(jīng)對(duì)Java語(yǔ)言有一定了解昔榴,今天便做一個(gè)最基本的撲克牌demo,來(lái)將各類知識(shí)串聯(lián)起來(lái)
單例設(shè)計(jì)模式
概念
java中單例模式是一種常見(jiàn)的設(shè)計(jì)模式碘橘,單例模式分三種:懶漢式單例互订、餓漢式單例、登記式單例三種痘拆;單例模式有以下特點(diǎn): 1仰禽、單例類只能有一個(gè)實(shí)例; 2、單例類必須自己自己創(chuàng)建自己的唯一實(shí)例吐葵;3规揪、單例類必須給所有其他對(duì)象提供這一實(shí)例;
單例模式確保某個(gè)類只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例;在計(jì)算機(jī)系統(tǒng)中温峭,線程池猛铅、緩存、日志對(duì)象凤藏、對(duì)話框奸忽、打印機(jī)、顯卡的驅(qū)動(dòng)程序?qū)ο蟪1辉O(shè)計(jì)成單例;這些應(yīng)用都或多或少具有資源管理器的功能;每臺(tái)計(jì)算機(jī)可以有若干個(gè)打印機(jī)揖庄,但只能有一個(gè)Printer Spooler栗菜,以避免兩個(gè)打印作業(yè)同時(shí)輸出到打印機(jī)中;每臺(tái)計(jì)算機(jī)可以有若干通信端口,系統(tǒng)應(yīng)當(dāng)集中管理這些通信端口抠艾,以避免一個(gè)通信端口同時(shí)被兩個(gè)請(qǐng)求同時(shí)調(diào)用;總之苛萎,選擇單例模式就是為了避免不一致?tīng)顟B(tài),避免政出多頭
關(guān)鍵詞
1.整個(gè)程序都操作同一個(gè)對(duì)象
2.不允許用戶創(chuàng)建這個(gè)類的一個(gè)對(duì)象检号,而將類的構(gòu)造方法私有化
3.在自己的類里面提供創(chuàng)建對(duì)象的方法
兩種形式
餓漢式
class Poker{
//default sharedInstance manager
//2.定義一個(gè)靜態(tài)的成員變量 記錄這個(gè)單例對(duì)象
//餓漢式
public static final Poker sharedInstance = new Poker();
//1.默認(rèn)構(gòu)造函數(shù)
private Poker(){
}
public void test(){
}
}
懶漢式
class Player{
public int count;
//2.創(chuàng)建靜態(tài)變量
private static Player shared = null;
//1.私有化構(gòu)造方法
private Player(){}
//3.提供給外部一個(gè)訪問(wèn)的方法
//懶漢式
public static Player getInstance(){
Object b = new Object();
synchronized (b) {
if (shared == null) {
//如果沒(méi)有創(chuàng)建 那么就創(chuàng)建一個(gè)
shared = new Player();
}
}
return shared;
}
}
數(shù)組
Java數(shù)組里面保存的都是對(duì)象的引用(指針)腌歉;改變數(shù)組里面對(duì)象的屬性變量,原始對(duì)象的值也跟著改變齐苛,因?yàn)榇蠹叶际峭粋€(gè)內(nèi)存空間
class Test2{
public static void main(String[] args){
//泛型
ArrayList<Person> people = new ArrayList<>();
//獲取數(shù)組元素個(gè)數(shù)
people.size();
//添加數(shù)據(jù)
Person xw = new Person();
people.add(xw);
Person zs = new Person();
people.add(zs);
//訪問(wèn)數(shù)據(jù)
Person xw2 = people.get(0);
xw2.name = "小王";
System.out.println(xw2.name);
System.out.println(xw.name);
}
}
class Person{
public String name;
}
情況演示
撲克牌游戲
設(shè)計(jì)游戲大致思路
封裝輸出語(yǔ)句
創(chuàng)建一個(gè)Untils類翘盖,專門封裝輸出語(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) {
//有分隔線的時(shí)候需要換行
System.out.print(contents[0] + (hasStar ? "\n" : ""));
} else {
//輸出帶編號(hào)的多行數(shù)據(jù)
//1. 棄牌
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" : "");
}
}
調(diào)用這個(gè)類創(chuàng)建歡迎界面
public class MyClass {
public static void main(String[] args){
//歡迎界面
Utils.showText(true,true,new String[]{"歡迎使用撲克游戲"});
}
}
創(chuàng)建Poker
創(chuàng)建Constant類,管理常量
下面代碼為已完成狀態(tài)
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.DIAMONDS};
//保存默認(rèn)的玩家姓名
public static final String[] DEFAULT_NAMES = {"劉德華","周潤(rùn)發(fā)","張家輝","周星馳"};
//設(shè)置默認(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 DIAMONDS = 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)對(duì)象
public static final PokerManager manager = new PokerManager();
//私有化過(guò)程方法
private PokerManager(){}
//定義一個(gè)方法 生成一副牌
public void deal(){
//遍歷整個(gè)點(diǎn)數(shù)的數(shù)組
for (int i = 0; i < Constant.dots.length; i++){
//獲取相應(yīng)的點(diǎn)數(shù)
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);
}
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)建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(){
//1號(hào)玩家:劉德華 金幣1000
return id+"號(hào)玩家:"+name+" 金幣"+money+" "+getPokerString();
}
public String getPokerString(){
String pkString = "";
if (poker != null){
pkString = poker.getDot() + poker.getType().getPic();
}
return pkString;
}
/**
* 下底注&下注
* @param count 下注金額
* @return -1:失敗 >0: 成功
*/
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;
public class PlayManager {
//記錄當(dāng)前下注的玩家編號(hào)
public int currentPlayerIndex = 0;
//保存所有的玩家
public ArrayList<Player> players = new ArrayList<>();
public static final PlayManager manager = new PlayManager();
private PlayManager(){}
//初始化玩家
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 shows(){
for (Player player:players){
System.out.println(player);
}
}
/**
* 全場(chǎng)下底注
* @param count 每局消耗的金幣
* @return -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 == true && 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 == true && player.money > 0){
currentPlayerIndex = i;
return;
}
}
}
/**
* 獎(jiǎng)勵(lì)贏家
*/
public void awardWinner(int total){
Player winner ;
int available = leftPlayerCount();
if (available == 1){
//只有一個(gè)玩家 即為贏家
changeNext();
winner = currentPlayer();
}else{
//需要比較這兩個(gè)玩家的牌
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.bigerThen(w2.poker);
if (result){
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 {
//記錄這局的籌碼
private int totalMoney;
//開(kāi)始游戲
public void start(){
System.out.println("游戲開(kāi)始 請(qǐng)下底注");
PlayManager manager = PlayManager.manager;
//扣除底注
manager.betAll(Constant.BASE);
manager.shows();
//發(fā)牌
System.out.println("開(kāi)始發(fā)牌");
PokerManager.manager.dealCards(manager.players);
manager.shows();
int time = 0;//記錄如果是兩個(gè)人的次數(shù)
boolean isFirst = true;
int betMoney = 0;
while (true){
//獲取當(dāng)前玩家信息
Player player = 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.println("余額不足 ");
}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ì)算當(dāng)前還有多少人可以參與
int available = manager.leftPlayerCount();
if (available > 1){
//本劇結(jié)束
manager.changeNext();
Player winner = manager.currentPlayer();
System.out.println(player.id+"號(hào)玩家獲得勝利 獲得金幣:"+totalMoney);
break;
}
if (available == 2){
time++;
if (time == 4){
//兩個(gè)回合結(jié)束 結(jié)束游戲
break;
}
}
//切換到下一個(gè)人
manager.changeNext();
}
}
}
整體邏輯
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[]{"請(qǐng)輸入玩家人數(shù):"});
int count = Utils.getInput();
//初始化玩家
PlayManager.manager.initPlayer(count);
//顯示玩家信息
//PlayManager.manager.shows();
//開(kāi)始游戲
GameCenter center = new GameCenter();
center.start();
}
}
心得體會(huì)
今天是正式地學(xué)習(xí)第一個(gè)完整的demo凹蜂,其中還有很多不懂的馍驯,需要不斷看視頻和學(xué)習(xí),才能將她摸透