扫描程序仅获取某些输入

时间:2017-06-07 04:20:37

标签: java java.util.scanner

我正在使用卡片和甲板课程制作一个二十一点程序。一切都有效,除了主类中的一个方法。在每轮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;
    }
}

1 个答案:

答案 0 :(得分:1)

问题不在于扫描仪!

我将此代码插入调试器,并且卡在Card.createSuit()函数的无限循环中。 duplicateCheck字典被true填充,因此它永远不会选择下一个套装。

注意:duplicateCheck被声明为静态,因此它将在“deals”之间维护其实例。 duplicateCheck可能不应该在Card类中,而是在Deck类中,而不是静态的。这样,每个Deck实例都会引用已使用的卡片。您仍然可以调用新的Card()来生成随机卡,但检查Deck实例中新Card实例的套装和值。

另一个注意事项:这仍然是一个非常繁忙的甲板发生器,因为你每次都会生成一张随机卡,这可能已经是甲板的一部分了。我建议可能有一些“可用”卡片列表(或套装),每次你想要一张卡片时,你在该列表中选择一个随机索引来获得卡片价值/套装。然后从列表中删除该项目,以便它不适用于下一张卡片选择。我会把这一切都留给你了。玩得开心!