Как чередовать два списка массивов? - PullRequest
2 голосов
/ 28 марта 2020

Я пытаюсь разработать программу, которая перетасовывает колоду, разделяя ее на две, а затем чередуя их.

Классовая колода представляет колоду из 52 карт. Есть два метода: Deck (int n) и Card drawCard () .

Deck (int n) - конструктор. Параметр сообщает, сколько раундов колода должна быть перетасована. В каждом раунде перетасовки вся колода сначала делится на две суб-колоды. Подпакеты затем переплетаются в одну целую колоду.

Некоторые примечания :

  • Чтобы упростить обсуждение, мы предполагаем, что карты равны 1 , 2,…, 10.

  • В первом раунде вся колода делится на [1, 2, 3, 4, 5] и [6, 7, 8, 9 10]. Затем мы объединяем две суб-колоды, чередуя их с [1, 6, 2, 7, 3, 8, 4, 9, 5, 10].

  • Во втором раунде , мы снова делим целые колоды на две подкаки [1, 6, 2, 7, 3] и [8, 4, 9, 5, 10] и затем объединяем их в [1, 8, 6, 4, 2 , 9, 7, 5, 3, 10].

  • Поскольку мы всегда кладем карты в первую суб-колоду перед второй суб-колодой, первой и последней картой колоды остается неизменной независимо от того, сколько раундов мы перетасуем.

  • Исходный порядок колоды: S2, S3,…, SK, SA, H2,…, HA, C2 ,…, CA, D2,…, DA.

Card drawCard () удаляет первую карту из колоды и возвращает ее. Обратитесь к колоде после второго раунда в приведенном выше обсуждении: drawCard () возвращает 1, и колода становится [8, 6, 4, 2, 9, 7, 5, 3, 10].

Мой метод чередования : Создайте 3 списка массивов, в которых 2 из них ( cards1 и cards2 ) содержали карты SA - HA и C2 - DA а другой ( перетасованный ) держал чересстрочную колоду. Мне удалось реализовать исходный порядок колоды, однако, когда я пытаюсь чередовать, я получаю ошибку «вне границ»: «Индекс 0 вне границ для длины 0».

Вопрос : Что я делаю не так?

Вот мои коды :

import java.util.*;

public class Deck {
    private int rounds;
    private ArrayList<Card> cards = new ArrayList<Card>();
    private ArrayList<Card> cards1 = new ArrayList<Card>();
    private ArrayList<Card> cards2 = new ArrayList<Card>();
    private ArrayList<Card> shuffled = new ArrayList<Card>();

    public Deck(int n) {
        for (Suit s : Suit.values()) {
            for (Rank r : Rank.values()) {
                cards.add(new Card(r,s));
            }
        }

        for (int x=0; x<n; x++) {
            for (int i=0; i<((cards.size())/2); i++) {
                cards1.add(cards.get(i));
                for (int j=26; j<cards.size(); j++) {
                    cards2.add(cards.get(j));
                    for (int k=0; k<cards.size(); k++) {
                        shuffled.add(k*2, cards1.get(i));
                        shuffled.add(k*2+1, cards2.get(j));
                    }
                }
            }
        }

        System.out.println(cards);
        System.out.println(cards1);
        System.out.println(cards2);
        System.out.println(shuffled);
        rounds = n;
    }

    public Card drawCard() {
        Card removed = shuffled.get(0);
        shuffled.remove(0);
        return removed;
    }
}


public class Card {
    private Rank rank;
    private Suit suit;

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

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

public enum Suit {
    SPADE("S"), 
    HEART("H"), 
    CLUB("C"), 
    DIAMOND("D"); 

    private String suit;

    Suit (String s) {
      suit = s;
    }

    public String toString() {
      return suit;
    }
}
// YOU CANNOT MODIFY THIS FILE

public enum Rank {
  TWO("2"), 
  THREE("3"), 
  FOUR("4"), 
  FIVE("5"), 
  SIX("6"), 
  SEVEN("7"), 
  EIGHT("8"),
  NINE("9"), 
  TEN("10"), 
  JACK("J"), 
  QUEEN("Q"), 
  KING("K"),
  ACE("A"); 

  private String rank;

  // Constructor
  Rank (String r) {
    rank = r;
  }

