我为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;
}
}
答案 0 :(得分:1)
除了你的循环之外,你有两次显示这些行的原因是:
在阅读投注时,您正在使用
bet = input.nextInt();
将读取用户输入的int,但用户在数字后按ENTER键,后者又插入换行符,而nextInt()不会消耗它
稍后在代码中,您正在使用:
String hitOrStand = input.nextLine();
和nextLine()将使用该换行符。
解决此问题的方法很少,例如:
可能还有其他一些人。以下是它的外观:
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。您可能想重新考虑这三个布尔值的语义以及它们之间的关系。