重复循环,java

时间:2013-11-29 07:12:35

标签: java

我为java编写了一个基本的命令行Blackjack游戏,我在编码时遇到了一个意想不到的问题,这引发了以下问题:在java中结束'action'序列的最佳方法是什么。即我们应该使用do while循环还是应该使用while(boolean)?

我知道我的代码中某处肯定存在逻辑错误,但我找不到它。当我运行代码时,我希望被告知我的手是什么,并被问到我是否想要站立或击中,如下:

Welcome to Blackjack!
Dealer stands on 17
Your current balance is €100
Please enter you bet, between €5 and €25. Your bet must be less than your bank,
and be a multiple of 5: 
5
House holds: ? + 4 of Clubs 
You hold: Jack of Hearts Queen of Hearts 
For a total score of: 20.

Would you like to hit or stand? (h or s): 

但是我收到的这部分打印了两次:

House holds: ? + 4 of Clubs 
You hold: Jack of Hearts Queen of Hearts 
For a total score of: 20.

我认为可能相关的代码部分是

while (play) {
            // Print out the two hands to the console
            System.out.print("House holds: ? + ");
            // The print hand action takes sn array and a boolean, if     false
            // it sets the amount of cards to print for each hand to     the
            // hand length - 1, so on the first round it will show 1 card.
            // If set to true it prints all cards in the hand.
            Blackjack.printHand(dealer, false);
            System.out.println();

            System.out.print("You hold: ");
            Blackjack.printHand(player, true);
            System.out.println();
            System.out.println("For a total score of: "
                    + Blackjack.calculateScore(player) + ".");

            // This checks for Blackjack
            if (Blackjack.blackjack(player, dealer) == 1) {
                System.out.println("Blackjack! Player has won!");
                bank += bet;
                System.out.print("The dealer had ");
                Blackjack.printHand(dealer, true);
                System.out.println();
                done = true;
                break;

            }

            System.out.println();
            System.out.print("Would you like to hit or stand? (h or s): ");

            String hitOrStand = input.nextLine();

我不确定我是否正确使用布尔'play'。如果问题不在本节中,我将在下面包含完整(相当繁琐)的代码。非常感谢你。

import java.util.*;

public class TestBlackjack {
    // Declare and initialise the bank at €100
    static int bank = 100;

    public static void main(String[] args) {
            // Originally the game is not finished
            boolean gameFinished = false;
            boolean play = true;
            // Until game is finished, play a game of Blackjack
            while (gameFinished == false) {
                    // Create a scanner object
                    Scanner input = new Scanner(System.in);
                    boolean done = false;
                    System.out
                                    .println("Welcome to Blackjack!\nDealer stands on 17\nYour current balance is €"
                                                    + bank
                                                    + "\nPlease enter you bet, between €5 and €25. Your bet must be less than your bank,\nand be a multiple of 5: ");

                    int bet = input.nextInt();
                    while (bet > 25 || bet < 5 || bet % 5 != 0 || bet > bank) {
                            System.out
                                            .print("Please re-enter you bet, this must be either 5, 10, 15, 20 or 25\nand be less than €"
                                                            + bank + ": ");
                            bet = input.nextInt();
                    }

                    // Declare and populate a deck array, and declare a hand array for
                    // each player
                    int[] deck = DeckOfCards.deck();
                    int[] player = new int[12];
                    int[] dealer = new int[12];

                    // Start a new game of Blackjack
                    Blackjack.setupNewGame(deck, player, dealer);

                    while (play) {
                            // Print out the two hands to the console
                            System.out.print("House holds: ? + ");
                            // The print hand action takes sn array and a boolean, if false
                            // it sets the amount of cards to print for each hand to the
                            // hand length - 1, so on the first round it will show 1 card.
                            // If set to true it prints all cards in the hand.
                            Blackjack.printHand(dealer, false);
                            System.out.println();

                            System.out.print("You hold: ");
                            Blackjack.printHand(player, true);
                            System.out.println();
                            System.out.println("For a total score of: "
                                            + Blackjack.calculateScore(player) + ".");

                            // This checks for Blackjack
                            if (Blackjack.blackjack(player, dealer) == 1) {
                                    System.out.println("Blackjack! Player has won!");
                                    bank += bet;
                                    System.out.print("The dealer had ");
                                    Blackjack.printHand(dealer, true);
                                    System.out.println();
                                    done = true;
                                    break;

                            }

                            System.out.println();
                            System.out.print("Would you like to hit or stand? (h or s): ");

                            String hitOrStand = input.nextLine();

                            System.out.println();
                            System.out.println();

                            // If the user inputs h or H, it calls the hit method from the
                            // Blackjack class
                            if (hitOrStand.equals("h") || hitOrStand.equals("H")) {
                                    Blackjack.hit(deck, player);

                                    // If the new score for the user is greater than 21, they
                                    // are bust
                                    if (Blackjack.calculateScore(player) > 21) {
                                            System.out.print("You hold: ");
                                            Blackjack.printHand(player, true);
                                            System.out.println();
                                            System.out.println("Your score is: "
                                                            + Blackjack.calculateScore(player)
                                                            + " You are bust.\nHouse wins.");
                                            // Subtract the bet from the bank
                                            bank -= bet;
                                            // Game is done
                                            done = true;
                                            break;
                                    }
                                    // Else, if the user stands, break out of this loop and
                                    // continue the game
                            } else if (hitOrStand.equals("s") || hitOrStand.equals("S")) {
                                    break;
                            }
                    }

                    // If the hit did not bust the user
                    if (!done) {

                            // Automate AI response, to stand on 17
                            Blackjack.finishDealersPlay(deck, dealer);

                            System.out.print("House holds: ");
                            Blackjack.printHand(dealer, true);
                            System.out.println("For a score of "
                                            + Blackjack.calculateScore(dealer));
                            System.out.println();

                            // Call the calculate winnings to see who has won
                            if (Blackjack.calculateWinnings(player, dealer) == 1) {
                                    System.out.println("You win.");
                                    // Update the bank
                                    bank += bet;
                            } else if (Blackjack.calculateWinnings(player, dealer) == 0) {
                                    System.out.println("Push.");
                            } else if (Blackjack.calculateWinnings(player, dealer) == -1) {
                                    System.out.println("House wins.");
                                    bank -= bet;
                            }
                    }

                    // Sends the game back to the beginning of the loop if the player
                    // wants to play again
                    System.out.print("Would you like to play again(y/n)? ");
                    String playAgain = input.nextLine();

                    if (playAgain.equals("y")) {
                            // Place a line in the console before the start of the new game
                            System.out.println();
                            continue;
                    } else {
                            System.out.println("Thanks for playing!");
                            System.exit(0);
                    }

            }

    }

}

class DeckOfCards {

    /*
     * Returns an integer representing a card in the deck. Between shuffles, the
     * same card will never be returned twice
     */
    public static int drawCard(int[] deck) {
            // Assign i a random value between 1 and 52
            int i = (int) (Math.random() * 52);

            // Assign card the value of deck at position i
            int card = deck[i];
            // Update the value of deck at position i to 0, in order to identify
            // that it has been drawn
            deck[i] = -1;

            // While the value drawn for card is 0, run the selection process again
            while (card == -1) {
                    i = (int) (Math.random() * 52);
                    card = deck[i];
            }

            // Return the value for card
            return card;

    }

    /* Shuffle the "deck" of ints */
    public static void shuffle(int[] deck) {
            // Run for the length of the deck array
            for (int i = 0; i < deck.length; i++) {
                    // Generate a random index to use
                    int index = (int) (Math.random() * deck.length);
                    // Declare a holder variable to hold the value of deck at position i
                    int holder = deck[i];
                    // Set the value of deck at position i to deck at the random index
                    deck[i] = deck[index];
                    // Swap the value that was at position i into position index
                    deck[index] = holder;
            }
    }

    /* Creates a "deck" of ints */
    static int[] deck() {
            // Declare and initialise an array
            int[] deck = new int[52];
            for (int i = 0; i < deck.length; i++)
                    deck[i] = i;
            return deck;
    }

}

class Blackjack {

    /*
     * Set up the game: perform a shuffle, "deal" 2 cards to both the dealer and
     * player
     */
    public static void setupNewGame(int[] deck, int[] player, int[] dealer) {

            // Set all values to -1 as 0 is actually equal to the ace of spades
            for (int i = 0; i < player.length; i++) {
                    player[i] = -1;
                    dealer[i] = -1;
            }

            // Shuffle the deck
            DeckOfCards.shuffle(deck);

            // Deal to player, dealer, player and then dealer
            player[0] = DeckOfCards.drawCard(deck);
            dealer[0] = DeckOfCards.drawCard(deck);
            player[1] = DeckOfCards.drawCard(deck);
            dealer[1] = DeckOfCards.drawCard(deck);

    }

    /* Deal another card to the player */
    public static void hit(int[] deck, int[] player) {
            int count = 0;

            // Find the first element with a value of -1
            for (int i = 0; i < player.length; i++) {
                    if (player[i] != -1) {
                            count++;
                    }
            }

            // Assign the value to that element.
            player[count] = DeckOfCards.drawCard(deck);

    }

    /*
     * Takes a hand and a boolean for Parameters, and prints the value and suit
     * of hand
     */
    public static void printHand(int[] hand, boolean isPlayer) {
            String[] suits = { "Spades", "Hearts", "Diamonds", "Clubs" };
            String[] values = { "Ace", "2", "3", "4", "5", "6", "7", "8", "9",
                            "10", "Jack", "Queen", "King" };

            // Declare and initialise a counter for amount of cards to reveal for
            // the players hand
            int playerCounter = 2;
            // Declare and initialise a counter for amount of cards to reveal for
            // the AI's hand
            int AiCounter = 1;

            if (isPlayer) {
                    for (int i = 0; i < playerCounter; i++) {
                            String suit = suits[hand[i] / 13];
                            String value = values[hand[i] % 13];
                            System.out.print(value + " of " + suit + " ");
                    }
            } else {
                    for (int j = 0; j < AiCounter; j++) {
                            String suit = suits[hand[j] / 13];
                            String value = values[hand[j] % 13];
                            System.out.print(value + " of " + suit + " ");
                    }
                    AiCounter++;
            }

    }

    /*
     * Automates the dealer's play after the player stands. Dealer draws a new
     * card until he has 17 or greater
     */
    public static void finishDealersPlay(int[] deck, int[] dealer) {
            // Calls the calculateScore method to check the Dealers score, if its
            // less than, 17, calls the hit method to augment the dealers hand
            while (calculateScore(dealer) < 17) {
                    hit(deck, dealer);
            }

    }

    /* Take in two hands, and checks if either scores 21. */
    public static int blackjack(int[] player, int[] dealer) {
            if ((calculateScore(player) == 21 && calculateScore(dealer) != 21)
                            && player[2] == -1) {
                    return 1;
            }
            if ((calculateScore(player) == 21 && calculateScore(dealer) == 21)
                            && player[2] == -1) {
                    return 0;
            }
            return -1;
    }

    /*
     * Expects an int array representing a Blackjack hand as a parameter.
     * Returns the score from the card representation
     */
    public static int calculateScore(int[] hand) {
            // Originally score is 0
            int score = 0;
            // Originially no ace has been played
            boolean acePlayed = false;

            for (int i = 0; i < hand.length; i++) {
                    // Add ten for the 'picture' cards, excluding the Ace
                    if (hand[i] % 13 > 9) {
                            score += 10;
                            // Add 11 for any Aces played
                    } else if (hand[i] % 13 == 0) {
                            score += 11;
                            // Set the boolean for acePlayed to true
                            acePlayed = true;
                    } else {
                            // Add the numerical value of any other card
                            score += hand[i] % 13 + 1;
                    }
            }
            // If the score with the ace is greater than 21, delete 10 from the
            // score, to make the ace equal 1
            if (score > 21 && acePlayed == true) {
                    score -= 10;
            }

            // Return the computed score
            return score;
    }

    /* Computes who has won */
    public static int calculateWinnings(int[] player, int[] dealer) {
            if ((calculateScore(player) <= 21)
                            && (calculateScore(dealer) < calculateScore(player))
                            || calculateScore(dealer) > 21) {
                    // Player wins
                    return 1;
            }

            else if (calculateScore(player) == calculateScore(dealer)) {
                    // Push
                    return 0;
            }
            // Dealer wins
            return -1;
    }
}

2 个答案:

答案 0 :(得分:1)

除了你的循环之外,你有两次显示这些行的原因是:

  • 在阅读投注时,您正在使用

    bet = input.nextInt();
    

将读取用户输入的int,但用户在数字后按ENTER键,后者又插入换行符,而nextInt()不会消耗它

  • 稍后在代码中,您正在使用:

    String hitOrStand = input.nextLine();
    

和nextLine()将使用该换行符。

  • hitOrStand现在等于换行符,所以你以后做的所有比较('h'或'H','s'或'S')将评估为false,然后你回到while的开头(玩)循环。

解决此问题的方法很少,例如:

  • 在您使用的每个nextXXX()方法之后使用input.nextLine()来使用换行符;
  • 使用bet = Integer.parseInt(input.nextLine())而不是input.nextInt()

可能还有其他一些人。以下是它的外观:

int bet = input.nextInt();

//add nextLine() to consume newline character
input.nextLine();

while (bet > 25 || bet < 5 || bet % 5 != 0 || bet > bank) {
    System.out
            .print("Please re-enter you bet, this must be either 5, 10, 15, 20 or 25\nand be less than €"
                    + bank + ": ");

    bet = input.nextInt();

    //add nextLine() to consume newline character
    input.nextLine();
}

请详细了解扫描仪课程here 另请注意,您没有检查无效的用户输入,因此如果期望数字,您的程序将会中断,并且会给出一个字符串,但我会将其作为改进机会留给您:)

答案 1 :(得分:0)

您将done设置为true,但您从未将play设置为false或将gameFinished设置为true。您可能想重新考虑这三个布尔值的语义以及它们之间的关系。