Итак, это игра в блэкджек, любые отзывы или советы о том, что мне следует удалить из кода, который не нужен, очень ценятся.
Примечание: некоторые имена классов или переменных на шведском языке, но я думаю, это не должно мешать пониманию кода.
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 ответ
Хороший проект, ниже представлены мои предложения.
Очистка терминала
Есть более 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);
дизайн
Похоже, что главный метод несет большую ответственность. Оно включает:
- Запрос ввода от пользователя
- Играя в игру
- Обновление счета
- Печать вывода на консоль
Это делает 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
называется.