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