頁:
[1]
樸克牌之黑傑克
package poker;
public class Card {
// 定義牌面數字
public enum Rank {ACE(1), 二(2), 三(3), 四(4), 五(5), 六(6), 七(7), 八(8), 九(9), 十(10), JACK(11), QUEEN(12), KING(13);
public final int num;
private Rank(int num) {
this.num = num;
}
}
// 定義牌面花色
public enum Suit { 梅花, 方塊, 紅心, 黑桃 }
private final Rank rank;
private final Suit suit;
protected Card(Rank rank, Suit suit) {
this.rank = rank;
this.suit = suit;
}
public int getNum() { return rank.num; }
public Rank rank() { return rank; }
public Suit suit() { return suit; }
public String toString() {
return suit + " " + rank;
}
}
package poker;
import java.util.*;
public class Deck {
private static final List<Card> protoDeck = new ArrayList<Card>();
private List<Card> currentDeck;
private int size;
public Deck() {
reflash();
}
// 抽出一張牌
public Card getNext() {
Card c = currentDeck.get((int)(Math.random()*size));
currentDeck.remove(c);
size--;
return c;
}
// 補滿所有的牌
public void reflash() {
currentDeck = newDeck();
size = currentDeck.size();
}
// 建立樸克牌模型
static {
for (Card.Suit suit : Card.Suit.values())
for (Card.Rank rank : Card.Rank.values())
protoDeck.add(new Card(rank, suit));
}
// 建立新的一副樸克牌
private static ArrayList<Card> newDeck() {
return new ArrayList<Card>(protoDeck);
}
}
package poker.game;
import poker.*;
import java.util.*;
import javax.swing.JOptionPane; //引入JOptionPane類別
class BlackJack {
private Deck deck = new Deck();
private HandCards[] players;
private int winnerPoint;
private int numPlayers;
public BlackJack(int numPlayers) throws IllegalArgumentException {
if(numPlayers < 1) {
throw new IllegalArgumentException("numPlayers 小於 1.");
}
this.numPlayers = numPlayers;
players = new HandCards;
String name;
int input;
// 輸入名字建立玩家,詢問是否為電腦玩家
for(int i = 0 ; i < numPlayers ; i++) {
name = JOptionPane.showInputDialog("請輸入名字:");
if(name.equals("")) {
name = "Player " + (i+1);
}
input = JOptionPane.showConfirmDialog(null,name + " 是一個電腦玩家嗎??","詢問",JOptionPane.YES_NO_OPTION);
players = new HandCards(name,input == JOptionPane.YES_OPTION);
}
}
// 初始化牌堆與手牌
public void reflash() {
deck.reflash();
winnerPoint = 0;
for(int i = 0 ; i < numPlayers ; i++) {
players.clear();
}
}
// 開始進行遊戲
public void startGame() {
reflash();
int point;
for(int i = 0 ; i < players.length ; i++) {
point = players.getFromDeck();
System.out.println(players.listCards() + "\t" + point);
if(point < 22) {
winnerPoint = Math.max(winnerPoint,point);
}
}
System.out.println(showWinner());
}
// return 勝利者名字
public String showWinner() {
StringBuilder sb = new StringBuilder("\n Winner :\n");
for(int i = 0 ; i < players.length ; i++) {
if(winnerPoint == players.getHandCardNum()) {
sb.append(players.getName()+"\n");
}
}
return sb.toString();
}
// 手牌類別
public class HandCards {
private ArrayList<Card> handCards = new ArrayList<Card>();
private boolean hasAce = false,isStart = false;
private int num = 0;
private final String name;
private final boolean isAI;
private HandCards(String name,boolean ai) {
this.name = name;
this.isAI = ai;
}
public String getName() {
return name;
}
// 清空手牌
private void clear() {
handCards.clear();
hasAce = false;
num = 0;
isStart = false;
}
// return 現在持有的牌
public String listCards() {
Card[] cards = new Card;
handCards.toArray(cards);
StringBuilder sb = new StringBuilder(name+":\n");
for(int i = 0 ; i < cards.length ; i++)
sb.append("\t"+cards+"\n");
return sb.toString();
}
// return 現在持有的牌之數字和
public int getHandCardNum() {
return num + (num < 12 && hasAce ? 10 : 0);
}
// 由 ai 判定是否取牌
private void aiGetFromDeck() {
while(this.getHandCardNum() < 17) {
getFromDeck(1);
}
}
// 由 使用者 判定是否取牌
private void userGetFromDeck() {
int input;
boolean canGetNext;
do {
input = JOptionPane.showConfirmDialog(null,this.listCards() + this.getHandCardNum() + "\n還要一張嗎?","詢問",JOptionPane.YES_NO_OPTION);
if(input == JOptionPane.YES_OPTION) {
canGetNext = this.getFromDeck(1);
} else {
canGetNext = false;
}
} while(canGetNext && input == JOptionPane.YES_OPTION);
}
// 只有在從未取過牌時能夠取牌,根據是否為 ai 決定由誰取牌
public synchronized int getFromDeck() {
if(!isStart) {
isStart = true;
getFromDeck(2);
if(isAI)
aiGetFromDeck();
else
userGetFromDeck();
}
return getHandCardNum();
}
// 取 size 量的牌,若牌堆沒牌了就不取了,若取牌前中後數字和就不能再取了
private synchronized boolean getFromDeck(int size) {
Card c;
int n;
if(num > 21) {
return false;
}
for(int i = 0 ; i < size ; i++) {
c = deck.getNext();
if(c == null) {
return false;
}
handCards.add(c);
n = c.getNum();
num += (n > 9 ? 10 : n);
if(n == 1) {
hasAce = true;
}
if(num > 21) {
return false;
}
}
if(num > 21) {
return false;
}
return true;
}
}
}
package poker.game;
import javax.swing.JOptionPane; //引入JOptionPane類別
public class BlackJackLoader {
public static void main(String [] argv) {
BlackJack bj = null;
int input = 0;
String str;
// 取得玩家人數
do {
str = JOptionPane.showInputDialog("請輸入玩家人數:");
try {
input = Integer.parseInt(str) ;
} catch(NumberFormatException e) {}
if(input > 0) {
bj = new BlackJack(input);
break;
}
} while(input < 1);
// 開始進行遊戲,結束後詢問是否再玩一次
do {
bj.startGame();
input = JOptionPane.showConfirmDialog(null,"還要再來一場嗎?","詢問",JOptionPane.YES_NO_OPTION);
} while (input == JOptionPane.YES_OPTION);
}
}
...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><div></div>
package poker;
import java.util.*;
public class Deck {
private static final List<Card> 牌堆模型 = new ArrayList<Card>();
private List<Card> 現有的牌;
private int 數量;
public Deck() {
洗牌();
}
// 抽出一張牌
public Card 抽出一張牌() {
Card c = 現有的牌.get((int)(Math.random()*數量));
現有的牌.remove(c);
數量--;
return c;
}
// 補滿所有的牌
public void 洗牌() {
現有的牌 = 新牌堆();
數量 = 現有的牌.size();
}
// 建立樸克牌模型
static {
for (Card.Suit suit : Card.Suit.values())
for (Card.Rank rank : Card.Rank.values())
牌堆模型.add(new Card(rank, suit));
}
// 用牌堆模型建立新的一副牌堆
private static ArrayList<Card> 新牌堆() {
return new ArrayList<Card>(牌堆模型);
}
}
package poker.game;
import poker.*;
import java.util.*;
import javax.swing.JOptionPane; //引入JOptionPane類別
class BlackJack {
private Deck 牌堆 = new Deck();
private 手 莊家;
private int 莊家點數;
private 手[] 閒家;
private int[] 閒家點數;
public BlackJack(int 閒家數量) throws IllegalArgumentException {
if(閒家數量 < 1)
throw new IllegalArgumentException("閒家數量 小於 1.");
莊家 = new 手("莊家",true);
閒家 = new 手[閒家數量];
閒家點數 = new int[閒家數量];
String 名字;
int input;
// 輸入名字建立閒家,詢問是否為電腦控制
for(int i = 0 ; i < 閒家數量 ; i++) {
名字 = JOptionPane.showInputDialog("請輸入名字:");
if(名字.equals(""))
名字 = "閒家 " + (i+1);
input = JOptionPane.showConfirmDialog(null,名字 + " 是否電腦控制嗎??","詢問",JOptionPane.YES_NO_OPTION);
閒家 = new 手(名字,input == JOptionPane.YES_OPTION);
}
}
public void 洗牌() {
牌堆.洗牌();
莊家.清空手牌();
for(int i = 0 ; i < 閒家.length ; i++)
閒家.清空手牌();
}
public void 發牌(手 玩家,int 張數) {
for(int i = 0 ; i < 張數 ; i++ ) {
if(玩家.可以拿牌())
玩家.拿牌(牌堆.抽出一張牌());
else {
JOptionPane.showMessageDialog(null,玩家.get名字()+"已經爆炸了!!!");
break;
}
}
}
public void 開始進行遊戲() {
洗牌();
this.發牌(莊家,2);
for(int i = 0 ; i < 閒家.length ; i++) {
this.發牌(閒家,2);
JOptionPane.showMessageDialog(null,莊家.列出手牌());
閒家點數 = 閒家.開始要牌();
}
莊家點數 = 莊家.開始要牌();
JOptionPane.showMessageDialog(null,結果());
}
public String 結果() {
StringBuilder 結果 = new StringBuilder(莊家.列出手牌() + "\t" + 莊家點數 + " " + (莊家點數 > 21 ? "爆牌" : "")+"\n");
StringBuilder 贏家 = new StringBuilder("\n 贏莊家 :\n");
StringBuilder 輸家 = new StringBuilder("\n 輸莊家 :\n");
StringBuilder 平手 = new StringBuilder("\n 平 手 :\n");
StringBuilder 爆牌 = new StringBuilder("\n 爆 牌 :\n");
莊家點數 = 莊家點數 > 21 ? -1 : 莊家點數;
for(int i = 0 ; i < 閒家.length ; i++) {
結果.append(閒家.列出手牌() + "\t" + 閒家點數 + " " + (閒家點數 > 21 ? "爆牌" : "")+"\n");
(閒家點數 > 21 ? 爆牌 : (莊家點數 == 閒家點數 ? 平手 : (莊家點數 < 閒家點數 ? 贏家 : 輸家))).append("\t"+閒家.get名字()+ " : " + 閒家點數 +"\n");
}
return 結果.append(贏家).append(輸家).append(平手).append(爆牌).toString();
}
private class 手 {
private final String 名字;
private final boolean isAI;
private ArrayList<Card> 手牌 = new ArrayList<Card>();
private boolean hasAce = false;
private int 總和 = 0;
private 手(String 名字,boolean isAI) {
this.名字 = 名字;
this.isAI = isAI;
}
public String get名字() {
return 名字;
}
private void 清空手牌() {
手牌.clear();
hasAce = false;
總和 = 0;
}
public String 列出明牌() {
Card[] cards = new Card[手牌.size()];
手牌.toArray(cards);
StringBuilder sb = new StringBuilder();
for(int i = 1 ; i < cards.length ; i++)
sb.append("\t"+cards+"\n");
return sb.toString();
}
public String 列出手牌() {
return 名字 + ":\n\t" + ((手牌.size() > 0) ? (手牌.get(0) + "\n" + 列出明牌()) : "沒有牌");
}
// 由 電腦 判定是否取牌
private void 電腦要牌() {
while(可以拿牌() && this.算點數() < 17)
BlackJack.this.發牌(this,1);
}
// 由 使用者 判定是否取牌
private void 使用者要牌() {
int input;
while(可以拿牌()) {
input = JOptionPane.showConfirmDialog(null,this.列出手牌() + this.算點數() + "\n還要一張嗎?","詢問",JOptionPane.YES_NO_OPTION);
if(input == JOptionPane.YES_OPTION)
BlackJack.this.發牌(this,1);
}
}
// 只有在從未取過牌時能夠取牌,根據是否為 ai 決定由誰取牌
public synchronized int 開始要牌() {
if(isAI)
電腦要牌();
else
使用者要牌();
return 算點數();
}
private synchronized boolean 拿牌(Card 牌) {
int 數字 = 牌.getNum();
手牌.add(牌);
總和 += (數字 > 9 ? 10 : 數字);
hasAce = 數字 == 1 ? true : hasAce;
return 可以拿牌();
}
// 判斷能否拿牌
private boolean 可以拿牌() {
return (總和 <= 21);
}
// return 現在手牌的點數和
public int 算點數() {
return 總和 + (總和 < 12 && hasAce ? 10 : 0);
}
}
}
...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div> 這就是21點的遊戲嗎?謝謝大大分享,之前看到有人問,就很好奇程式碼是如何寫的,現在有可以多一個學習的機會了 ,謝謝 QQ編譯不出來 為何有CLASS相同PACKAGE也相同的檔案
要如何編譯呢? 望高手解答 感謝大大分享~~
JAVA新手正在努力學習中^^~<br><br><br><br><br><div></div>
頁:
[1]