java自定义类怎么比大小_实战:Java 扑克牌比较游戏
一.目的
通過(guò)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的撲克牌比大小的游戲,體會(huì)面向?qū)ο缶幊痰乃枷搿?/p>
二.技術(shù)
1.常量類(lèi)
2.類(lèi)的創(chuàng)建,封裝
3.單例模式
4.自定義異常類(lèi)
三.如何使用
1.常量類(lèi)
對(duì)于程序運(yùn)行過(guò)程中,一直不變的數(shù)據(jù),我們將它們統(tǒng)一保存在一個(gè)類(lèi)中,這個(gè)類(lèi)的名字通常是Constants,常量數(shù)據(jù)要用public static final修飾。
例如:
public class Constants {
//所有點(diǎn)數(shù)
public static final String[] DOTS = {"2","3","4","5","6","7","8","9","10","J","Q","K","A"};
//所有的花色
public static final String[] COLORS = {"?","?","?","?"};
//默認(rèn)的玩家姓名數(shù)組
public static final String[] DEFAULT_NAMES ={"周潤(rùn)發(fā)","渣渣輝","陳小春","甄子丹"};
//玩家默認(rèn)的持有金幣
public static final int DEFAULT_MONEY = 1000;
//玩家金幣不足
public static final int NOT_ENOUGH = -1;
//玩家金幣足夠
public static final int ENOUGH = 1;
//底注金額
public static final int BASE_WAGER = 100;
}
很明撲克牌的花色和點(diǎn)數(shù)是一直不變的,類(lèi)似這樣的數(shù)據(jù)我們就要寫(xiě)入常量類(lèi)中,注意常量變量的名字一般大寫(xiě)。
2.類(lèi)的創(chuàng)建,封裝
明確這個(gè)任務(wù)中需要哪些類(lèi),這些類(lèi)有什么功能
對(duì)于一個(gè)撲克牌游戲,我們需要玩家類(lèi)Player來(lái)抽象玩家,需要撲克牌類(lèi)Poker來(lái)抽象撲克牌,一系列玩家的行為需要一個(gè)類(lèi)來(lái)管理所以誕生了我們的玩家管理類(lèi)PlayerManager,同理管理我們的撲克牌也需要一個(gè)管理類(lèi)PokerManager。一局游戲需要一個(gè)類(lèi)來(lái)管理賭注,到那個(gè)玩家選擇,所以誕生了我們的中心類(lèi)Center
Poker類(lèi):有自己的點(diǎn)數(shù)和花色,重寫(xiě)String toString()是為了方便打印
public class Poker {
public String dot;
public String color;
public Poker(){}
public Poker(String dot,String color){
this.dot = dot;
this.color = color;
}
@Override
public String toString() {
return "Poker[" +
"'" + dot + '\'' +
"'" + color + '\'' +
']';
}
}
PokerManager類(lèi),首先需要一個(gè)變量保存一副牌,接著要產(chǎn)生一副洗好的牌,展示牌,給每個(gè)人發(fā)牌。
/**
* 管理牌的相關(guān)操作
*/
public class PokerManager {
//單例模式
private PokerManager() {}
public static final PokerManager PokerDefault = new PokerManager();
//成員變量:保存一副牌
public static ArrayList pokers = new ArrayList<>();
/**
* 展示一副牌
*/
public void showPokers(){
for (Poker poker : pokers) {
System.out.print(poker+" ");
}
System.out.println("");
}
/**
* 洗牌
*/
public void shufflePokers(){
//生成一副牌
for (int i = 0; i < Constants.DOTS.length; i++) {
for (int j = 0; j < Constants.COLORS.length; j++) {
Poker poker = new Poker(Constants.DOTS[i],Constants.COLORS[j]);
pokers.add(poker);
}
}
//洗牌
Collections.shuffle(pokers);
}
/**
* 發(fā)牌
*/
public void dealPokerToPlayers(){
for (int i = 0; i < PlayerManager.PlayerDefault.players.size(); i++) {
PlayerManager.PlayerDefault.players.get(i).poker = pokers.get(i);
}
}
}
3.單例模式
惡漢式創(chuàng)建:私有化構(gòu)造方法,利用構(gòu)造方法創(chuàng)建一個(gè)不可變的靜態(tài)常量。
使用單利模式的目的是為了共享數(shù)據(jù)
在這里PokerManager類(lèi)就需要使用單例模式,我們需要用它來(lái)創(chuàng)建一副牌,一副牌在一局游戲中肯定只有一個(gè)。難道現(xiàn)實(shí)中玩牌是先這副牌發(fā)牌后另一副牌發(fā)牌?
/**
* 管理牌的相關(guān)操作
*/
public class PokerManager {
//單例模式
private PokerManager() {}
public static final PokerManager PokerDefault = new PokerManager();
}
4.自定義異常類(lèi)
兩步走:自定義一個(gè)類(lèi)繼承Throwable類(lèi);創(chuàng)建構(gòu)造方法,我建議創(chuàng)建有參的構(gòu)造方法,便于傳遞異常信息。
比如我們這里初始化玩家數(shù)量最多只能初始化4個(gè);如果超過(guò)四個(gè),那么我們就在對(duì)應(yīng)位置拋出一個(gè)異常。
public class XLWrongInputEXception extends Throwable {
public XLWrongInputEXception(String desc){
super(desc);
}
}
四.具體使用
工程結(jié)構(gòu)圖
PlayerManager類(lèi)
package swu.xl.day4.MyPractise.Manager;
import java.util.ArrayList;
import java.util.Arrays;
import swu.xl.day4.MyPractise.Constants;
import swu.xl.day4.MyPractise.Model.Player;
import swu.xl.day4.MyPractise.Status;
/**
* 管理人的相關(guān)操作
*/
public class PlayerManager {
//單例模式
private PlayerManager(){}
public static final PlayerManager PlayerDefault = new PlayerManager();
//成員變量:保存玩家
public ArrayList players = new ArrayList<>();
/**
* 展示所有玩家信息
*/
public void showPlayers(){
for (Player player : players) {
System.out.print(player+" ");
}
System.out.println("");
}
/**
* 初始化游戲玩家
* @param count 玩家的人數(shù)
*/
public void initPlayers(int count){
for (int i = 0; i < count; i++) {
Player player = new Player(Constants.DEFAULT_NAMES[i],Constants.DEFAULT_MONEY);
player.id = i+1;
player.status = Status.StatusIn;
players.add(player);
}
}
/**
* 所有游戲玩家下底注
* @return 下的底注金額
*/
public int betWagerOfPlayers(){
for (Player player : players) {
player.bet(Constants.BASE_WAGER);
}
return players.size()*Constants.BASE_WAGER;
}
/**
* 當(dāng)前玩家
* @param index 當(dāng)前玩家的索引值
* @return
*/
public Player getPlayerOfIndex(int index){
return players.get(index);
}
/**
* 比較兩個(gè)玩家的撲克牌
* @param p1 玩家1
* @param p2 玩家2
* @return 撲克牌牌面大的玩家
*/
public Player compareTwoPlayer(Player p1,Player p2){
//比較點(diǎn)數(shù)大小
int index1 = Arrays.binarySearch(Constants.DOTS,p1.poker.dot);
int index2 = Arrays.binarySearch(Constants.DOTS,p2.poker.dot);
if (index1 != index2){
//點(diǎn)數(shù)不同
if (index1 > index2){
return p1;
}else {
return p2;
}
}else {
//點(diǎn)數(shù)相同
index1 = Arrays.binarySearch(Constants.COLORS,p1.poker.color);
index2 = Arrays.binarySearch(Constants.COLORS,p2.poker.color);
if (index1 > index2){
return p1;
}else {
return p2;
}
}
}
}
PokerManager類(lèi)
package swu.xl.day4.MyPractise.Manager;
import java.util.ArrayList;
import java.util.Collections;
import swu.xl.day4.MyPractise.Constants;
import swu.xl.day4.MyPractise.Model.Poker;
/**
* 管理牌的相關(guān)操作
*/
public class PokerManager {
//單例模式
private PokerManager() {}
public static final PokerManager PokerDefault = new PokerManager();
//成員變量:保存一副牌
public static ArrayList pokers = new ArrayList<>();
/**
* 展示一副牌
*/
public void showPokers(){
for (Poker poker : pokers) {
System.out.print(poker+" ");
}
System.out.println("");
}
/**
* 洗牌
*/
public void shufflePokers(){
//生成一副牌
for (int i = 0; i < Constants.DOTS.length; i++) {
for (int j = 0; j < Constants.COLORS.length; j++) {
Poker poker = new Poker(Constants.DOTS[i],Constants.COLORS[j]);
pokers.add(poker);
}
}
//洗牌
Collections.shuffle(pokers);
}
/**
* 發(fā)牌
*/
public void dealPokerToPlayers(){
for (int i = 0; i < PlayerManager.PlayerDefault.players.size(); i++) {
PlayerManager.PlayerDefault.players.get(i).poker = pokers.get(i);
}
}
}
Playerr類(lèi)
package swu.xl.day4.MyPractise.Model;
import swu.xl.day4.MyPractise.Constants;
import swu.xl.day4.MyPractise.Status;
public class Player {
public String name;
public int money;
public int id;
public Poker poker;
public Status status;
public Player(){}
public Player(String name,int money){
this.name = name;
this.money = money;
}
@Override
public String toString() {
return id+"號(hào):'" + name + '\'' +
":" + money + " " + poker;
}
/**
* 玩家下注
* @param betMoney 下注金額
* @return ENOUGH 金額足夠 NOT_ENOUGH金額不足
*/
public int bet(int betMoney){
if (money >= betMoney){
money -= betMoney;
return Constants.ENOUGH;
}
return Constants.NOT_ENOUGH;
}
}
Poker類(lèi)
package swu.xl.day4.MyPractise.Model;
public class Poker {
public String dot;
public String color;
public Poker(){}
public Poker(String dot,String color){
this.dot = dot;
this.color = color;
}
@Override
public String toString() {
return "Poker[" +
"'" + dot + '\'' +
"'" + color + '\'' +
']';
}
}
Center類(lèi)
package swu.xl.day4.MyPractise;
import swu.xl.day4.MyPractise.Manager.PlayerManager;
import swu.xl.day4.MyPractise.Manager.PokerManager;
import swu.xl.day4.MyPractise.Model.Player;
/**
* 管理游戲
*/
public class Center {
//成員變量:記錄下注的總金額
public int wager;
//成員變量:記錄當(dāng)前玩家
int currentPlayerIndex;
//開(kāi)始游戲
public void start(){
//玩家下底注
Utils.log(false,true,new String[]{"游戲中心---玩家開(kāi)始下底注"+Constants.BASE_WAGER+":"});
int temp = PlayerManager.PlayerDefault.betWagerOfPlayers();
wager += temp;
PlayerManager.PlayerDefault.showPlayers();
//開(kāi)始發(fā)牌
Utils.log(false,true,new String[]{"游戲中心---開(kāi)始發(fā)牌:"});
PokerManager.PokerDefault.dealPokerToPlayers();
PlayerManager.PlayerDefault.showPlayers();
//第一個(gè)玩家
currentPlayerIndex = 0;
//是否有人下注
boolean hasPlayerBet = false;
//只有兩個(gè)人,還允許各下注一次
int betTime = 0;
//臨時(shí)的下注金額
int tempWager = 0;
//各個(gè)玩家做出選擇
while (true) {
System.out.println("");
//獲得當(dāng)前玩家
Player tempPlayer = PlayerManager.PlayerDefault.getPlayerOfIndex(currentPlayerIndex);
//判斷是否需要切換到下一個(gè)
boolean needChangeNext = true;
//提示信息
Utils.log(false,true,new String[]{"游戲中心---請(qǐng)"+tempPlayer+"玩家選擇操作"});
//提示哪一位玩家做出選擇
Utils.log(true,false,new String[]{"看牌","棄牌",hasPlayerBet?"跟注":"下注"});
int count = Utils.getInput();
try {
if (count > 3){
throw new XLWrongInputEXception("異常:超出選擇范圍");
}
}catch (XLWrongInputEXception e){
System.out.println(e.getMessage());
System.exit(1);
}
//具體的選擇操作
switch (count) {
case 1:
//看牌
Utils.log(false,true,new String[]{"你的撲克牌是:"+tempPlayer.poker});
//不需要比較人數(shù)
needChangeNext = false;
break;
case 2:
//棄牌
Utils.log(false,true,new String[]{"游戲中心---"+tempPlayer+"選擇棄牌"});
tempPlayer.status = Status.StatusOut;
break;
case 3:
//下注
Utils.log(false,false,new String[]{"游戲中心---請(qǐng)輸入"+(hasPlayerBet?"跟注":"下注")+"的金額:"});
//判斷下注是否成功
while (true) {
//下注金額
tempWager = Utils.getInput();
//判斷是否下注成功
if (tempPlayer.bet(tempWager) == Constants.NOT_ENOUGH){
//不成功
Utils.log(false,false,new String[]{"游戲中心---賭注不足,請(qǐng)重新輸入"+(hasPlayerBet?"跟注":"下注")+"的金額:"});
}else {
//成功
//增加賭盤(pán)上的賭注
wager += tempWager;
//輸出信息
Utils.log(false,true,new String[]{tempPlayer.id+"號(hào)玩家"+(hasPlayerBet?"跟注":"下注")+tempWager+"成功"});
//切換為已經(jīng)有人下注
hasPlayerBet = true;
break;
}
}
break;
default:
break;
}
//根據(jù)玩家數(shù)量做出決定
if (needChangeNext) {
//臨時(shí)變量保存當(dāng)前的玩家數(shù)量
int remainingCount = getCountOfRemainingPlayers();
//如果只有一個(gè)人
if (remainingCount == 1){
//取得結(jié)果
//這種情況必定是兩個(gè)人了,其中一個(gè)人做出了棄牌的選擇
//此時(shí)指引玩家的索引還停留在該棄牌玩家上
//切換到下一個(gè)人
changePlayerToNext();
//得到勝利者
Player winner = PlayerManager.PlayerDefault.getPlayerOfIndex(currentPlayerIndex);
winner.money += wager;
//輸出勝利者
Utils.log(false,true,new String[]{"游戲中心---"+winner.id+"號(hào)玩家贏得勝利,贏得金額"+wager});
break;
}
//如果只有兩個(gè)人
if (remainingCount == 2){
betTime++;
if (betTime > 2){
//0 有人做出棄牌決定
//1 2
//只有兩個(gè)人的時(shí)候,只可以再互相下注一次
//之后比較結(jié)果
//提示信息
System.out.println("");
Utils.log(false,true,new String[]{"游戲中心---下注次數(shù)用盡 進(jìn)行比較"});
//進(jìn)行比較
Player winner = getWinner();
winner.money += wager;
//輸出勝利者
Utils.log(false,true,new String[]{"游戲中心---"+winner.id+"號(hào)玩家贏得勝利,贏得金額"+wager});
break;
}
}
//切換到下一個(gè)
changePlayerToNext();
}
}
//跳出循環(huán)后結(jié)束游戲
//PlayerManager.PlayerDefault.showPlayers();
}
/**
* 獲得目前還在游戲的玩家數(shù)量
* @return 玩家數(shù)量
*/
public int getCountOfRemainingPlayers(){
int sum = 0;
for (Player player : PlayerManager.PlayerDefault.players) {
if (player.status == Status.StatusIn) {
sum++;
}
}
return sum;
}
/**
*找到下一個(gè)玩家
*/
public void changePlayerToNext(){
//獲得玩家數(shù)量
int size = PlayerManager.PlayerDefault.players.size();
//找到下一個(gè)玩家
//從下一個(gè)玩家開(kāi)始currentPlayerIndex+1
for (int i = (currentPlayerIndex+1) % size; ; i++) {
Player player = PlayerManager.PlayerDefault.getPlayerOfIndex(i);
if (player.status == Status.StatusIn){
currentPlayerIndex = i % size;
return;
}
}
}
/**
* 比較最后剩余的兩個(gè)玩家的撲克牌大小
* @return 最后勝利的玩家
*/
public Player getWinner(){
//得到兩個(gè)玩家
Player p1 = null;
Player p2 = null;
for (Player player : PlayerManager.PlayerDefault.players) {
if (player.status == Status.StatusIn){
if (p1 ==null){
p1 = player;
}else {
p2 = player;
}
}
}
return PlayerManager.PlayerDefault.compareTwoPlayer(p1,p2);
}
}
Constants類(lèi)
package swu.xl.day4.MyPractise;
public class Constants {
//所有點(diǎn)數(shù)
public static final String[] DOTS = {"2","3","4","5","6","7","8","9","10","J","Q","K","A"};
//所有的花色
public static final String[] COLORS = {"?","?","?","?"};
//默認(rèn)的玩家姓名數(shù)組
public static final String[] DEFAULT_NAMES ={"周潤(rùn)發(fā)","渣渣輝","陳小春","甄子丹"};
//玩家默認(rèn)的持有金幣
public static final int DEFAULT_MONEY = 1000;
//玩家金幣不足
public static final int NOT_ENOUGH = -1;
//玩家金幣足夠
public static final int ENOUGH = 1;
//底注金額
public static final int BASE_WAGER = 100;
}
Main類(lèi)
package swu.xl.day4.MyPractise;
import swu.xl.day4.MyPractise.Manager.PlayerManager;
import swu.xl.day4.MyPractise.Manager.PokerManager;
public class Main {
public static void main(String[] args){
//歡迎
Utils.log(false,true,new String[]{"游戲中心---歡迎來(lái)到撲克游戲"});
//洗牌
Utils.log(false,true,new String[]{"游戲中心---撲克牌已經(jīng)洗好:"});
PokerManager.PokerDefault.shufflePokers();
PokerManager.PokerDefault.showPokers();
//提示輸入玩家
Utils.log(false,false,new String[]{"游戲中心---請(qǐng)輸入玩家人數(shù):"});
//生成玩家
int count = Utils.getInput();
try {
if (count > Constants.DEFAULT_NAMES.length){
throw new XLWrongInputEXception("異常:系統(tǒng)最多加載4個(gè)玩家");
}
} catch (XLWrongInputEXception e) {
System.out.println(e.getMessage());
System.exit(1);
}
PlayerManager.PlayerDefault.initPlayers(count);
PlayerManager.PlayerDefault.showPlayers();
//開(kāi)始游戲
Center center = new Center();
center.start();
}
}
Status類(lèi)
package swu.xl.day4.MyPractise;
public enum Status {
StatusIn, //玩家未棄牌
StatusOut //玩家棄牌
}
Utils類(lèi)
package swu.xl.day4.MyPractise;
import java.util.Scanner;
public class Utils {
/**
* 打印內(nèi)容
* @param separator 要不要***
* @param lineBreak 要不要換行
* @param content 輸出的文本內(nèi)容
*/
public static void log(boolean separator,boolean lineBreak,String...content){
//判斷是否需要分割線
System.out.print(separator?"**************\n":"");
//判斷輸出的內(nèi)容是單行還是多行
if (content.length == 1) {
System.out.print(content[0]+(separator?"\n":""));
}else {
//輸出帶編號(hào)的多行數(shù)據(jù)
for (int i = 0; i < content.length; i++) {
System.out.println((i+1)+". "+content[i]);
}
}
//判斷是否需要分割線
System.out.print(separator?"**************\n":"");
//判斷是或需要換行
System.out.print(lineBreak?"\n":"");
}
/**
* 接受用戶輸入
* @return 用戶輸入
*/
public static int getInput(){
Scanner scanner = new Scanner(System.in);
return scanner.nextInt();
}
}
XLWrongInputEXception類(lèi)
package swu.xl.day4.MyPractise;
public class XLWrongInputEXception extends Throwable {
public XLWrongInputEXception(String desc){
super(desc);
}
}
運(yùn)行結(jié)果:
總結(jié)
以上是生活随笔為你收集整理的java自定义类怎么比大小_实战:Java 扑克牌比较游戏的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java组件化的优势_组件化编程开发如何
- 下一篇: 阿里云 刷新缓存 java_【从入门到放