Блэкджек на Java

Итак, это игра в блэкджек, любые отзывы или советы о том, что мне следует удалить из кода, который не нужен, очень ценятся.

Примечание: некоторые имена классов или переменных на шведском языке, но я думаю, это не должно мешать пониманию кода.

Blackjack.java

import java.util.Scanner;

class Card {
    private final Face face;

    private final Suit suit;

    public Card(Face face, Suit suit) {
        this.face = face;
        this.suit = suit;
    }

    public Face getFace() {
        return face;
    }
    public Suit getSuit() {
        return suit;
    }

    @Override
    public String toString() {
        return face + " of " + suit;
    }
}

enum Face {
    Ace(11), Deuce(2), Three(3), Four(4), Five(5), Six(6), Seven(7), Eight(8), Nine(9), Ten(10), Jack(10), Queen(10), King(10);

    private final int value;

    private Face(int value) {
        this.value = value;
    }
    
    public int getValue() {
        return value;
    }
}

enum Suit {
    hearts, spades, diamonds, clubs;
}

public class BlackJack {
    public static void main(String[] args) {

        int wins = 0;
        int losses = 0;

        Scanner scanner = new Scanner(System.in);
        String input;
        
        //Clear Terminal from file paths
        System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");
        
        //Start loop
        do {

            //Clear Terminal from last game
            System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");System.out.println(" ");

            //Create players, shuffle deck and turn gameOver off
            Player player = new Player("You");
            Player dealer = new Player("Dealer");
            Deck deck = new Deck();
            deck.shuffle();
            boolean gameOver = false;

            //Get cards for player
            player.addCard(deck.draw());
            player.addCard(deck.draw());
            System.out.print(player.getHandAsString(false));
            System.out.println("Total: " + player.getHandSum());
            System.out.println("");System.out.println("");

            //Get cards for dealer
            dealer.addCard(deck.draw());
            dealer.addCard(deck.draw());

            

            //Player turn
            do {
                if (player.getHandSum() == 21) {
                    System.out.println("Super lucky Blackjack! You win.");
                    wins = wins + 1;
                    gameOver = true;
                    break;
                }
                if (player.getHandSum() > 21) {
                    System.out.println("Super unlucky! You lost.");
                    losses = losses + 1;
                    gameOver = true;
                    break;
                }

                System.out.println("");System.out.println("");
                System.out.println("Draw or stay?");
                do {
                    input = scanner.nextLine();
                } while (!input.equalsIgnoreCase("Draw") && !input.equalsIgnoreCase("Stay"));

                //Draw
                if (input.equalsIgnoreCase("Draw")) {
                    player.addCard(deck.draw());
                    System.out.println("");
                    System.out.print(player.getHandAsString(false));
                    System.out.println("Total: " + player.getHandSum());
                    System.out.println("");System.out.println("");
                    if (player.getHandSum() == 21) {
                        System.out.println("Blackjack! You win.");
                        wins = wins + 1;
                        gameOver = true;
                    }
                    if (player.getHandSum() > 21) {
                        System.out.println("You busted with " + player.getHandSum() + " in your hand. Dealer wins!");
                        losses = losses + 1;
                        gameOver = true;
                    }
                }
                //Stay
                if (input.equalsIgnoreCase("stay")) {
                    System.out.println("You have chosen to stay. Your hand: " + player.getHandSum());
                }
            } while (input.equalsIgnoreCase("Draw") && !gameOver);

            //Dealer turn
            if (!gameOver) {
                System.out.println("");System.out.println("");System.out.println("");System.out.println("");System.out.println("");
                System.out.println("________________________________________________________________________");
                System.out.println("Dealers turn");
                System.out.println("________________________________________________________________________");
                
                System.out.println("");
                System.out.print(dealer.getHandAsString(false));
                
                System.out.println(dealer.getHandSum());
                System.out.println("");System.out.println(""); 

                if (dealer.getHandSum() == 21) {
                    System.out.println("Blackjack! Dealer won.");
                    losses = losses + 1;
                    gameOver = true;
                }
            }
            while (!gameOver) {
                if (dealer.getHandSum() <= 17) {
                    //Draw card
                    dealer.addCard(deck.draw());
                    System.out.println(dealer.getVem() + " drew another card");
                    System.out.println("");
                    System.out.print(dealer.getHandAsString(false));
                    System.out.println(dealer.getHandSum());
                    System.out.println("");System.out.println(""); 
                    
                    if (dealer.getHandSum() == 17) {
                        if (player.getHandSum() == 17) {
                            System.out.println("Dealer won.");
                            losses = losses + 1;
                            gameOver = true;
                        }
                    }

                    if (dealer.getHandSum() == 18) {
                        if (player.getHandSum() == 18) {
                            System.out.println("Dealer won.");
                            losses = losses + 1;
                            gameOver = true;
                        }
                    }

                    if (dealer.getHandSum() == 19) {
                        if (player.getHandSum() == 19) {
                            System.out.println("Dealer won.");
                            losses = losses + 1;
                            gameOver = true;
                        }
                    }
                    
                    if (dealer.getHandSum() == 20) {
                        if (player.getHandSum() == 20) {
                            System.out.println("It's a draw!");
                            gameOver = true;
                        }
                    }

                    if (dealer.getHandSum() == 21) {
                        System.out.println("Blackjack! Dealer won.");
                        losses = losses + 1;
                        gameOver = true;
                    }
                    if (dealer.getHandSum() > 21) {
                        System.out.println("Dealer busted with " + dealer.getHandSum() + " in their hand. You win!");
                        wins = wins + 1;
                        gameOver = true;
                    }

                } else {
                    //Stay
                    System.out.println("Dealer chose to stay!");
                    System.out.println("");
                    int totalDealerSum = dealer.getHandSum();
                    int totalPlayerSum = player.getHandSum();

                    if (totalDealerSum > totalPlayerSum) {
                        System.out.println("Both players decided to stay. The Dealer won with a total of " + totalDealerSum + " in their hand.");
                        losses = losses + 1;
                    } else {
                        System.out.println("Both players decided to stay. You win with a total of " + totalPlayerSum + " in your hand.");
                        wins = wins + 1;
                    }
                    gameOver = true;
                }
            }

            //New game? And Score
            System.out.println("");System.out.println("");System.out.println("");
            
            if(wins==1 && losses==0){
                System.out.println("You have won " + wins + " time and lost " + losses + " times.");
            }
            if(wins==0 && losses==1){
                System.out.println("You have won " + wins + " times and lost " + losses + " time.");
            }
            
            if(wins>1 && losses>1){
                System.out.println("You have won " + wins + " times and lost " + losses + " times.");
            }
            if(wins==0 && losses>1){
                System.out.println("You have won " + wins + " times and lost " + losses + " times.");
            }
            if(wins>1 && losses==0){
                System.out.println("You have won " + wins + " times and lost " + losses + " times.");
            }

            if(wins>1 && losses==1){
                System.out.println("You have won " + wins + " times and lost " + losses + " time.");
            }
            if(wins==1 && losses==1){
                System.out.println("You have won " + wins + " time and lost " + losses + " time.");
            }
            if(wins==1 && losses>1){
                System.out.println("You have won " + wins + " time and lost " + losses + " times.");
            }

            System.out.println("");
            System.out.println("Play again?");
            do {
                input = scanner.nextLine();
            } while (!input.equalsIgnoreCase("Yes") && !input.equalsIgnoreCase("No"));
            

        } while (input.equalsIgnoreCase("Yes"));
        
        scanner.close();
    }
}

