Использование оператора if для раздачи карт

#java #if-statement #while-loop

#java #if-statement #цикл while

Вопрос:

Я пытаюсь раздать игроку x карт в зависимости от того, сколько у них уже есть в руке (максимум 5). Но чтобы гарантировать, что вам не сдадут одну и ту же карту дважды или не сдадут карту, которая уже была сыграна, я использовал оператор if .

 Card[] hand = new Card[5];
public void dealCard() {
  int cardCount = 0;
  Random ran = new Random();

  if (cardCount < 5) {
    int times = 5 - cardCount;
    for (int l = 0; l < times; l  ) {
      int index = ran.nextInt(deck.length);
      if (deck[index] != null) {
        hand[cardCount] = deck[index];
        deck[index] = null;
        cardCount  ;
      }
    }
  }
}
  

Сначала казалось, что это работает, но время от времени последняя карта, и это всегда последняя карта, равна null. Мне сказали, что, вероятно, было бы лучше использовать вместо этого цикл while, но только для того, чтобы узнать, что я здесь сделал не так.

Комментарии:

1. Вы могли бы использовать a Set для предотвращения дублирования

2. nextInt(x) возвращает значение int между, [0, x[ что может быть вашей проблемой

3. Поскольку cardCount инициализируется с 0 помощью, вам не нужен самый внешний if . Кроме того, вам необходимо предпринять действие if deck[index] == null , потому что ваш for цикл всегда будет выполняться ровно 5 раз, независимо от того, как часто вы eoncouter null значение

4. Где ваше deck объявление?

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

Ответ №1:

Ваш for цикл всегда выполняется ровно пять раз, независимо от того, как часто вы сталкиваетесь с a null в теле цикла. Вы можете убедиться в этом, изменив размер deck to something < 5 . Если ваш метод работает правильно, он должен попасть в бесконечный цикл. вместо этого вы получите как минимум 5 - deck.size много null s. Быстрым и грязным решением будет уменьшение l в случае, если вы столкнетесь с null :

 if (deck[index] != null) {
    // ...
} else /* if (deck[index] == null) */ {
    --l;
}
  

Я бы рекомендовал другую стратегию в целом. Вместо того, чтобы генерировать случайный индекс каждый раз, когда вы хотите взять карту, вы могли бы заранее определить порядок всех карт, например, с помощью Фишера-Йейтса в случайном порядке. Таким образом, вам нужно только запомнить, сколько карт было разыграно, и извлечь следующую карту из вашего массива / списка / очереди.