首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >首次尝试玩Blackjack游戏

首次尝试玩Blackjack游戏
EN

Code Review用户
提问于 2014-04-06 09:02:07
回答 4查看 30K关注 0票数 15

我对这段代码不满意,因为我确信有更好的方法来实现我想要实现的目标。我是一个初学者,我已经用我所知道的日期来完成这个任务。

代码语言:javascript
复制
import java.util.Random;
import java.util.Scanner;


public class SeventySix {

    public static void main(String[] args) {

        Scanner keyboard = new Scanner(System.in);

        //52 Cards, Aces = 11, Picture cards = 10, Ace's cannot be reduced to 1.
        int[] newCard = {2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11};

        //Shuffle. Once per game.
        shuffleArray(newCard);

        //Start BlackJack.
        System.out.println("Welcome to BlackJack!");
        System.out.println();
        System.out.println("You get a " + newCard[0] + " and a " + newCard[1] + ".");
        int playerTotal = newCard[0] + newCard[1];
        System.out.println("Your total is " + playerTotal + ".");
        System.out.println();

        //Player can get blackjack/bust in the 1st deal. - awaiting betting system (enhanced bets for blackjack in first round)
        if (playerTotal == 21){
            System.out.println("Blackjack, you win.");
            System.exit(0);
        }
        if (playerTotal > 21){
            System.out.println("Bust, You lose.");
            System.exit(0);
        }
        // Dealer cards
        System.out.println("The dealer has a " + newCard[2] + " showing, and a hidden card.");
        int dealerTotal = newCard[2] + newCard[3];
        if (dealerTotal > 21){     //Dealer bust check.
            System.out.println();
            System.out.println("Dealers total is " + dealerTotal + ".");
            System.out.println("Dealer is bust, you win!");
            System.exit(0);
        }
        if (dealerTotal == 21){    //Dealer blackjack check.
            System.out.println();
            System.out.println("Dealer reveals his second card: " + newCard[3] + ".");
            System.out.println("Dealers total is " + dealerTotal + ".");
            System.out.println();
            System.out.println("Dealer has BlackJack, you lose.");
            System.exit(0);
        }
        System.out.println("His total is hidden.");
        System.out.println();


        // Hit or Stay for player.
        System.out.print("Would you like to \"hit\" or \"stay\"? ");
        String hitStay = keyboard.next();
        System.out.println();

        //cc = card count
        int cc = 4; 
        if (hitStay.equalsIgnoreCase("hit")){
            // While loop to ensure different cards & multiple "hits".
            while (playerTotal < 21 && hitStay.equalsIgnoreCase("hit")){
                if (hitStay.equalsIgnoreCase("hit")){
                    System.out.println("You drew a " + newCard[cc] + ".");
                    playerTotal = playerTotal + newCard[cc];
                    System.out.println("Your total is " + playerTotal + ".");
                    System.out.println();
                    cc++;        //Adds 1 to ensure next card is different.
                    // Bust & Blackjack check.
                    if (playerTotal > 21){
                        System.out.println("You are bust, You lose.");
                        System.exit(0);
                    }
                    if (playerTotal == 21){
                        System.out.println("Blackjack, you win.");
                        System.exit(0);
                    }
                    System.out.print("Would you like to \"hit\" or \"stay\"? ");
                    hitStay = keyboard.next();
                    System.out.println();
                }
            }        
        }

        // Dealers turn, only if Round 1 didn't end in bust/blackjack.
        keyboard.close();
        System.out.println("Ok dealers turn.");
        System.out.println("His hidden card was a " + newCard[3] + "."); // reveal hidden from round one.

        cc++; // Pretty sure its not needed.
        while (dealerTotal < 16){ // Dealer will stay on 16+ and hit if below.
            System.out.println();
            System.out.println("Dealer chooses to hit.");
            System.out.println("He draws a " + newCard[cc] + ".");
            cc++;
            dealerTotal = dealerTotal + newCard[cc];
            System.out.println();
            System.out.println("His total is " + dealerTotal);
            // bust check - no need for blackjack check due to final win sequence
            if (dealerTotal > 21){
                System.out.println();
                System.out.println("Dealer is bust, YOU WIN!");
                System.exit(0);
            }
            // stay condition.
            if (dealerTotal < 21 && dealerTotal > 16){
                System.out.println();
                System.out.println("Dealer Stays.");
            }
        }

        // final win sequence.
        System.out.println();
        System.out.println("Dealer total is " + dealerTotal);
        System.out.println("Your total is " + playerTotal);
        System.out.println();

        if (dealerTotal > playerTotal){
            System.out.println("Dealer wins.");
        } 
        if (dealerTotal == playerTotal){
            System.out.println("You both draw.");
        }
        if (dealerTotal < playerTotal){
            System.out.println("You win.");
        }
    }