  public String toString() {
    return rank;
  }
}

public class TestDeck {
  public static void main(String[] args) {

    Deck deck; 

    deck = new Deck(0);
    System.out.println("The original deck is: ");
    for (int i = 0; i < 52; i++) {
      System.out.print(deck.drawCard() + " ");
    }
    System.out.println();
    System.out.println();

    deck = new Deck(1);
    System.out.println("After shuffling once is: ");
    for (int i = 0; i < 52; i++) {
      System.out.print(deck.drawCard() + " ");
    }
    System.out.println();
    System.out.println();

    deck = new Deck(2);
    System.out.println("After shuffling twice is: ");
    for (int i = 0; i < 52; i++) {
      System.out.print(deck.drawCard() + " ");
    }
    System.out.println();
    System.out.println();
  }
}

Предполагаемый вывод для Класс TestDeck является

The original deck is:
S2 S3 S4 ... DK DA

After shuffling once is:
S2 C2 S3 C3 ... DA

After shuffling twice is:
S2 H2 C2 D2  ... DA

1 Ответ

1 голос
/ 29 марта 2020

Хорошо, дорогой, на самом деле вы получаете «индекс за пределами» (бог знает почему ... :), вот как я решил (с комментариями):

public class Deck {

    //constants for 52 and 26 :
    private static final int FULL_DECK = Suit.values().length * Rank.values().length;
    private static final int HALF_DECK = FULL_DECK / 2;
    // use the constants, we need only one list (+2 temp lists, throw away
    // "shuffeld" (not needed, confusing, we use "cards" for "full deck")):
    private final ArrayList<Card> cards = new ArrayList<>(FULL_DECK);
    public Deck(int n) {

        init(); // as you had/see below

        // more overview/structure ... and we can limit n:
        for (int rounds = 0; rounds < n % 8; rounds++) {
            interlace();
        }
        // comment this, since we do output in main method...
        // System.out.println(cards);
    }

init & " interlace "методы:

    private void init() {
        for (Suit s : Suit.values()) {
            for (Rank r : Rank.values()) {
                cards.add(new Card(r, s));
            }
        }
    }

    private void interlace() {
        // throw exception, when illegal state
        assert (!cards.isEmpty());
        // left & right temp lists:
        final ArrayList<Card> left = new ArrayList<>(HALF_DECK);
        final ArrayList<Card> right = new ArrayList<>(HALF_DECK);
        // put the first half of "cards" into "left"
        left.addAll(cards.subList(0, HALF_DECK));
        // ...the rest into "right"
        right.addAll(cards.subList(HALF_DECK, FULL_DECK));
        // clear "cards"
        cards.clear();

        // iterate half deck:
        for (int i = 0; i < HALF_DECK; i++) {
            // fill cards from "left" (with "double step")
            cards.add(i * 2, left.get(i));
            // ..and from "right" (with "double step" +1;)
            cards.add(i * 2 + 1, right.get(i));
        }
        // done!
        // debug:
        // System.out.println(left);
        // System.out.println(right);
        // System.out.println(cards);
    }

метод" draw "будет go следующим образом:

    public Card drawCard() {
        assert (!cards.isEmpty());
        return cards.remove(0);
    }

И с тем же основным методом (Suit, Rank classes) мы получим:

The original deck is: 
S2 S3 S4 S5 S6 S7 S8 S9 S10 SJ SQ SK SA H2 H3 H4 H5 H6 H7 H8 H9 H10 HJ HQ HK HA C2 C3 C4 C5 C6 C7 C8 C9 C10 CJ CQ CK CA D2 D3 D4 D5 D6 D7 D8 D9 D10 DJ DQ DK DA 

After shuffling once is: 
S2 C2 S3 C3 S4 C4 S5 C5 S6 C6 S7 C7 S8 C8 S9 C9 S10 C10 SJ CJ SQ CQ SK CK SA CA H2 D2 H3 D3 H4 D4 H5 D5 H6 D6 H7 D7 H8 D8 H9 D9 H10 D10 HJ DJ HQ DQ HK DK HA DA 

After shuffling twice is: 
S2 H2 C2 D2 S3 H3 C3 D3 S4 H4 C4 D4 S5 H5 C5 D5 S6 H6 C6 D6 S7 H7 C7 D7 S8 H8 C8 D8 S9 H9 C9 D9 S10 H10 C10 D10 SJ HJ CJ DJ SQ HQ CQ DQ SK HK CK DK SA HA CA DA 

Это не "этот" потокобезопасный ... но для демонстрации ... надеюсь, это поможет! :)

.. и индекс вне границ на самом деле, потому что вы никогда не заполнены shuffeled, , когда n == 0 ... iobex на Main: System.out.print(deck.drawCard() + " "); (и (n == 0))

...