2013-11-29 128 views
0

我寫了一個基本的命令行面向java的Blackjack遊戲,編碼時遇到了一個意想不到的問題,並且這提示了以下問題什麼是在java中結束'action'序列的最佳方式。即我們應該使用do while循環還是應該使用while(boolean)?重複循環,java

我知道我的代碼中必須存在邏輯錯誤,但我找不到它。當我運行的代碼,我期望能夠告訴我的手是什麼,要問我是否想站或打,像這樣:

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(); 

我不知道如果我使用布爾「玩」正確。爲防萬一這個問題不在本節中,我將在下面列出完整的(相當乏味的)代碼。非常感謝你。

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; 
    } 
} 
+0

請根據這段代碼[SSCCE](http://sscce.org/) –

+0

,play可以替換爲'true' - 它的值似乎沒有改變。 –

+0

在讀取整數時,您不會消耗換行符(當用戶按ENTER時添加) - 請參閱下面的較長答案。 – Melquiades

回答

1

你的循環之外,你爲什麼有這些行顯示兩次的原因是:

  • 閱讀的賭注時,您使用

    bet = input.nextInt(); 
    

將讀取的int用戶輸入,但用戶在數字後按下ENTER鍵,然後插入換行符並且nextInt()不會消耗它

  • 稍後在代碼中,你使用:

    String hitOrStand = input.nextLine(); 
    

和nextLine()將消耗該換行符。

  • hitOrStand現在等於換行字符,所以所有的比較你後來做的(「H」或「H」,「S」或「S」)將評估爲假,而你回到起點while(play)循環。

有幾個方法可以解決這個問題,比如:

  • 由您使用的每個nextXXX()方法後使用input.nextLine()消費換行符; =的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 另外請注意,你不檢查無效的用戶輸入,因此,如果該公司預計數你的程序將打破,並給出一個字符串,但我會把它作爲你的一個改進機會:)

+0

非常感謝您的回覆。我已經閱讀了掃描儀類並修復了代碼。乾杯。 – Dobhaweim

0

您設置done爲真,但你永遠不設置play以虛假或gameFinished爲true。您可能想重新思考這三種布爾的語義以及它們之間的關係。