目錄
原題呈現
題意分析
簡單的概括本游戲:
實作功能:
代碼實作
參與者類
發牌器類
判斷機制game類
Main運行類
運行結果
總結
原題呈現
人稱Black Jack,21點!
"21點"紙牌游戲是一種古老的撲克牌游戲,游戲規則是參與者設法使自己的牌達到總分21,而不超過這個數值(<=21),撲克牌的分值取他們的面值,A充當1分,J、Q、和K分別是11、12和13分
莊家和玩家,在開局時各有兩張牌,玩家可以看到自己的牌及總分,而莊家有一張牌暫時隱藏的,接下來,若玩家愿意,玩家可以再拿一張牌(經過多次閱讀相關游戲規則,現實中每位玩家是可以無限要牌的,但基于本題的,玩家只能再拿一張更為合理,即每位玩家和莊家最多三張牌),如果玩家的總分超過了21分,即引爆,那么玩家就輸了,在玩家拿了額外的牌后,莊家將顯示隱藏的牌,只有莊家的總分小于等于21,那么他就必須拿牌,如果莊家引爆了,那么玩家將獲勝,否則將玩家和莊家的總分的作比較,如果玩家的總分大于莊家的總分,則玩家獲勝,若總分相同,則玩家與莊家打成平局,
要求:利用鏈表實作洗牌、發牌、計算總分、顯示撲克的花色和面值
題意分析
(由于實際的21點游戲規則和本題有所出入,此處限制參與人數:莊家1名,玩家(閑家)1名)
簡單的概括本游戲:
- 開場階段:開場兩人均有2張底牌,玩家的牌是顯示的,莊家的牌一張顯示一張隱藏,
- 玩家要牌階段:玩家可選擇是否繼續摸牌;若有玩家選擇摸取,莊家將顯示隱藏的牌,此時若莊家的總分小于等于21,他在后續的計算總分階段便必須摸取第三張牌,
- 計算總分階段:摸牌結束后,莊家可選擇是否進行摸牌,摸牌后若沒有爆,則比總分
實作功能:
總體來講,我們需要用程式實作以下幾個功能:
- 初始階段的洗牌發牌
- 判斷玩家是否繼續摸牌,并執行對應的操作
- 進行結果的判定
代碼實作
參與者類
功能:獲取牌,分數,身份
package 資料結構;
import java.util.ArrayList;
/**
* 玩家
*/
public class Player {
//玩家手中牌
private ArrayList<String> cardList=new ArrayList<>();
//分數
private int mark=0;
//身份
private String identity;
public Player() {
}
public Player(String identity) {
this.identity = identity;
}
//獲取身份名稱
public String getIdentity() {
return identity;
}
public void setIdentity(String identity) {
this.identity = identity;
}
//獲取分數
public int getMark() {
return mark;
}
//設定分數
public void setMark(int mark) {
this.mark = mark;
}
//獲取玩家手牌
public ArrayList<String> getCardList() {
return cardList;
}
//玩家拿牌
public void setCard(String card){
cardList.add(card);
}
}
發牌器類
功能:生產牌,記錄牌,提供對應卡牌的分值表
package 資料結構;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Random;
/**
* 發牌器
*/
public class Dealer {
//總牌
private ArrayList<String> getCardList = new ArrayList<>();
//已經發放的牌
private LinkedList<String> terminal = new LinkedList<>();
//分值本
private HashMap<String, Integer> map = new HashMap();
//洗牌
public void ini() {
String[] color = {"紅心", "黑桃", "梅花", "方塊"};
String[] number = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
for (int i = 0; i < color.length; i++) {
for (int i1 = 0; i1 < number.length; i1++) {
getCardList.add(color[i] + number[i1]);
map.put(color[i] + number[i1], i1 + 1);
}
}
}
//獲取一個隨機的卡牌
public String getCard() {
Random random = new Random();
String card = getCardList.get(random.nextInt(getCardList.size()));
while (terminal.contains(card)) card = getCardList.get(random.nextInt(getCardList.size()));
terminal.add(card);
return card;
}
//獲取分值本
public HashMap<String, Integer> getMap() {
return map;
}
}
判斷機制game類
功能:判定參與者是否引爆,存盤參與者物件
package 資料結構;
import java.util.ArrayList;
import java.util.HashMap;
public class Game {
private ArrayList plays = new ArrayList();
private Dealer dealer = new Dealer();
public Game(Dealer dealer) {
this.dealer = dealer;
}
//判斷參與者是否引爆
public boolean isDead(Player player) {
return player.getMark() > 21 ? true : false;
}
//獲取參與者的分數
public int getMark(Player player) {
int mark = 0;
HashMap<String, Integer> map = dealer.getMap();
for (String card : player.getCardList()) {
mark += map.get(card);
}
return mark;
}
//歷遍顯示參與者的牌
public void show(Player player) {
for (String s : player.getCardList()) {
System.out.print(s + " ");
}
}
//獲取參與者物件集合
public ArrayList<Player> getPlays() {
return plays;
}
public void judge() {
if (isDead(getPlays().get(0)) && !isDead(getPlays().get(1))) {//若莊家引爆,玩家未引爆
printMark();
System.out.println(getPlays().get(0).getIdentity() + "已引爆," + getPlays().get(1).getIdentity() + "獲勝");
System.out.println();
} else if (!isDead(getPlays().get(0)) && isDead(getPlays().get(1))) {//若莊家未引爆,玩家引爆
printMark();
System.out.println(getPlays().get(1).getIdentity() + "已引爆," + getPlays().get(0).getIdentity() + "獲勝");
System.out.println();
} else if (isDead(getPlays().get(0)) && isDead(getPlays().get(1))) {//若兩者均引爆
printMark();
System.out.println(getPlays().get(1).getIdentity() + "和" + getPlays().get(0).getIdentity() + "均已引爆,平局");
System.out.println();
} else {//兩者均未引爆
if (getPlays().get(0).getMark() > getPlays().get(1).getMark()) {
printMark();
System.out.println(getPlays().get(0).getIdentity() + "贏得了勝利");
System.out.println();
} else if (getPlays().get(0).getMark() < getPlays().get(1).getMark()) {
printMark();
System.out.println(getPlays().get(1).getIdentity() + "贏得了勝利");
System.out.println();
} else {
printMark();
System.out.println("平局");
System.out.println();
}
}
}
public void printMark() {
System.out.print(getPlays().get(0).getIdentity() + "手牌為:");
show(getPlays().get(0));
System.out.print(" " + getPlays().get(0).getIdentity()+"得分為:" + getPlays().get(0).getMark());
System.out.println();
System.out.print(getPlays().get(1).getIdentity() + "手牌為:");
show(getPlays().get(1));
System.out.print(" " + getPlays().get(1).getIdentity() + "得分為:" + getPlays().get(1).getMark());
System.out.println();
}
}
Main運行類
功能:整合代碼,實作邏輯運行
package 資料結構;
import java.io.*;
public class Main {
static StreamTokenizer r;
static PrintWriter pr;
static BufferedReader re;
static Dealer dealer;;//初始化發牌器
static Game game;
static {
r = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
pr = new PrintWriter(new OutputStreamWriter(System.out));
re = new BufferedReader(new InputStreamReader(System.in));
}
public static void main(String[] args) throws IOException {
System.out.println("-------------21點游戲正式開始-------------");
int round = 0;
while (true) {
//初始化
dealer=new Dealer();
dealer.ini();
game=new Game(dealer);
pr.println(" (第" + ++round + "回合) ");
pr.flush();
//初始化發牌器
dealer.ini();
//初始化參與者(兩位:一名莊家,一名玩家)
Player player1 = new Player("莊家");
Player player2 = new Player("玩家");
game.getPlays().add(player1);
game.getPlays().add(player2);
//玩家發牌
for (int i = 0; i < game.getPlays().size(); i++) {
for (int i1 = 0; i1 < 2; i1++) {
game.getPlays().get(i).setCard(dealer.getCard());
}
//存盤玩家的分數
game.getPlays().get(i).setMark(game.getMark(game.getPlays().get(i)));
}
//進行牌的展示,并計算得分
for (int i = 0; i < game.getPlays().size(); i++) {
int cord = 0;
pr.print(game.getPlays().get(i).getIdentity() + ":");
pr.flush();
game.show(game.getPlays().get(i));
System.out.println();
}
//發牌后進行拿牌階段
pr.println("請玩家選擇是否繼續摸牌(輸入0不摸牌,否則再拿一張牌)");
pr.flush();
String status = re.readLine();
if (status.equals("0")) {//若玩家不拿牌
pr.println("玩家選擇不拿牌");
pr.flush();
pr.println("請莊家選擇是否繼續摸牌(輸入0不摸牌,輸入1再拿一張牌)");
pr.flush();
String status1 = re.readLine();
if (status1.equals("0")) {//若莊家也不拿牌
game.judge();
} else {//若莊家拿牌
String card = dealer.getCard();
pr.println("莊家選擇再拿一張:"+card);
pr.flush();
game.getPlays().get(0).getCardList().add(card);
game.getPlays().get(0).setMark(game.getMark(game.getPlays().get(0)));
game.judge();
}
} else {//若玩家拿牌
String card1 = dealer.getCard();
pr.println("玩家選擇再拿一張牌:"+card1);
pr.flush();
game.getPlays().get(1).getCardList().add(card1);
game.getPlays().get(1).setMark(game.getMark(game.getPlays().get(1)));
String card2 = dealer.getCard();
pr.println("莊家選擇再拿一張牌:"+card2);
pr.flush();
game.getPlays().get(0).getCardList().add(card2);
game.getPlays().get(0).setMark(game.getMark(game.getPlays().get(0)));
game.judge();
}
}
}
}
運行結果

總結
再本題中我們是采用面向物件的思想來解決本題的,對應本題而言采用這種思想可能反而加大了我們的代碼量,但從長遠的角度,這樣寫有助于我們后期的維護,減少了代碼間的耦合:比如,若我們再升級下游戲的玩法,給參與者加上錢數,那么對于我們程式的改動將會很友好
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/352036.html
標籤:其他
上一篇:三子棋/九宮格代碼實作
