Post-scriptum: @ k73i55no5 a commenté une meilleure proposition de refactoring. Merci beaucoup. Voir les commentaires pour plus de détails. Refactoriser uniquement la structure des membres de la classe (structure). Nous n'avons pas commencé à refactoriser le code de traitement (intérieur, implémentation). (Ajouté jusqu'à ici)
J'ai vu le code source de "Make Blackjack with Java" posté par @ yuta-yoshinaga. J'ai écrit un commentaire un peu amer parce que l'encapsulation a été détruite par tous les setters et getters, et certaines classes ne fonctionnaient pas. C'est juste un commentaire, alors je l'ai refactorisé à ma manière. Il y a encore quelques points à revoir, mais j'espère que vous le trouverez utile.
Ajoutez un diagramme de séquence.
@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