    static void shuffleArray(int[] deckCards){

        /**
         * This code is obtained from the internet and is not my own though process
         * I need to understand it before I will be happy using it.
         * I'll have a try at explaining this, please correct me if I suckarino.
         * deckCards is a placeholder for the array I chose to use.
         * i = the length of the array which is 52, -1 would be 51.
         * i will be greater than 0 until the i-- completely loops it down to 0.
         * index is a random number between 1 & 52.
         * a is a random number in the array.
         * deckCards[i] is replaced with a; 
         * essentially shuffling 1 card in the array, this happens 51 times?
         */

        Random rnd = new Random();
        for (int i = deckCards.length - 1; i > 0; i--)
        {
            int index = rnd.nextInt(i + 1);
            // Swap
            int a = deckCards[index];
            deckCards[index] = deckCards[i];
            deckCards[i] = a;
        }
    }
}

我试着让这些评论在某种程度上可以理解。

EN

回答 4

Code Review用户

回答已采纳

发布于 2014-04-06 09:34:04

您应该使整个应用程序更加面向对象。一个很好的起点是将一副牌和相关功能移到其他类中。

下面是从StackOverflow问题中窃取的一个甲板的实现。注意,还有一个Card对象。

代码语言:javascript
复制
public class DeckOfCards {
  private Card cards[];

  public DeckOfCards() {
    this.cards = new Card[52];
    for (int i = 0; i < 52; i++) {
        Card card = new Card(...); //Instantiate a Card
        this.cards[i] = card; //Adding card to the Deck
    }
  }
}

还可以考虑使用enums作为套装和跟踪卡值的方法。搜索谷歌的Cark排名模式将有助于这一点。

您有很多多行打印语句,这些语句可能都可以结合在一起;

代码语言:javascript
复制
System.out.println();
System.out.println("Dealer total is " + dealerTotal);
System.out.println("Your total is " + playerTotal);
System.out.println();

可能是;

代码语言:javascript
复制
System.out.println(
  String.format("\nDealer total is %s \nYour total is %s \n", dealerTotal, playerTotal)
);

为了节省复杂性,这些人应该是else ifs;

代码语言:javascript
复制
if (dealerTotal > playerTotal){
    System.out.println("Dealer wins.");
} 
else if (dealerTotal == playerTotal){
    System.out.println("You both draw.");
}
else {
    System.out.println("You win.");
}

最后,您的代码不是很干的。您需要在不同的方法中使用更多的功能,以防止重复使用。一个很好的例子是,您有多个win序列。您的赢/输条件应该会导致调用一个win/lose方法,该方法执行适当的序列。

此外,Blackjack是一个重复的游戏,第二轮与第一轮相同,您的代码只是第二次重复相同的操作。同样,应该将其移到方法中。

票数 15
EN

Code Review用户

发布于 2014-04-06 10:49:54

我只想指出,虽然卡片将更好地表示为对象而不是ints,而且程序组织和流程有点混乱,但是您对洗牌算法的选择是很好的。

费舍-耶茨洗牌是一种简单而不偏不倚的方法,可以将数组元素的顺序随机化,并且您有一个教科书上的实现。即使你没有自己写代码,我认为你应该因为选择正确的代码而获得荣誉。

编辑:因为您在shuffleArray()…中询问了评论的有效性

这就是你所写的,忽略了最初的噪音:

  • deckCards是我选择使用的数组的占位符。
  • i =数组的长度,为52,-1将为51。
  • i将大于0,直到i--将其完全循环到0。
  • index是介于1和52之间的随机数。
  • a是数组中的一个随机数。
  • deckCards[i]代之以a

基本上洗牌1卡在数组中,这会发生51次吗?

你的词汇表略有偏离,关于i下降到0,而index在1到52之间的评论是不准确的。

  • deckCards是对输入数组的引用。此函数调整其元素的位置。
  • i最初是数组最后一个元素的索引。
  • i迭代到1。
  • index是介于0和i之间的一个随机数,包含在内。
  • a是数组的随机元素。
  • deckCards[i]a交换;

基本上洗牌1卡在数组中,这会发生51次吗?

然而,这是一个缺乏洞察力的,机械的代码描述。更好的意见是:

对于数组中的每个元素(第一个除外),从末尾开始,以一致的概率选择任何先前的元素(或其本身),并交换它们。这种技术是无偏的。例如,考虑一下第一个循环在洗牌52张牌时会发生什么.甲板上的每一张牌都同样有可能占据deckCards[51]的位置。对于最后一个元素deckCards[51],重复这个过程--从剩下的51张卡牌中随机抽取,来填充它的最后一个元素deckCards[50],等等。

票数 11
EN

Code Review用户

发布于 2014-04-07 03:49:51

代码中有一个小错误:

Aces只有11,但不是1。这意味着玩家(或经销商)可能只需要两张牌就会崩溃。

假设他们只有Aces,那么这将是一个半身像。我会加上一张支票,看看这名球员是否正在崩溃,但其中一张牌是作为一张Ace牌发行的。甚至可能创建一个布尔值,PlayerHasAce

伪码:

代码语言:javascript
复制
If they bust, and PlayerHasAce is TRUE;
    minus 10 from the total;
    are they still busting without additional aces? 
    No? Good! They can continue playing. 

不过,您只需要确保每个Ace只设置一次布尔值,而不是在同一只手中重复。

票数 11
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

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

复制
相关文章

相似问题

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