Как я могу напечатать комбинированные значения переключателя без повторения в Java? - PullRequest
0 голосов
/ 22 октября 2019

Как я могу заставить консоль распечатать 1 костюм и 1 номер без печати той же самой комбинации?

Это начало покерной игры, которую я создаю.

import java.util.Scanner;

public class Poker {
    public static void main(String[] args) {
        int Cards_Per_Player= 5;
        int Num_Cards = 5;
        int Num_Players = 5;
        int Num_Attempts = 0;
        String suit = "deck";
        String value = "Ace";
        Scanner input = new Scanner(System.in);
        System.out.println("welcome to the den");
        System.out.println("only 2 to 5 players are allowed in here.");
        System.out.println("How many of you are there?");
        Num_Players = input.nextInt();
        Num_Attempts = 1;
        while(Num_Players < 2 |  Num_Players > 5) {
            if(Num_Players < 2 | Num_Players > 5)
                System.out.println("That is wrong try again.");
            Num_Players = input.nextInt();
            Num_Attempts++;
        }
        System.out.println("alright, we got "+ Num_Players + " Here");
        for(int i=1; i <= Num_Players; i++) {
            System.out.println("Player" + i);
            for (int card = 1; card <= Num_Cards; card++) {
                double s1 = Math.random();
                double v1 = Math.random();
                int Suit = (int)(s1 * 4) + 1;
                int Cards = (int)(v1 * 13);
                switch (Suit)
                {
                    case 1: suit = "Hearts"; break;
                    case 2: suit = "Clubs"; break;
                    case 3: suit = "Spades"; break;
                    case 4: suit = "Diamond"; break;
                }
                switch (Cards)
                {
                    case 1: value = "Ace"; break;
                    case 2: value = "2"; break;
                    case 3: value = "3"; break;
                    case 4: value = "4"; break; 
                    case 5: value = "5"; break;
                    case 6: value = "6"; break;
                    case 7: value = "7"; break;
                    case 8: value = "8"; break;
                    case 9: value = "9"; break;
                    case 10: value = "10"; break;
                    case 11: value = "Jack"; break;
                    case 12: value = "Queen"; break;
                    case 13: value = "King"; break;
                }
                System.out.println(" " + value + " of " + suit + ",");
            }
            System.out.println();
        }
    }
}

Ответы [ 3 ]

1 голос
/ 24 октября 2019

Ваша проблема не в печати, а в выборе значения перед печатью, поскольку значение - это то, с чем ваша программа продолжит работать, когда вы расширите ее до реальной игры.

Вы не должны использоватьswitch утверждение здесь вообще. Используйте коллекции законных ценностей. Например, если у вас есть список

, например

List<String> list = Arrays.asList("foo", "bar", "baz");

, вы можете выбрать случайное значение, например

Random r = new Random(); // reusable

String value = list.get(r.nextInt(list.size()));

Но чтобы избежать повторения, не следует выбирать случайное значениеценность и проверка на столкновения впоследствии. Чем больше значений вы выбрали, тем выше вероятность столкновения и тем дольше будет процесс выбора отличного значения.

Вместо этого делайте это как настоящий дилер карт. Просто перетасуйте всю колоду, затем распределите карты в указанном порядке. Когда список содержит различное значение, перетасовка его не изменит, и если брать элементы по порядку, никогда не выбирает элемент дважды.

Например,

// invariants; starting with Java 9, you can use List.of(...)
List<String> suits = Arrays.asList("Hearts", "Clubs", "Spades", "Diamond");
List<String> ranks = Arrays.asList(
    "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King");

// create a deck
List<List<String>> allCards = new ArrayList<>(suits.size() * ranks.size());
for(String suit: suits) for(String rank: ranks) allCards.add(Arrays.asList(rank, suit));

Collections.shuffle(allCards); // shuffle in one operation

System.out.println("alright, we got "+ Num_Players + " here");
for(int i = 1, pos = 0; i <= Num_Players; i++, pos += Num_Cards) {
    System.out.println("Player " + i);
    // split the deck into sublist of Num_Card size
    List<List<String>> hand = allCards.subList(pos, pos + Num_Cards);
    for(List<String> card: hand) {
        System.out.println(" " + card.get(0) + " of " + card.get(1) + ",");
    }
    System.out.println();
}

