Nachtrag: @ k73i55no5 kommentierte einen besseren Refactoring-Vorschlag. Vielen Dank. Siehe Kommentare für Details. Refactoring nur der Klassenmitgliedsstruktur (Struktur). Wir haben noch nicht begonnen, den Verarbeitungscode (Interieur, Implementierung) umzugestalten. (Bis hierher addiert)
Ich habe den Quellcode von "Blackjack mit Java machen" von @ yuta-yoshinaga gesehen. Ich schrieb einen etwas bitteren Kommentar, weil die Kapselung von allen Setzern und Gettern zerstört wurde und einige Klassen nicht funktionierten. Es ist nur ein Kommentar, also habe ich ihn auf meine eigene Weise überarbeitet. Es gibt noch einige Punkte zu überprüfen, aber ich hoffe, Sie finden es hilfreich.
Fügen Sie ein Sequenzdiagramm hinzu.
@startuml
participant "BlackJack" as blackjack
@enduml
BlackJack.java
public class BlackJack {
private final Player player;
private final Dealer dealer;
public BlackJack() {
this(new CUIPlayer(), new Dealer());
}
public BlackJack(Player player, Dealer dealer) {
this.player = player;
this.dealer = dealer;
}
public void play() {
player.reset();
dealer.reset();
for (int i = 0; i < 2; i++) {
dealer.dealCard(player);
dealer.dealCard(dealer);
}
dealer.show();
if (player.play(dealer)) {
dealer.play(dealer);
showJudge();
}
}
public void showJudge() {
dealer.show();
player.show();
Player winner = judgeWinner();
System.out.println("----------");
if (winner == player) {
System.out.println("You are the winner.");
} else if (winner == dealer) {
System.out.println("It is your loss.");
} else {
System.out.println("It is a draw.");
}
}
public Player judgeWinner() {
if (player.isBust()) {
return dealer;
} else if (dealer.isBust()) {
return player;
} else if (player.isBlackJack() && !dealer.isBlackJack()) {
return player;
} else if (dealer.isBlackJack() && !player.isBlackJack()) {
return dealer;
}
int diff = player.calcScore() - dealer.calcScore();
if (diff > 0) {
return player;
} else if (diff < 0) {
return dealer;
} else {
return null;
}
}
public static void main(String[] args) {
BlackJack blackjack = new BlackJack();
while (true) {
blackjack.play();
blackjack.player.play(null);
}
}
}
Player.java
import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;
abstract public class Player {
public final String name;
protected final List<Card> cards = new ArrayList<Card>();
protected boolean stand = false;
public Player() {
this("Player");
}
public Player(String name) {
this.name = name;
}
public void reset() {
cards.clear();
stand = false;
}
public void holdCard(Card card) {
cards.add(card);
}
abstract boolean play(CardDealer dealer);
public int calcScore() {
int score = 0;
boolean hasAce = false;
for (Card card: cards) {
score += card.rank < 10 ? card.rank : 10;
if (card.rank == 1) {
hasAce = true;
}
}
if (score <= 11 && hasAce) {
score += 10;
}
return score;
}
public boolean isBlackJack() {
return cards.size() == 2 && calcScore() == 21;
}
public boolean isBust() {
return calcScore() > 21;
}
public void show() {
System.out.println("----------");
showCards();
System.out.println(name + "'s score: " + calcScore());
}
public void showCards() {
System.out.println(name + "'s card: " + cards.stream().map(Object::toString).collect(Collectors.joining(", ")));
}
}
CUIPlayer.java
import java.util.Scanner;
public class CUIPlayer extends Player {
private Scanner sc = new Scanner(System.in);
public boolean play(CardDealer dealer) {
while (!isBust() || dealer == null) {
if (!stand) {
show();
}
System.out.println("----------");
System.out.println("Please enter a command.");
System.out.println(" q: quit");
System.out.println(" r: restart");
if (!stand && dealer != null) {
System.out.println(" h: hit");
System.out.println(" s: stand");
}
System.out.print("? ");
String inputStr = sc.nextLine();
switch (inputStr) {
case "q":
case "quit":
System.out.println("bye.");
sc.close();
System.exit(0);
break;
case "r":
case "reset":
return false;
case "h":
case "hit":
if (!stand && dealer != null) {
dealer.dealCard(this);
}
break;
case "s":
case "stand":
stand = true;
return true;
default:
System.out.println("Unsupported command.");
break;
}
}
stand = true;
return true;
}
}
Dealer.java
public class Dealer extends Player implements CardDealer {
private final Deck deck;
public Dealer() {
this(new Deck());
}
public Dealer(Deck deck) {
super("Dealer");
this.deck = deck;
}
public void dealCard(Player player) {
player.holdCard(deck.drowCard());
}
public boolean play(CardDealer dealer) {
while (calcScore() < 17) {
dealer.dealCard(this);
}
stand = true;
return true;
}
@Override
public void show() {
if (stand || cards.size() != 2) {
super.show();
} else {
System.out.println("----------");
cards.get(1).faceDown();
showCards();
cards.get(1).faceUp();
}
}
}
CardDealer.java
public interface CardDealer {
public void dealCard(Player player);
}
Deck.java
import java.util.ArrayList;
import java.util.Collections;
public class Deck {
private final ArrayList<Card> cards = new ArrayList<Card>();
public Deck() {
reset();
}
void reset() {
cards.clear();
for (Suit suit: Suit.values()) {
for (int rank = 1; rank <= 13; rank++) {
cards.add(new Card(suit, rank));
}
}
shuffle();
}
public void shuffle() {
Collections.shuffle(cards);
}
public Card drowCard() {
if (cards.size() == 0) {
reset();
}
return cards.remove(0);
}
}
Card.java
enum Suit {
SPADE, CLOBBER, HEART, DIAMOND;
}
public class Card {
public static String[] RANK = {
"", "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"
};
public final Suit suit;
public final int rank;
private boolean visible;
public Card(Suit suit, int rank) {
this.suit = suit;
this.rank = rank;
faceUp();
}
public void faceUp() {
this.visible = true;
}
public void faceDown() {
this.visible = false;
}
@Override
public String toString() {
if (visible) {
return suit.name() + ' ' + RANK[rank];
} else {
return "???";
}
}
}
Recommended Posts