TL;DR
昨年GW期間中にTypeScriptで作成したブラックジャックをJavaで作り直したので、その作業メモ。
公開リポジトリ
doxygenドキュメント
各種クラス
Card
////////////////////////////////////////////////////////////////////////////////
/// @file Card.java
/// @brief カードクラス
/// @author Yuta Yoshinaga
/// @date 2019.04.27
/// $Version: $
/// $Revision: $
///
/// (c) 2019 Yuta Yoshinaga.
///
/// - 本ソフトウェアの一部又は全てを無断で複写複製(コピー)することは、
/// 著作権侵害にあたりますので、これを禁止します。
/// - 本製品の使用に起因する侵害または特許権その他権利の侵害に関しては
/// 当方は一切その責任を負いません。
///
////////////////////////////////////////////////////////////////////////////////
package jp.gr.java_conf.yuta_yoshinaga.java_trumpcards;
////////////////////////////////////////////////////////////////////////////////
/// @class Card
/// @brief カードクラス
///
////////////////////////////////////////////////////////////////////////////////
public class Card {
public static final int DEF_CARD_TYPE_JOKER = 0;
public static final int DEF_CARD_TYPE_SPADE = 1;
public static final int DEF_CARD_TYPE_CLOVER = 2;
public static final int DEF_CARD_TYPE_HEART = 3;
public static final int DEF_CARD_TYPE_DIAMOND = 4;
public static final int DEF_CARD_TYPE_MIN = DEF_CARD_TYPE_JOKER;
public static final int DEF_CARD_TYPE_MAX = DEF_CARD_TYPE_DIAMOND;
public static final int DEF_CARD_VALUE_JOKER = 0;
public static final int DEF_CARD_VALUE_MIN = 0;
public static final int DEF_CARD_VALUE_MAX = 13;
private int type; //!< カード種類
private int value; //!< カード値
private boolean drowFlag; //!< カード払い出しフラグ
private String ext; //!< カード拡張情報など(カード別にメッセージを出す場合など)
////////////////////////////////////////////////////////////////////////////////
/// @brief コンストラクタ
/// @fn public Card()
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public Card() {
this.type = DEF_CARD_TYPE_JOKER;
this.value = DEF_CARD_VALUE_JOKER;
this.drowFlag = false;
this.ext = "";
}
////////////////////////////////////////////////////////////////////////////////
/// @brief ゲッター
/// @fn public int getType()
/// @return カード種類
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public int getType() {
return type;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief セッター
/// @fn public void setType(int type)
/// @param[in] int type カード種類
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public void setType(int type) {
if(DEF_CARD_TYPE_MIN <= type && type <= DEF_CARD_TYPE_MAX){
this.type = type;
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief ゲッター
/// @fn public getValue(): number
/// @return カード値
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public int getValue() {
return value;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief セッター
/// @fn public void setValue(int value)
/// @param[in] int value カード値
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public void setValue(int value) {
if(DEF_CARD_VALUE_MIN <= value && value <= DEF_CARD_VALUE_MAX){
this.value = value;
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief ゲッター
/// @fn public boolean getDrowFlag()
/// @return カード払い出しフラグ
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public boolean getDrowFlag() {
return drowFlag;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief セッター
/// @fn public void setDrowFlag(boolean drowFlag)
/// @param[in] boolean drowFlag カード払い出しフラグ
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public void setDrowFlag(boolean drowFlag) {
this.drowFlag = drowFlag;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief ゲッター
/// @fn public String getExt()
/// @return カード払い出しフラグ
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public String getExt() {
return ext;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief セッター
/// @fn public void setExt(String ext)
/// @param[in] String ext カード拡張情報など(カード別にメッセージを出す場合など)
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public void setExt(String ext) {
this.ext = ext;
}
}
トランプのカード情報を保持するクラス。
TrumpCards
////////////////////////////////////////////////////////////////////////////////
/// @file TrumpCards.java
/// @brief トランプカードクラス
/// @author Yuta Yoshinaga
/// @date 2019.04.27
/// $Version: $
/// $Revision: $
///
/// (c) 2019 Yuta Yoshinaga.
///
/// - 本ソフトウェアの一部又は全てを無断で複写複製(コピー)することは、
/// 著作権侵害にあたりますので、これを禁止します。
/// - 本製品の使用に起因する侵害または特許権その他権利の侵害に関しては
/// 当方は一切その責任を負いません。
///
////////////////////////////////////////////////////////////////////////////////
package jp.gr.java_conf.yuta_yoshinaga.java_trumpcards;
import java.util.ArrayList;
import java.util.Collections;
////////////////////////////////////////////////////////////////////////////////
/// @class TrumpCards
/// @brief トランプカードクラス
///
////////////////////////////////////////////////////////////////////////////////
public class TrumpCards {
public static final int DEF_CARD_CNT = (13 * 4);
private ArrayList<Card> deck; //!< 山札
private int deckDrowCnt; //!< 山札配った枚数
private int deckCnt; //!< 山札枚数
////////////////////////////////////////////////////////////////////////////////
/// @brief コンストラクタ
/// @fn public TrumpCards(int jokerCnt)
/// @param[in] int jokerCnt ジョーカー枚数
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public TrumpCards(int jokerCnt) {
this.deckCnt = DEF_CARD_CNT + jokerCnt;
this.cardsInit();
this.deckInit();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief ゲッター
/// @fn public ArrayList<Card> getDeck()
/// @return 山札
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public ArrayList<Card> getDeck() {
return deck;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief セッター
/// @fn public void setDeck(ArrayList<Card> deck)
/// @param[in] ArrayList<Card> deck 山札
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public void setDeck(ArrayList<Card> deck) {
this.deck = deck;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief ゲッター
/// @fn public int getDeckDrowCnt()
/// @return 山札配った枚数
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public int getDeckDrowCnt() {
return deckDrowCnt;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief セッター
/// @fn public void setDeckDrowCnt(int deckDrowCnt)
/// @param[in] int deckDrowCnt 山札配った枚数
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public void setDeckDrowCnt(int deckDrowCnt) {
this.deckDrowCnt = deckDrowCnt;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief ゲッター
/// @fn public int getDeckCnt()
/// @return 山札枚数
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public int getDeckCnt() {
return deckCnt;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief セッター
/// @fn public void setDeckCnt(int deckCnt)
/// @param[in] int deckCnt 山札枚数
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public void setDeckCnt(int deckCnt) {
this.deckCnt = deckCnt;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief カード初期化
/// @fn private void cardsInit()
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
private void cardsInit() {
this.deck = new ArrayList<Card>();
for (int i = 0; i < this.deckCnt; i++) {
Card curCard = new Card();
curCard.setDrowFlag(false);
if (0 <= i && i <= 12) {
// *** スペード *** //
curCard.setType(Card.DEF_CARD_TYPE_SPADE);
curCard.setValue(i + 1);
} else if (13 <= i && i <= 25) {
// *** クローバー *** //
curCard.setType(Card.DEF_CARD_TYPE_CLOVER);
curCard.setValue((i - 13) + 1);
} else if (26 <= i && i <= 38) {
// *** ハート *** //
curCard.setType(Card.DEF_CARD_TYPE_HEART);
curCard.setValue((i - 26) + 1);
} else if (39 <= i && i <= 51) {
// *** ダイアモンド *** //
curCard.setType(Card.DEF_CARD_TYPE_DIAMOND);
curCard.setValue((i - 39) + 1);
} else {
// *** ジョーカー *** //
curCard.setType(Card.DEF_CARD_TYPE_JOKER);
curCard.setValue((i - 52) + 1);
}
this.deck.add(curCard);
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief 山札初期化
/// @fn private void deckInit()
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
private void deckInit() {
this.deckDrowFlagInit();
this.deckDrowCnt = 0;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief 山札ドローフラグ初期化
/// @fn private deckDrowFlagInit(): void
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
private void deckDrowFlagInit() {
for (int i = 0; i < this.deckCnt; i++) {
this.deck.get(i).setDrowFlag(false);
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief 山札シャッフル
/// @fn public shuffle(): void
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public void shuffle() {
Collections.shuffle(this.deck);
this.deckDrowFlagInit();
this.deckDrowCnt = 0;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief 山札配る
/// @fn public drowCard(): Card
/// @return カードクラス
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public Card drowCard() {
Card res = null;
if (this.deckDrowCnt < this.deckCnt) {
this.deck.get(this.deckDrowCnt).setDrowFlag(true);
res = this.deck.get(this.deckDrowCnt++);
}
return res;
}
}
トランプカードの山札などを管理するクラス。
Player
////////////////////////////////////////////////////////////////////////////////
/// @file Player.java
/// @brief プレイヤークラス
/// @author Yuta Yoshinaga
/// @date 2019.04.27
/// $Version: $
/// $Revision: $
///
/// (c) 2019 Yuta Yoshinaga.
///
/// - 本ソフトウェアの一部又は全てを無断で複写複製(コピー)することは、
/// 著作権侵害にあたりますので、これを禁止します。
/// - 本製品の使用に起因する侵害または特許権その他権利の侵害に関しては
/// 当方は一切その責任を負いません。
///
////////////////////////////////////////////////////////////////////////////////
package jp.gr.java_conf.yuta_yoshinaga.java_trumpcards;
import java.util.ArrayList;
////////////////////////////////////////////////////////////////////////////////
/// @class Player
/// @brief プレイヤークラス
///
////////////////////////////////////////////////////////////////////////////////
public class Player {
private ArrayList<Card> cards; //!< プレイヤーカード
private int cardsCnt; //!< プレイヤーカード枚数
private int score; //!< プレイヤースコア
////////////////////////////////////////////////////////////////////////////////
/// @brief コンストラクタ
/// @fn public Player()
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public Player() {
this.cards = new ArrayList<Card>();
this.cardsCnt = 0;
this.score = 0;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief ゲッター
/// @fn ArrayList<Card> getCards()
/// @return プレイヤーカード
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public ArrayList<Card> getCards() {
return cards;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief セッター
/// @fn public void setCards(ArrayList<Card> cards)
/// @param[in] ArrayList<Card> cards プレイヤーカード
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public void setCards(ArrayList<Card> cards) {
this.cards = cards;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief ゲッター
/// @fn public int getCardsCnt()
/// @return プレイヤーカード枚数
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public int getCardsCnt() {
return cardsCnt;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief セッター
/// @fn public void setCardsCnt(int cardsCnt)
/// @param[in] int cardsCnt プレイヤーカード枚数
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public void setCardsCnt(int cardsCnt) {
this.cardsCnt = cardsCnt;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief ゲッター
/// @fn public int getScore()
/// @return プレイヤースコア
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public int getScore() {
return score;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief セッター
/// @fn public void setScore(int score)
/// @param[in] int score プレイヤースコア
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public void setScore(int score) {
this.score = score;
}
}
ブラックジャックのプレイヤー情報を保持するクラス
BlackJack
////////////////////////////////////////////////////////////////////////////////
/// @file BlackJack.java
/// @brief ブラックジャッククラス
/// @author Yuta Yoshinaga
/// @date 2019.04.27
/// $Version: $
/// $Revision: $
///
/// (c) 2019 Yuta Yoshinaga.
///
/// - 本ソフトウェアの一部又は全てを無断で複写複製(コピー)することは、
/// 著作権侵害にあたりますので、これを禁止します。
/// - 本製品の使用に起因する侵害または特許権その他権利の侵害に関しては
/// 当方は一切その責任を負いません。
///
////////////////////////////////////////////////////////////////////////////////
package jp.gr.java_conf.yuta_yoshinaga.java_trumpcards;
import java.util.ArrayList;
////////////////////////////////////////////////////////////////////////////////
/// @class BlackJack
/// @brief ブラックジャッククラス
///
////////////////////////////////////////////////////////////////////////////////
public class BlackJack {
public static final int DEF_SHUFFLE_CNT = 10;
private TrumpCards trumpCards; //!< トランプカード
private Player player; //!< プレイヤー
private Player dealer; //!< ディーラー
private boolean gameEndFlag; //!< ゲーム終了フラグ
////////////////////////////////////////////////////////////////////////////////
/// @brief コンストラクタ
/// @fn public BlackJack()
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public BlackJack() {
this.trumpCards = new TrumpCards(0);
this.player = new Player();
this.dealer = new Player();
this.gameInit();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief ゲッター
/// @fn TrumpCards getTrumpCards()
/// @return トランプカード
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public TrumpCards getTrumpCards() {
return trumpCards;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief セッター
/// @fn public void setTrumpCards(TrumpCards trumpCards)
/// @param[in] TrumpCards trumpCards トランプカード
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public void setTrumpCards(TrumpCards trumpCards) {
this.trumpCards = trumpCards;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief ゲッター
/// @fn public Player getPlayer()
/// @return プレイヤー
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public Player getPlayer() {
return player;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief セッター
/// @fn public void setPlayer(Player player)
/// @param[in] Player player プレイヤー
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public void setPlayer(Player player) {
this.player = player;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief ゲッター
/// @fn public Player getDealer()
/// @return ディーラー
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public Player getDealer() {
return dealer;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief セッター
/// @fn public void setDealer(Player dealer)
/// @param[in] Player dealer ディーラー
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public void setDealer(Player dealer) {
this.dealer = dealer;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief ゲッター
/// @fn public boolean getGameEndFlag()
/// @return ディーラー
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public boolean getGameEndFlag() {
return gameEndFlag;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief セッター
/// @fn public void setGameEndFlag(boolean gameEndFlag)
/// @param[in] boolean gameEndFlag ゲーム終了フラグ
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public void setGameEndFlag(boolean gameEndFlag) {
this.gameEndFlag = gameEndFlag;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief ゲーム初期化
/// @fn public void gameInit()
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public void gameInit() {
this.gameEndFlag = false;
// *** 山札シャッフル *** //
for (int i = 0; i < DEF_SHUFFLE_CNT; i++) {
this.trumpCards.shuffle();
}
// *** プレイヤー・ディーラー初期化 *** //
this.player.setCards(new ArrayList<Card>());
this.player.setCardsCnt(0);
this.dealer.setCards(new ArrayList<Card>());
this.dealer.setCardsCnt(0);
// *** プレイヤー・ディーラー手札を2枚づつ配る *** //
for (int i = 0; i < 2; i++) {
this.player.getCards().add(this.trumpCards.drowCard());
this.player.setCardsCnt(this.player.getCardsCnt() + 1);
this.dealer.getCards().add(this.trumpCards.drowCard());
this.dealer.setCardsCnt(this.dealer.getCardsCnt() + 1);
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief プレイヤーヒット
/// @fn public void playerHit()
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public void playerHit() {
if (this.gameEndFlag == false) {
this.player.getCards().add(this.trumpCards.drowCard());
this.player.setCardsCnt(this.player.getCardsCnt() + 1);
int score = this.getScore(this.player.getCards(), this.player.getCardsCnt());
if (22 <= score)
this.playerStand(); // バーストしたので強制終了
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief プレイヤースタンド
/// @fn public void playerStand()
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public void playerStand() {
this.dealerHit();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief ディーラーヒット
/// @fn private void dealerHit()
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
private void dealerHit() {
for (;;) {
int score = this.getScore(this.dealer.getCards(), this.dealer.getCardsCnt());
if (score < 17) {
// *** ディーラーは自分の手持ちのカードの合計が「17」以上になるまで *** //
// *** ヒットし続ける(カードを引き続ける) *** //
this.dealer.getCards().add(this.trumpCards.drowCard());
this.dealer.setCardsCnt(this.dealer.getCardsCnt() + 1);
} else {
// *** ディーラーは自分の手持ちカードの合計が「17」以上になったら *** //
// *** ステイする(カードを引かない)。 *** //
this.dealerStand();
break;
}
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief ディーラースタンド
/// @fn private void dealerStand()
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
private void dealerStand() {
this.gameEndFlag = true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief 手札から現在のスコア取得
/// @fn public int getScore(ArrayList<Card> cards,int cardsCnt)
/// @param[in] ArrayList<Card> cards 手札
/// @param[in] int cardsCnt 手札枚数
/// @return 現在のスコア
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public int getScore(ArrayList<Card> cards, int cardsCnt) {
int res = 0;
boolean aceFlag = false;
for (int i = 0; i < cardsCnt; i++) {
if (2 <= cards.get(i).getValue() && cards.get(i).getValue() <= 10) {
// *** 2~10 *** //
res += cards.get(i).getValue();
} else if (11 <= cards.get(i).getValue() && cards.get(i).getValue() <= 13) {
// *** 11~13 *** //
res += 10;
} else {
if (aceFlag) {
// *** 2枚目のエースは強制的に1で換算する*** //
res += 1;
} else {
// *** エースは後ほど計算する *** //
aceFlag = true;
}
}
}
if (aceFlag) {
// *** エース計算 *** //
var tmpScore1 = res + 1;
var tmpScore2 = res + 11;
var diff1 = 21 - tmpScore1;
var diff2 = 21 - tmpScore2;
if ((22 <= tmpScore1) && (22 <= tmpScore2)) {
// *** どちらもバーストしているならエースを1 *** //
res = tmpScore1;
} else if ((22 <= tmpScore1) && (tmpScore2 <= 21)) {
// *** エースが1でバーストしているならエースを11 *** //
res = tmpScore2;
} else if ((tmpScore1 <= 21) && (22 <= tmpScore2)) {
// *** エースが11でバーストしているならエースを1 *** //
res = tmpScore1;
} else {
// *** どちらもバーストしていないなら21との差分が小さい方を採用 *** //
if (diff1 < diff2)
res = tmpScore1;
else
res = tmpScore2;
}
}
return res;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief ゲーム勝敗判定
/// @fn public int gameJudgment()
/// @return ゲーム勝敗判定
/// - 1 : プレイヤーの勝利
/// - 0 : 引き分け
/// - -1 : プレイヤーの敗北
///
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public int gameJudgment() {
int res = 0;
int score1 = this.getScore(this.player.getCards(), this.player.getCardsCnt());
int score2 = this.getScore(this.dealer.getCards(), this.dealer.getCardsCnt());
int diff1 = 21 - score1;
int diff2 = 21 - score2;
if (22 <= score1 && 22 <= score2) {
// *** プレイヤー・ディーラー共にバーストしているので負け *** //
res = -1;
} else if (22 <= score1 && score2 <= 21) {
// *** プレイヤーバーストしているので負け *** //
res = -1;
} else if (score1 <= 21 && 22 <= score2) {
// *** ディーラーバーストしているので勝ち *** //
res = 1;
} else {
if (diff1 == diff2) {
// *** 同スコアなら引き分け *** //
res = 0;
if (score1 == 21 && this.player.getCardsCnt() == 2 && this.dealer.getCardsCnt() != 2) {
// *** プレイヤーのみがピュアブラックジャックならプレイヤーの勝ち *** //
res = 1;
}
} else if (diff1 < diff2) {
// *** プレイヤーの方が21に近いので勝ち *** //
res = 1;
} else {
// *** ディーラーの方が21に近いので負け *** //
res = -1;
}
}
return res;
}
}
ブラックジャックゲーム及びプレイヤーの状態を管理するクラス。
BlackJackMain
////////////////////////////////////////////////////////////////////////////////
/// @file BlackJackMain.java
/// @brief ブラックジャックメインクラス
/// @author Yuta Yoshinaga
/// @date 2019.04.27
/// $Version: $
/// $Revision: $
///
/// (c) 2019 Yuta Yoshinaga.
///
/// - 本ソフトウェアの一部又は全てを無断で複写複製(コピー)することは、
/// 著作権侵害にあたりますので、これを禁止します。
/// - 本製品の使用に起因する侵害または特許権その他権利の侵害に関しては
/// 当方は一切その責任を負いません。
///
////////////////////////////////////////////////////////////////////////////////
package jp.gr.java_conf.yuta_yoshinaga.java_trumpcards;
import java.util.ArrayList;
import java.util.Scanner;
////////////////////////////////////////////////////////////////////////////////
/// @class BlackJackMain
/// @brief ブラックジャックメインクラス
///
////////////////////////////////////////////////////////////////////////////////
public class BlackJackMain {
////////////////////////////////////////////////////////////////////////////////
/// @brief メインメソッド
/// @fn public static void main(String[] args)
/// @param[in] String[] args
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public static void main(String[] args) {
BlackJackMain blackJackMain = new BlackJackMain();
BlackJack blackJack = new BlackJack();
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("Please enter a command.");
System.out.println("q・・・quit");
System.out.println("r・・・reset");
System.out.println("h・・・hit");
System.out.println("s・・・stand");
blackJackMain.showStatus(blackJack);
String inputStr = sc.nextLine();
switch (inputStr) {
case "q":
case "quit":
// quit
System.out.println("bye.");
sc.close();
System.exit(0);
break;
case "r":
case "reset":
// reset
blackJack.gameInit();
break;
case "h":
case "hit":
// hit
blackJack.playerHit();
break;
case "s":
case "stand":
// stand
blackJack.playerStand();
break;
default:
// Unsupported command
System.out.println("Unsupported command.");
break;
}
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief ステータス表示
/// @fn public void showStatus(BlackJack blackJack)
/// @param[in] BlackJack blackJack
/// @return ありません
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public void showStatus(BlackJack blackJack) {
System.out.println("----------");
// dealer
ArrayList<Card> dc = blackJack.getDealer().getCards();
int dcc = blackJack.getDealer().getCardsCnt();
System.out.println("dealer score " + (blackJack.getGameEndFlag() ? blackJack.getScore(dc, dcc) : ""));
String cardStr = "";
if (blackJack.getGameEndFlag()) {
for (int i = 0; i < dcc; i++) {
if (i != 0)
cardStr += ",";
cardStr += getCardStr(dc.get(i));
}
} else {
cardStr = getCardStr(dc.get(0)) + ",*";
}
System.out.println(cardStr);
System.out.println("----------");
// player
ArrayList<Card> pc = blackJack.getPlayer().getCards();
int pcc = blackJack.getPlayer().getCardsCnt();
System.out.println("player score " + blackJack.getScore(pc, pcc));
cardStr = "";
for (int i = 0; i < pcc; i++) {
if (i != 0)
cardStr += ",";
cardStr += getCardStr(pc.get(i));
}
System.out.println(cardStr);
System.out.println("----------");
if (blackJack.getGameEndFlag()) {
if (blackJack.gameJudgment() == 1) {
System.out.println("You are the winner.");
} else if (blackJack.gameJudgment() == 0) {
System.out.println("It is a draw.");
} else {
System.out.println("It is your loss.");
}
System.out.println("----------");
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief カード情報文字列取得
/// @fn public String getCardStr(Card card)
/// @param[in] Card card
/// @return カード情報文字列取得
/// @author Yuta Yoshinaga
/// @date 2019.04.27
///
////////////////////////////////////////////////////////////////////////////////
public String getCardStr(Card card) {
String res = "";
switch (card.getType()) {
case Card.DEF_CARD_TYPE_SPADE:
res = "SPADE ";
break;
case Card.DEF_CARD_TYPE_CLOVER:
res = "CLOVER ";
break;
case Card.DEF_CARD_TYPE_HEART:
res = "HEART ";
break;
case Card.DEF_CARD_TYPE_DIAMOND:
res = "DIAMOND ";
break;
default:
res = "Unsupported card";
break;
}
res = res + card.getValue();
return res;
}
}
ブラックジャックゲームをコンソールで行う為のクラス。
コンソールからの入力に応じて、対応したアクションを取る。
所感
- なるべくオブジェクト指向に沿うようにクラス設計を行った。
- 現在業務にてJavaのコンソールアプリに携わっているので、コンソールアプリで作成した。
- できれば今後サーブレット版を作ってWebアプリ化したい。
- GW10連休の初日で、昼寝をしすぎて夜眠れなそうな変なテンションで作業を開始した。
- 作業時間2時間くらい。コンソールアプリは手軽に作れるので良い。