При этом используются списки из двух строк, ранги костюм для представления карты. Но гораздо лучше использовать специальные типы, например enum типы для масти и ранга и неизменный Card тип, представляющий комбинацию ранга и масти. В принципе, у вас может быть и тип enum для карт, но объявление всех возможных карт не будет правильным решением. Неизменяемый тип Card по-прежнему позволяет поддерживать отдельные объекты для всех возможных комбинаций внутри.

Это может выглядеть следующим образом:

enum Suit {
    Hearts, Clubs, Spades, Diamond
}
enum Rank {
    Ace, _2, _3, _4, _5, _6, _7, _8, _9, _10, Jack, Queen, King;
    String userName = name().startsWith("_")? name().substring(1): name();

    @Override
    public String toString() {
        return userName;
    }
}
final class Card {
    public static Card of(Suit suit, Rank rank) {
        return LOOKUP.get(suit).get(rank);
    }

    public static List<Card> newDeck() {
        return new ArrayList<>(ALL);
    }

    public static List<Card> newShuffledDeck() {
        final List<Card> deck = newDeck();
        Collections.shuffle(deck);
        return deck;
    }

    public static Map<String, List<Card>> deal(int numberOfPlayers, int cardsPerPlayer) {
        if(numberOfPlayers < 1 || cardsPerPlayer < 1
        || numberOfPlayers*cardsPerPlayer > ALL.size()) {
            throw new IllegalArgumentException();
        }
        Map<String, List<Card>> allHands = new LinkedHashMap<>();
        List<Card> deck = newShuffledDeck();
        for(int player = 1, pos = 0;
                player <= numberOfPlayers; player++, pos += cardsPerPlayer) {
            allHands.put("Player "+player,
                Collections.unmodifiableList(deck.subList(pos, pos + cardsPerPlayer)));
        }
        return allHands;
    }

    public final Suit suit;
    public final Rank rank;

    private Card(Suit suit, Rank rank) {
        this.suit = suit;
        this.rank = rank;
    }

    @Override
    public String toString() {
        return rank+" of "+suit;
    }

    private static final Map<Suit,Map<Rank,Card>> LOOKUP;
    private static final List<Card> ALL;
    static {
        Map<Suit,Map<Rank,Card>> all = new EnumMap<>(Suit.class);
        List<Card> list = new ArrayList<>();
        for(Suit suit: Suit.values()) {
            Map<Rank,Card> byRank = new EnumMap<>(Rank.class);
            all.put(suit, Collections.unmodifiableMap(byRank));
            for(Rank rank: Rank.values()) {
                byRank.put(rank, new Card(suit, rank));
            }
            list.addAll(byRank.values());
        }
        LOOKUP = Collections.unmodifiableMap(all);
        ALL = Collections.unmodifiableList(list);
    }
}

, который можно интегрировать в существующий код, например

Map<String, List<Card>> hands = Card.deal(Num_Players, Cards_Per_Player);
for(Map.Entry<String, List<Card>> hand: hands.entrySet()) {
    System.out.println(hand.getKey());
    for(Card card: hand.getValue()) {
        System.out.println(" "+card);
    }
}
0 голосов
/ 22 октября 2019

У вас есть несколько вариантов, но я бы отслеживал уже просмотренные карты, используя Set. Вы можете либо сделать Set<String> cards, используя формат "номер масти", либо Set<Card> cards, а затем позвонить cards.contains(card), чтобы узнать, найдена ли сгенерированная карта.

В качестве отступления / заголовка, в Java принято называть все переменные, начинающиеся с буквы нижнего регистра, так как имена, подобные этим, традиционно зарезервированы для классов.

0 голосов
/ 22 октября 2019

Если вы хотите убедиться, что вывод не повторяется, я бы рекомендовал использовать java.util.ArrayList. Например, если после ваших переключателей, ваших suit == "Hearts" и value == "10", вы можете сделать java.util.List <Integer> suitList = new ArrayList<>() и каждый раз перед тем, как распечатать карточку, вы можете позвонить suitList.add(suit). (Конечно, вам также придется делать это и для значений, и, вероятно, лучше создать собственный класс, содержащий две переменные, а не 2 массива)

Потенциальная реализация:

До System.out.println(" "+value+" of "+suit+",");

Вызовите suitList.add(suit), и то же самое для значений.

И цикл for для итерации по списку ArrayList, чтобы проверить, была ли уже напечатана та же карта.

...