Deck.java

import java.util.ArrayList;
import java.util.Collections;

public class Deck {

    private final ArrayList<Card> cards;

    public Deck() {
        cards = new ArrayList<Card>();
        // populate deck with cards
        for (Suit suit : Suit.values()) {
            for (Face face : Face.values()) {
                cards.add(new Card(face, suit));
            }
        }
    }

    public void shuffle() {
        Collections.shuffle(cards);
    }

    public Card draw() {
        return cards.remove(0);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < cards.size(); i++) {
            sb.append(i + 1);
            sb.append("https://codereview.stackexchange.com/");
            sb.append(cards.size());
            sb.append(' ');
            sb.append(cards.get(i));
            sb.append('n');
        }
        return sb.toString();
    }
}

Player.java

import java.util.ArrayList;

//Player class
public class Player {

    private final String vem;

    private final ArrayList<Card> hand;

    public Player(String vem) {
        this.vem = vem;
        this.hand = new ArrayList<Card>();
    }

    public String getVem() {
        return vem;
    }

    public void addCard(Card card) {
        hand.add(card);
    }

    public int getHandSum() {
        int handSum = 0;
        for (Card card : hand) {
            handSum += card.getFace().getValue();
        }
        return handSum;
    }

    public String getHandAsString(boolean b) {
        StringBuilder sb = new StringBuilder();
        sb.append(vem); //'s'
        sb.append('n');
        for (int i = 0; i < hand.size(); i++) {
            if (i == 0 && b) {
                sb.append('n');
            } else {
                sb.append(hand.get(i));
                sb.append('n');
            }
        }
        return sb.toString();
    }
}

