我正在使用卡片和甲板课程制作一个二十一点程序。一切都有效,除了主类中的一个方法。在每轮Blackjack之前,系统会询问玩家是否要保留相同的下注金额,更改下注或退出程序(哨兵值为0)。 getBet()方法被调用至少两次(如果此问题没有停止程序,则可以调用两次以上)。但是,与第一次调用该方法不同,该方法仅识别并作用于标记的输入。如果您尝试更改号码或按Enter键,则播放器会在控制台屏幕上陷入无限循环。
为什么getBet()方法在第二次调用时,不返回任何输入,除非输入的值为0?以下提供所有3个课程。我本来会提供一个Minimal,Complete和Verifiable示例,但是,我认为读者可能更喜欢运行我的实际代码,因为getBet()方法似乎没有错误,我无法缩小问题的范围。是
CARD CLASS
import java.util.Random;
public class Card
{
private String suit, valueString;
private int value, valueNum, suitNum;
private final String[] SUITS = {"Clubs", "Diamonds", "Hearts", "Spades"};
private final int[] VALUES = {2,3,4,5,6,7,8,9,10};
private static int tot = 0;
private static boolean[][] duplicateCheck = new boolean[4][13];//to see if suit/value pair has been used yet
Random rand = new Random();
public Card()
{
suit = createSuit();
value = createValue();
valueString = createValueString();
tot += value;
}
private String createSuit()
{
String suit;
do
{
suitNum = rand.nextInt((3 - 0) + 1) + 0;
suit = SUITS[suitNum];
valueNum = rand.nextInt((12 - 0) + 1) + 0;
}
while(duplicateCheck[suitNum][valueNum]);
duplicateCheck[suitNum][valueNum] = true;
return suit;
}
private int createValue()
{
int value;
if(valueNum >= 9 && valueNum <= 11)
value = 10;
else if(valueNum == 12)
{
if(tot + 11 > 21)
value = 1;
else
value = 11;
}
else
value = VALUES[valueNum];
return value;
}
private String createValueString()
{
String valueString;
if(valueNum >= 9 && valueNum <= 11)
{
switch(valueNum)
{
case 9:
valueString = "Jack";
break;
case 10:
valueString = "King";
break;
case 11:
valueString = "Queen";
break;
default:
valueString = Integer.toString(valueNum);//not really needed
break;
}
}
else if(valueNum == 12)
valueString = "Ace";
else
valueString = Integer.toString(VALUES[valueNum]);
return valueString;
}
public String getSuit()
{
return suit;
}
public int getValue()
{
return value;
}
public String getValueString()
{
return valueString;
}
@Override
public String toString()
{
String str;
str = valueString + " (" + suit + ")";
return str;
}
}
DECK CLASS
import java.util.ArrayList;
public class Deck
{
ArrayList <Card> deck = new ArrayList<>();
private static int drawCard = 0;
public Deck()//creates shufffled deck (each card is made at random)
{
for(int x = 0; x < 52; x++)
{
deck.add(new Card());
}
}
public Card draw()
{
Card drawn;
drawn = deck.get(drawCard);
drawCard++;
return drawn;
}
}
主要类别和方法
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Scanner;
public class Blackjack
{
public static void main(String[] args)
{
Deck newDeck;
Card c = null;
String name;
int bal = 1000, currentBet = 25;
char move = 'h';//hit by default
int[] handValues = new int[2];
ArrayList<Card> dealer = new ArrayList<>();
ArrayList<Card> player = new ArrayList<>();
DecimalFormat df = new DecimalFormat("#,###");
name = getName();
System.out.println(name + " has $" + df.format(bal));
currentBet = getBet(currentBet);
while(currentBet != 0 && bal > 0)//determines when program ends
{
newDeck = new Deck();
//player 2 cards, dealer 1 card
firstDeal(c, newDeck, player, dealer, name, handValues, currentBet);
System.out.println();
move = nextMove();
//loop: player hits until bust, stand, or hits 21
while(handValues[0] != 21 && handValues[0] < 21 && move != 's')
{
System.out.println("\nBet: $" + df.format(currentBet));
dealerStand(dealer, handValues);
playerHit(c, newDeck, player, name, handValues);
if(handValues[0] != 21 && handValues[0] < 21 && move != 's')
move = nextMove();
}
if(move == 's')//player stands
{
//loop: dealer hits until bust or stand
while(handValues[1] < 17)
{
System.out.println("\nBet: $" + df.format(currentBet));
dealerHit(c, newDeck, dealer, handValues);
playerStand(name, player, handValues);
}
if(handValues[1] >= 17 && handValues[1] <= 20 &&
handValues[1] > handValues[0])//dealer wins
{
System.out.println("Dealer wins\n");
bal -= currentBet;
}
if(handValues[1] >= 17 && handValues[1] <= 20 &&
handValues[1] < handValues[0])//player wins
{
System.out.println(name + " wins\n");
bal += currentBet;
}
if(handValues[1] > 21)//dealer bust, player wins
{
System.out.println("Dealer bust\n");
bal += currentBet;
}
if(handValues[0] == handValues[1])//push
System.out.println("The game is a push\n");
}
else if(handValues[0] > 21)//player busts
{
System.out.println(name + " bust\n");
bal -= currentBet;
}
else if(handValues[0] == 21)//player wins
{
System.out.println(name + " wins\n");
bal += currentBet;
}
else if(handValues[0] == handValues[1])//both tie at 21
System.out.println("The game is a push\n");
System.out.println(name + " has $" + df.format(bal));
currentBet = getBet(currentBet);//does stuff with 0, but not enter or new num
}
}
public static String getName()
{
Scanner input = new Scanner(System.in);
String name;
System.out.print("Name? ");
name = input.nextLine();
return name;
}
public static int getBet(int currentBet)
{
Scanner input = new Scanner(System.in);
String temp;
System.out.print("Bet? (0 to quit, Enter to stay at $" + currentBet + ", or a new number to change bet) ");
temp = input.nextLine();
if(!temp.isEmpty())
currentBet = Integer.parseInt(temp);
return currentBet;
}
public static char nextMove()
{
Scanner input = new Scanner(System.in);
String moveStr;
char move;
System.out.print("Move? (\"h\" for hit/\"s\" for stand) ");
moveStr = input.nextLine();
/*while(moveStr.charAt(0) != 'h' || moveStr.charAt(0) != 's')
{
System.out.println("Invalid choice. Enter either \"h\" or \"s\"."); //input validation
moveStr = input.nextLine();
}*/
move = moveStr.charAt(0);
return move;
}
public static int[] firstDeal(Card c, Deck newDeck, ArrayList player,
ArrayList dealer, String name, int[] handValues, int currentBet)
{
DecimalFormat df = new DecimalFormat("#,###");
System.out.println("\nBet: $" + df.format(currentBet));
//dealer 1 card
c = newDeck.draw();
dealer.add(c);
System.out.print("Dealer's hand: ");
for(int cardNum = 0; cardNum < dealer.size(); cardNum++)
System.out.print(dealer.get(cardNum) + " ");
System.out.println();
if(c.getValueString().equals("Ace"))
{
if(handValues[1] >= 11)
handValues[1] += 1;
else
handValues[1] += 11;
}
else
handValues[1] += c.getValue();
System.out.print("Value: " + handValues[1] + "\n");
//player 2 cards
c = newDeck.draw();
player.add(c);
if(c.getValueString().equals("Ace"))
{
if(handValues[0] >= 11)
handValues[0] += 1;
else
handValues[0] += 11;
}
else
handValues[0] += c.getValue();
c = newDeck.draw();
player.add(c);
if(c.getValueString().equals("Ace"))
{
if(handValues[0] >= 11)
handValues[0] += 1;
else
handValues[0] += 11;
}
else
handValues[0] += c.getValue();
System.out.print(name + "'s hand: ");
for(int cardNum = 0; cardNum < player.size(); cardNum++)
System.out.print(player.get(cardNum) + " ");
System.out.println();
System.out.print("Value: " + handValues[0] + "\n");
return handValues;
}
public static int playerHit(Card c, Deck newDeck, ArrayList player,
String name, int[] handValues)
{
c = newDeck.draw();
player.add(c);
System.out.print(name + "'s hand: ");
for(int cardNum = 0; cardNum < player.size(); cardNum++)
System.out.print(player.get(cardNum) + " ");
System.out.println();
if(c.getValueString().equals("Ace"))
{
if(handValues[0] >= 11)
handValues[0] += 1;
else
handValues[0] += 11;
}
else
handValues[0] += c.getValue();
System.out.println("Value: " + handValues[0] + "\n");
return handValues[0];
}
public static void playerStand(String name, ArrayList player,
int[] handValues)
{
System.out.println(name + "'s hand: ");
for(int cardNum = 0; cardNum < player.size(); cardNum++)
System.out.print(player.get(cardNum) + " ");
System.out.println();
System.out.println("Value: " + handValues[0] + "\n");
}
public static int[] dealerHit(Card c, Deck newDeck, ArrayList dealer,
int[] handValues)
{
c = newDeck.draw();
dealer.add(c);
System.out.print("Dealer's hand: ");
for(int cardNum = 0; cardNum < dealer.size(); cardNum++)
System.out.print(dealer.get(cardNum) + " ");
System.out.println();
if(c.getValueString().equals("Ace"))
{
if(handValues[1] >= 11)
handValues[1] += 1;
else
handValues[1] += 11;
}
else
handValues[1] += c.getValue();
System.out.println("Value: " + handValues[1]);
return handValues;
}
public static int[] dealerStand(ArrayList dealer, int[] handValues)
{
System.out.print("Dealers's hand: ");
for(int cardNum = 0; cardNum < dealer.size(); cardNum++)
System.out.print(dealer.get(cardNum) + " ");
System.out.println();
System.out.println("Value: " + handValues[1]);
return handValues;
}
}
答案 0 :(得分:1)
问题不在于扫描仪!
我将此代码插入调试器,并且卡在Card.createSuit()函数的无限循环中。 duplicateCheck
字典被true
填充,因此它永远不会选择下一个套装。
注意:duplicateCheck
被声明为静态,因此它将在“deals”之间维护其实例。 duplicateCheck
可能不应该在Card类中,而是在Deck类中,而不是静态的。这样,每个Deck实例都会引用已使用的卡片。您仍然可以调用新的Card()来生成随机卡,但检查Deck实例中新Card实例的套装和值。
另一个注意事项:这仍然是一个非常繁忙的甲板发生器,因为你每次都会生成一张随机卡,这可能已经是甲板的一部分了。我建议可能有一些“可用”卡片列表(或套装),每次你想要一张卡片时,你在该列表中选择一个随机索引来获得卡片价值/套装。然后从列表中删除该项目,以便它不适用于下一张卡片选择。我会把这一切都留给你了。玩得开心!