Сдвиг элементов в 2D ArrayList

1

У меня есть 2D ArrayList который был заполнен элементами (объектами, которые содержат изображения и т.д.), Поэтому 2D-массив был заполнен. После вызова функций удаления мой массив выглядит как изображение с левой стороны; с правой стороны вы можете увидеть желаемый результат. Может кто-нибудь, пожалуйста, дайте мне идею, как реорганизовать мой массив, как вы можете видеть на картинке?

Изображение 174551

Идея заключалась в том, чтобы идти снизу вверх. Если я нахожу пробел (разрыв означает, что я устанавливаю фон элемента imageIcon null, соответственно, для параметра imageIcon установлено значение null), я переключу его на предыдущий элемент. И поскольку я переключил его, я должен сделать это для всей колонки. Проблема в том, что когда они имеют 2 или более пробелов, а также этот алгоритм ничего не делает.

    for (int i = 0; i < 10; i++) {

        for (int j = 7; j > 0; j--) {
            Item currentItem = this.elements.get(j).get(i).getItem();

            if (currentItem.getBack().getIcon() == null) {
                int count = j;

                while (count > 1) {
                    Position temp = this.elements.get(count).get(i);
                    Position zero = this.elements.get(count).get(i);
                    Position previous = this.elements.get(count - 1).get(i);
                    zero = previous;
                    previous = temp;

                    count--;

                }

            }
        }
    }

Размер массива данных ограничен 10x8 из-за моей панели игровых панелей. Элементы массива не различаются, они имеют только разные фоны (тип компонента JLabel). Элементы должны "падать сверху вниз".

PS: Я создаю клон Bejeweled

Изображение 174551

Изображение 174551

  • 3
    Покажите нам код.
  • 0
    Согласитесь с @khelwood. Без вашего кода можно догадаться, что вы делаете неправильно.
Показать ещё 7 комментариев
Теги:
arraylist
sorting
jlabel
2d

3 ответа

0
Лучший ответ

Из того, что вы показали на снимках, вы хотите, чтобы элементы столбцов были "опущены вниз"? Если это так, вы, вероятно, должны использовать обычный 2D-массив вместо ArrayList, с массивом для каждого из ваших столбцов и предположить, что нижняя часть индексируется 0 - почему? потому что ArrayList не имеет фиксированного размера, а ваш оператор проблемы показывает, что контейнер должен иметь фиксированный размер. Тогда решение будет (грубо говоря, потому что вы указали только часть своего кода, а не SSCCE):

//Item[][] items;
for( Item[] arr : items )
  for( int i = arr.length - 2; i >= 0; i-- )
    if ( arr[i] == null ) // or arr[i].getBack().getIcon() == null or whatever
      for( int j = i; j < arr.length - 1; j++ )
        arr[j] = arr[j+1];

Это сырой пузырьковый вид, подходящий для небольших массивов. Возможны и другие решения (поскольку это проблема сортировки сама по себе), вы можете найти qsort для этого), но этот, возможно, самый простой.

Примечание. Вы можете реализовать одно и то же решение для ArrayList s, но я решительно выступаю против него. Использование вложенного массива ArrayList для имитации многоуровневых массивов редко является хорошей идеей - в любом случае они будут создавать массивы, но вы получите большие накладные расходы, делая код более медленным и менее читаемым - в любом случае вы можете это сделать, заменив [] с get()/set() и т.д.

Для справки:

//ArrayList<ArrayList<Item>> items;
//int columnHeight;
for( ArrayList<Item> arr : items )
  for( int i = columnHeight - 2; i >= 0; i-- )
    if ( arr.get(i) == null ) //or arr.get(i).getIcon()==null or whatever
      for( int j = i; j < columnHeight - 1; j++ )
        arr.set(j, arr.get(j+1));

или просто путем предоставления компаратора:

//ArrayList<ArrayList<Item>> items;
//int columnHeight;
for( ArrayList<Item> arr : items )
  Collections.sort(arr, new Comparator<Item>() {
    @Override
    public int compare(Item i1, Item i2) {
        return ...; // place the sorting rule here
    }
  });

Дополнительные сведения см. В документах для Collections.sort() & Comparator.

Кроме того, если это действительно клон Bejeweled - вы можете подумать о том, чтобы "сбросить", выполнив итерацию, сбросив все драгоценности с пустым полем под одним шагом, подсчитав количество упавших драгоценностей и повторив эту итерацию до количества капель == 0. То, что я использовал в моем клоне во времена прошлого.

0

Как уже упоминалось @vaxquis, лучше переписать свой код более элегантным способом.

for (int i = 0; i < 10; i++) {

    // Perfoming bubble sort for each column
    boolean swapped = true;
    for(int j = 6; j > 0 && swapped; j--) {
        swapped = false;

        for (int k = 0; k < j; k++) {
            Item currentItem =  this.elements.get(k).get(i).getItem();
            Item nextItem    =  this.elements.get(k+1).get(i).getItem();

            if (currentItem.getBack().getIcon() != nextItem.getBack().getIcon()) {
                swap(currentItem, nextItem);   // implement this yourself
                swapped = true;
            }

        }
    }
}
-1

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

Position temp = this.elements.get(count).get(i);
Position zero = this.elements.get(count).get(i);
Position previous = this.elements.get(count - 1).get(i);
zero = previous;
previous = temp;

Вероятно, у вас есть метод setItem() чтобы вернуть объект в объект Position? Тогда будет своп:

Position current = this.elements.get(count).get(i);
Position previous = this.elements.get(count - 1).get(i);
Item temp = current.getItem();
current.setItem(previous.getItem();
previous.setItem(temp);

Ещё вопросы

Сообщество Overcoder
Наверх
Меню