Спасибо за любую помощь, советы или отзывы!

1 ответ
1

Хороший проект, ниже представлены мои предложения.

Очистка терминала

Есть более 20 System.out.println(" ") в одну строку, а затем еще раз на несколько строк ниже. Создайте метод очистки терминала и сокращения кода с помощью цикла for. Это также другие способы чтобы очистить терминал.

Дублированный код

  • Запрос ввода от пользователя дублируется более одного раза. Вы можете создать метод для того, который принимает собственный вопрос.
  • Булевы операторы: есть много условий if, которые проверяются только с ==. Использовать && и || в комбинации с <= и >= для уменьшения дублирования кода.

Форматирование с правильным множественным числом

Эта часть:

if(wins==1 && losses==0){
    System.out.println("You have won " + wins + " time and lost " + losses + " times.");
}
if(wins==0 && losses==1){
    System.out.println("You have won " + wins + " times and lost " + losses + " time.");
}

if(wins>1 && losses>1){
    System.out.println("You have won " + wins + " times and lost " + losses + " times.");
}
if(wins==0 && losses>1){
    System.out.println("You have won " + wins + " times and lost " + losses + " times.");
}
if(wins>1 && losses==0){
    System.out.println("You have won " + wins + " times and lost " + losses + " times.");
}

if(wins>1 && losses==1){
    System.out.println("You have won " + wins + " times and lost " + losses + " time.");
}
if(wins==1 && losses==1){
    System.out.println("You have won " + wins + " time and lost " + losses + " time.");
}
if(wins==1 && losses>1){
    System.out.println("You have won " + wins + " time and lost " + losses + " times.");
}

Может быть сокращено до:

String pluralWins = wins == 1 ? "" : "s";
String pluralLosses = losses == 1 ? "" : "s";
System.out.printf("You have won %d time%s and lost %d time%s.%n", wins, pluralWins, losses, pluralLosses);

дизайн

Похоже, что главный метод несет большую ответственность. Оно включает:

  1. Запрос ввода от пользователя
  2. Играя в игру
  3. Обновление счета
  4. Печать вывода на консоль

Это делает BlackJack сложно:

  • Тест: не существует простого способа юнит-тестирования игры, только вручную.
  • Расширить: например, добавив игрока.
  • Повторное использование: повторно использовать непросто BlackJack в другом приложении, где, например, пользователь взаимодействует через сеть.

Чтобы улучшить его, часть шага 2 можно перенести в класс BlackJack. В идеале не должно быть взаимодействия с пользователем в BlackJack класс, только в основном. Это идея:

main method
  initialize score
  while user wants to play
    create a new BlackJack object
    while !blackJack.isGameOver()
      play game
    update score

Объект BlackJack представляет одну игру, а его методы позволяют начать игру и играть в нее.

Таким образом, методы BlackJack могут быть протестированы на единицу, а класс может быть легко использован повторно и расширен.

Именование

Более распространенное название для face (в классе Card) является rank. Название face можно спутать с изображением вверх / вниз.

Спектакль

Метод Player#getHandSum вызывается часто и каждый раз вычисляет сумму, повторяя все карты. Подумайте о том, чтобы кэшировать сумму и обновлять ее только тогда, когда Player#addCard называется.

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *