首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >第二次尝试黑杰克的比赛

第二次尝试黑杰克的比赛
EN

Code Review用户
提问于 2015-06-04 22:21:07
回答 1查看 2.2K关注 0票数 4

我昨天发了关于我的首次尝试玩Blackjack游戏的帖子。在收到了许多有用的建议之后,我尽了最大的努力来修复我的代码。我想知道你会怎么想第二轮!

编辑:如果你有两张相同的卡片,我也想实现一只手分开的能力。我的User类已经有了一个拆分方法,它添加了另一只手;您认为添加此特性的最佳方法是什么?

代码语言:javascript
复制
package Blackjack;

class Card {
private final int rank;
private final int suit;
private static String[] ranks = { "Joker", "Ace", "Two", "Three", "Four",
        "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen",
        "King" };
private static String[] suits = { "Clubs", "Diamonds", "Hearts", "Spades" };

Card(int suit, int values) {
    this.rank = values;
    this.suit = suit;
}

public String toString() {
    return ranks[rank] + " of " + suits[suit];
}

public int getRank() {
    return rank;
}

public int getSuit() {
    return suit;
}

public int getValue() {
    int value=0;
    if (rank > 10) {
        value = 10;
    } else if (rank == 1) {
        value = 11;
    } else {
        value = rank;
    }
    return value;
}
}

甲板

代码语言:javascript
复制
package Blackjack;

import java.util.ArrayList;
import java.util.Random;

class Deck {
private ArrayList<Card> deck;

Deck() {
    deck = new ArrayList<Card>();
    for (int i = 0; i < 4; i++) {
        for (int j = 1; j <= 13; j++) {
            deck.add(new Card(i, j));
        }
    }
}

public void shuffle() {
    Random random = new Random();
    Card temp;
    for (int i = 0; i < 200; i++) {
        int index1 = random.nextInt(deck.size() - 1);
        int index2 = random.nextInt(deck.size() - 1);
        temp = deck.get(index2);
        deck.set(index2, deck.get(index1));
        deck.set(index1, temp);
    }
}

public Card drawCard() {
    return deck.remove(0);
}
}

代码语言:javascript
复制
package Blackjack;

import java.util.ArrayList;
import java.util.Arrays;

class Hand {
private ArrayList<Card> hand;
private int handValue;
private int aceCounter;

Hand(Deck deck) {
    hand = new ArrayList<>();
    aceCounter = 0;
    handValue = 0;
    for (int i = 0; i < 2; i++) {
        hand.add(deck.drawCard());
    }
    Card[] aHand = new Card[]{};
    aHand = hand.toArray(aHand);
    for (int i = 0; i < aHand.length; i++) {
        handValue += aHand[i].getValue();
        if (aHand[i].getValue() == 11) {
            aceCounter++;
        }
        while (aceCounter > 0 && handValue > 21) {
            handValue -= 10;
            aceCounter--;
        }
    }
}

public void Hit(Deck deck) {
    hand.add(deck.drawCard());
    Card[] aHand = new Card[]{};
    aHand = hand.toArray(aHand);
    handValue = 0;
    aceCounter=0;
    for (int i = 0; i < aHand.length; i++) {
        handValue += aHand[i].getValue();
        if (aHand[i].getValue() == 11) {
            aceCounter++;
        }
        while (aceCounter > 0 && handValue > 21) {
            handValue -= 10;
            aceCounter--;
        }
    }
}

public int getHandSize() {
    return hand.size();
}

public int getHandValue() {
    return handValue;
}

public Card getCard(int cardnum) {
    Card[] aHand = new Card[]{};
    aHand = hand.toArray(aHand);
    return aHand[cardnum-1];
}

public String toString(){
    String hands ="";
    Card[] aHand = new Card[]{};
    aHand = hand.toArray(aHand);
    for(int i=0; i<aHand.length-1; i++) {
        hands = hands + aHand[i].toString() + ", ";
    }
    hands = hands + aHand[aHand.length-1].toString();
    return hands;
}   
}

播放器

代码语言:javascript
复制
package Blackjack;

import java.util.ArrayList;
import java.util.Arrays;

class Player {
ArrayList<Hand> hand;

Player() {
    hand = new ArrayList<Hand>();
}

public boolean hasBlackJack(int handnum) {
    Hand[] aHand = new Hand[] {};
    aHand = hand.toArray(aHand);
    return (aHand[handnum-1].getHandSize() == 2 && aHand[handnum-1].getHandValue() == 21);
}

public boolean hasBusted() {
    Hand[] aHand = new Hand[] {};
    aHand = hand.toArray(aHand);
    return (aHand[0].getHandValue() > 21);
}

public Hand getHand(int handnum) {
    Hand[] aHand = new Hand[] {};
    aHand = hand.toArray(aHand);
    return aHand[handnum-1];
}

public void getNewHand(Deck deck) {
    hand.clear();
    Hand myHand = new Hand(deck);
    hand.add(myHand);
}
}

用户

代码语言:javascript
复制
package Blackjack;

import java.util.ArrayList;
import java.util.Arrays;

class User extends Player {
private int cash;
private int bet;
private String name;

User() {
}

public int getCash() {
    return cash;
}

public int getBet() {
    return bet;
}

public String getName() {
    return name;
}

public void setCash(int money) {
    cash = money;
}

public void setBet(int money) {
    bet = money;
}

public void setName(String username) {
    name = username;
}

public void split(Deck deck) {
    Hand hand2 = new Hand(deck);
    hand.add(hand2);
}

public void doubleDown() {
    cash=cash-bet;
    bet=2*bet;
}

public void win() {
    cash=cash+2*bet;
}
public void push() {
    cash=cash+bet;
}
public void blackJack() {
    cash=cash+3*bet;
}

public boolean hasSplit() {
    return hand.size()==2;
}

public boolean hasFiveCardTrick(int handnum) {
    Hand[] aHand = new Hand[]{};
    aHand = hand.toArray(aHand);
    Hand myHand = aHand[handnum-1];
    return(myHand.getHandSize()==5 && myHand.getHandValue()<21);
}

}

经销商

代码语言:javascript
复制
package Blackjack;

import java.util.ArrayList;
import java.util.Arrays;

class Dealer extends Player {

Dealer() {
}

public void showFirstCard() {
    Card[] firstCard = new Card[] {};
    firstCard = hand.toArray(firstCard);
    System.out.println("[" + firstCard[0] + "]");
}

public boolean wantsToHit() {
    Hand[] aHand = new Hand[]{};
    aHand = hand.toArray(aHand);
    return aHand[0].getHandValue()<17;
}

public void showHand() {
    System.out.println(hand);
}

public void takeTurn(Deck deck) {
    Hand[] aHand = new Hand[]{};
    aHand = hand.toArray(aHand);
    while (wantsToHit()) {
        System.out.println("The dealer hits.");
        aHand[0].Hit(deck);
        if (hasBusted()) {
            break;
        }
    }
    System.out.println("The dealer stands.");
}
}

输入

代码语言:javascript
复制
package Blackjack;

import java.util.Scanner;

class Input {
private Output outputter;
Input(Output outputs) {
    outputs = outputter;
}

public String getName() {
    Scanner scan = new Scanner(System.in);
    String name = scan.nextLine();
    return name;
}

public int getCash() {
    Scanner money = new Scanner(System.in);
    int cash = money.nextInt();
    return cash;
}

public int getBet(int cash) {
    Scanner sc = new Scanner(System.in);
    int bet = sc.nextInt();
        while (bet > cash) {
            outputter.cannotBet();
            outputter.askBet();
            bet=sc.nextInt();
        }
    return bet;
}

public boolean choiceIsYes() {
    Scanner doubledown = new Scanner(System.in);
    String doubled = doubledown.nextLine();
    while (!isyesorno(doubled)) {
        outputter.yesOrNo();
        doubled = doubledown.nextLine();
    }
    return doubled.equals("yes");
}

public boolean isyesorno(String answer) {
    return (answer.equals("yes") || answer.equals("no"));
}

public boolean choiceisHit() {
    Scanner hitter = new Scanner(System.in);
    String hit = hitter.nextLine();
    while(!ishitorstand(hit)) {
        outputter.yesOrNo();
        hit = hitter.nextLine();
    }
    return hit.equals("hit");
}

public boolean ishitorstand(String hit) {
    return (hit.equals("hit") || hit.equals("stand"));
}

}

输出

代码语言:javascript
复制
package Blackjack;

class Output {

Output(){
}

public void askName() {
    System.out.println("Hi! What is your name?");
}

public void greeting(String name) {
    System.out.println("Hello, "+name+", let's play some Blackjack!");
}

public void askCash() {
    System.out.println("How much cash do you want to start with?");
}

public void tellCashStart(int cash) {
    System.out.println("You start with cash: "+cash);
}

public void showCash(int cash) {
    System.out.println("Cash: "+cash);
}

public void cannotBet() {
    System.out.println("You cannot bet more money than you have!");
}

public void askBet() {
    System.out.println("How much do you wish to bet?");
}

public void showBet(int bet) {
    System.out.println("Money on the table: " + bet);
}

public void showHand(User user) {
    System.out.println("Here is your hand: ");
    System.out.println(user.getHand(1));
}

public void showDealerFirstCard(Dealer dealer) {
    System.out.println("The dealer is showing:");
    Hand hand = dealer.getHand(1);
    System.out.println(hand.getCard(1));
}

public void showDealerHand(Dealer dealer) {
    System.out.println("Here is the dealer's hand:");
    System.out.println(dealer.getHand(1));
}

public void askDoubleDown() {
    System.out.println("Would you like to double down?");
}

public void yesOrNo() {
    System.out.println("Please answer yes or no.");
}

public void hasDoubledDown() {
    System.out.println("You have opted to double down!");
}

public void insurance() {
    System.out.println("The dealer is showing ace! Would you like insurance?");
}

public void hasInsurance() {
    System.out.println("You have opted for insurance!");
}

public void split() {
    System.out.println("You have two of the same card- would you like to split?");
}

public void hasSplit() {
    System.out.println("You have opted to split!");
}

public void splitHands(User user) {
    System.out.println("Here are your hands:");
    System.out.println(user.getHand(1));
    System.out.println(user.getHand(2));
}

public void dealerBlackJack() {
    System.out.println("The dealer has Blackjack!");
}

public void userBlackJack() {
    System.out.println("You have BlackJack!");
    System.out.println("You win 2x your money back!");
}

public void win() {
    System.out.println("Congratulations, you win!");
}

public void lose() {
    System.out.println("Sorry, you lose!");
}

public void push() {
    System.out.println("It's a push!");
    System.out.println("You get your money back.");
}

public void hitOrStand() {
    System.out.println("Would you like to hit or stand?");
}

public void enterHitorStand() {
    System.out.println("Please enter hit or stand.");
}

public void playAgain() {
    System.out.println("Would you like to play again?");
}

public void cashTotal(int cash) {
    System.out.println("Your cash total is: "+cash);
    System.out.println("Enjoy your winnings!");
}

public void cashTotalZero(int cash) {
    System.out.println("Your total cash is: "+cash);
    System.out.println("You ran out of cash!");
}

public void hasFiveCardTrick() {
    System.out.println("You have a five card trick!");
}

public void winInsurance() {
    System.out.println("The dealer does have Blackjack!");
    System.out.println("You have won your insurance.");
}

public void loseInsurance() {
    System.out.println("Sorry, the dealer does not have Blackjack.");
    System.out.println("You have lost your insurance");
}

public void busted() {
    System.out.println("You busted!");
}

public void dealerBusted() {
    System.out.println("The dealer busted!");
}
}

BlackJack对策

代码语言:javascript
复制
package Blackjack;

public class BlackJackGame {

public static void main(String[] args) {
    Output output = new Output();
    Input input = new Input(output);
    output.askName();
    output.greeting(input.getName());
    output.askCash();
    User user = new User();
    Dealer dealer = new Dealer();
    user.setCash(input.getCash());
    while (user.getCash() > 0) {
        Deck deck = new Deck();
        deck.shuffle();
        user.getNewHand(deck);
        dealer.getNewHand(deck);
        output.showCash(user.getCash());
        output.askBet();
        user.setBet(input.getBet(user.getCash()));
        user.setCash(user.getCash() - user.getBet());
        output.showCash(user.getCash());
        output.showBet(user.getBet());
        output.showHand(user);
        output.showDealerFirstCard(dealer);
        if (dealer.getHand(1).getCard(1).getRank() == 1) {
            output.insurance();
            if (input.choiceIsYes()) {
                if (dealer.hasBlackJack(1)) {
                    output.winInsurance();
                    user.win();
                    output.showCash(user.getCash());
                } else {
                    output.loseInsurance();
                    output.showCash(user.getCash());
                }
            }
        }
        if (user.hasBlackJack(1) && dealer.hasBlackJack(1)) {
            output.userBlackJack();
            output.dealerBlackJack();
            output.push();
            user.push();
        } else if (user.hasBlackJack(1)) {
            user.blackJack();
            output.userBlackJack();
            output.win();
        } else if (dealer.hasBlackJack(1)) {
            output.dealerBlackJack();
            output.lose();
        } else {
            if (2 * user.getBet() < user.getCash()) {
                output.askDoubleDown();
                if (input.choiceIsYes()) {
                    user.doubleDown();
                    output.showCash(user.getCash());
                    output.showBet(user.getBet());
                }
            }
            output.hitOrStand();
            while (input.choiceisHit()) {
                user.getHand(1).Hit(deck);
                output.showHand(user);
                output.hitOrStand();
                if (user.hasBusted()) {
                    output.busted();
                    output.lose();
                    break;
                }
                if (user.hasFiveCardTrick(1)) {
                    output.hasFiveCardTrick();
                    output.win();
                    user.win();
                    break;
                }
            }
            if(!user.hasBusted()) {
                dealer.takeTurn(deck);
                output.showDealerHand(dealer);
                if (dealer.hasBusted()) {
                    output.dealerBusted();
                    output.win();
                    user.win();
                } else {
                    if ((21 - user.getHand(1).getHandValue()) < (21 - dealer
                            .getHand(1).getHandValue())) {
                        output.win();
                        user.win();
                    }
                    if ((21 - user.getHand(1).getHandValue()) == (21 - dealer
                            .getHand(1).getHandValue())) {
                        output.push();
                        user.push();
                    }
                    if ((21 - user.getHand(1).getHandValue()) > (21 - dealer
                            .getHand(1).getHandValue())) {
                        output.lose();
                    }
                }
            }
        }
        output.showCash(user.getCash());
        output.playAgain();
        if (!input.choiceIsYes()) {
            break;
        }

    }
    if (user.getCash() == 0) {
        output.cashTotalZero(user.getCash());
    }
    output.cashTotal(user.getCash());
}
}
EN

回答 1

Code Review用户

回答已采纳

发布于 2015-06-05 14:40:10

结构

你的结构好多了。有几件事,我会做不同的,但总的来说是好的。

  • Hand并不需要一张牌,只需要一张牌(我认为这更符合逻辑)。
  • 我想你有很多Hands在Player是因为分裂吗?这事儿可以理解。但是您的hasBlackJack等方法只处理第一手的,因此它是无用的。我可能会将这些检查方法直接移到Hand中。
  • 我会让choiceisHit返回一个Action枚举,它可以是HitStaySplit等。这将使以后添加其他操作(双、拆分、投降等)变得容易得多。
  • 您的主要方法太长了,很难找到您感兴趣的部分,这将使您很难更改或扩展它。在开始时,我至少会为一轮黑板创建一个方法,并为设置创建一个方法。

数组和

列表

上一次我注意到了这一点,但是由于您仍然将列表转换为数组,我想您可能不知道如何单独处理列表?

通常--如果你没有充分的理由去做不同的事情--你应该坚持你的收藏。如果是数组,处理数组。如果这是一个列表,处理这个列表。

例如:

代码语言:javascript
复制
for (int i = 0; i < 2; i++) {
    hand.add(deck.drawCard());
}
Card[] aHand = new Card[]{};
aHand = hand.toArray(aHand);
for (int i = 0; i < aHand.length; i++) {
    handValue += aHand[i].getValue();
    if (aHand[i].getValue() == 11) {
        aceCounter++;
    }
    while (aceCounter > 0 && handValue > 21) {
        handValue -= 10;
        aceCounter--;
    }
}

可以在没有这样的数组的情况下重写:

代码语言:javascript
复制
for (int i = 0; i < 2; i++) {
    hand.add(deck.drawCard());
}
for (Card card : hand) {
    handValue += card.getValue();
    if (card.getValue() == 11) {
        aceCounter++;
    }
    while (aceCounter > 0 && handValue > 21) {
        handValue -= 10;
        aceCounter--;
    }
}

就我个人而言,我会动态地处理getHandValue中的值计数,以避免aces的麻烦以及HandHit中的复制(您也可以通过在构造函数中调用Hit两次来避免这种情况)。

您还可以在其他几个地方执行从list到数组的相同转换。例如:

代码语言:javascript
复制
public Card getCard(int cardnum) {
    Card[] aHand = new Card[]{};
    aHand = hand.toArray(aHand);
    return aHand[cardnum-1];
}

可能是这样的:

代码语言:javascript
复制
public Card getCard(int cardnum) {
    return hand.get(cardnum);
}

toStringhasBlackJackhasBusted等方面也是如此。

命名

  • 你的名字并不总是一致的。例如,getNewHand什么也不回,而getHand只回一只手。getNewHand可能应该类似于dealHand
  • choiceIsYes检索用户输入,而isyesorno不检索。我将使用您在这里使用的其他方法的getX命名模式。
  • 始终使用camelCase (参见ishitorstand)。
  • 同样,方法应该以小写字符开头,这样它们就不会与类/构造函数混淆。

Misc

  • drawCard中,您不检查是否还剩一张卡,这将导致空指针异常时,没有。
  • 您仍然有您的shuffle方法,可以用Collections.shuffle(deck);替换。
票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/92703

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档