Иногда возникает ошибка при работе с List Java

266
12 ноября 2017, 14:52

Уважаемые мастера программирования, ломаю голову, мне это очень нравится, но до тех пора она не начинает от этого болеть! Вот-вот я совсем близок к своей ПЕРВОЙ игре на Java , хоть и примитивной, но эта радость своей первой "сложной" программы нарастает, много было проблем, многие решал простым гугло-поиском, и справочниками.

И вот настала новая проблема, от которой я совершенно не понимаю как избавиться:

Моя программа это как-бы игра ДУРАК с 3 картами, но не суть.

Программа четко заполняет массив объектами класса Card:

#Карты:0 Rank: 0, Suit: 0 ,Is trump:false  |_2_| ♠
#Карты:1 Rank: 0, Suit: 1 ,Is trump:false  |_2_| ♣
#Карты:2 Rank: 0, Suit: 2 ,Is trump:false  |_2_| ♥
#Карты:3 Rank: 0, Suit: 3 ,Is trump:false  |_2_| ♦
#Карты:4 Rank: 1, Suit: 0 ,Is trump:false  |_3_| ♠
#Карты:5 Rank: 1, Suit: 1 ,Is trump:false  |_3_| ♣
и.т.д;

Также здорово через Collections.Shuffle мешает карты:

#Карты:0 Rank: 0, Suit: 1 ,Is trump:false |_2_|♣
#Карты:1 Rank: 9, Suit: 0 ,Is trump:false |_J_|♠
#Карты:2 Rank: 8, Suit: 3 ,Is trump:false |_10_|♦
#Карты:3 Rank: 11, Suit: 3 ,Is trump:false |_K_|♦
#Карты:4 Rank: 2, Suit: 2 ,Is trump:false |_4_|♥
и.т.д

Колода из 52 карт (от 0 до 51)

Настал момент раздачи карты игрокам- то он раздает все правильно и программа завершается хорошо:

Начало инициализации игроков:
Карты игрока 1:
Карта №:0 |_6_|♠
Карта №:1 |_4_|♦
Карта №:2 |_K_|♣
Карты игрока 2:
Карта №:0 |_4_|♣
Карта №:1 |_J_|♥
Карта №:2 |_10_|♣
КОЛОДА КАРТ ПОСЛЕ УДАЛЕНИЯ КАРТ ИГРОКОВ: 46
СБОРКА УСПЕШНО ЗАВЕРШЕНА (общее время: 0 секунд)

Но иногда сборка с ошибкой, причем ошибка начинается во-время перемешивания колоды!:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 49, Size: 49
    at java.util.LinkedList.checkElementIndex(LinkedList.java:555)
    at java.util.LinkedList.get(LinkedList.java:476)
    at simplecardgame.DeckOfCards.DeckInit(DeckOfCards.java:185)
    at simplecardgame.SimpleCardGame.main(SimpleCardGame.java:25)

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

Вот код, который не работает, когда ошибка появляется при сборке:

        System.out.println("Начало инициализации игроков:");
    //Переменные для игроков
    int currentDeckP1 = 3;
    int currentDeckP2 = 3;
    int rndmX1;
    int rndmX2;
    //Карты игроков;
    List<Card> listOfP1 = new LinkedList<>();
    List<Card> listOfP2 = new LinkedList<>();
    List<Card> deathCards = new LinkedList<>();
    //Инициализация игроков:
    Player p1 = new Player(0,false);
    Player p2 = new Player(0,false);
    //Раздача случайных 3х карт для игроков:
    for (int i = 0; i < 3 ; i++)
    {
        Random rndNum = new Random();
        //Измнеение переменных, чтобы можно было удалить карту из колоды:
        rndmX1 = rndNum.nextInt(list.size());
        rndmX2 = rndNum.nextInt(list.size());
        //Добавление карты в колоду игрока
        listOfP1.add(list.get(rndmX1));
        //удаление карты из основной колоды:
        list.remove(rndmX1);
        //Добавление карты в колоду игрока
        listOfP2.add(list.get(rndmX2));
        //Удаление карты из основной колоды
        list.remove(rndmX2);
    }
Answer 1

Вы тут rndmX2 = rndNum.nextInt(list.size()); получили случайное число 49. Элементов в списке 50.

Дальше удаляете list.remove(rndmX1); элемент. Там теперь 49.

А теперь пытаетесь взять элемент listOfP2.add(list.get(rndmX2)); на 49 позиции.

Вот и ошибка.

Находите случайное значение rndmX2 = rndNum.nextInt(list.size()); после удаления.

Random rndNum = new Random();
//Измнеение переменных, чтобы можно было удалить карту из колоды:
rndmX1 = rndNum.nextInt(list.size());
//Добавление карты в колоду игрока
listOfP1.add(list.get(rndmX1));
//удаление карты из основной колоды:
list.remove(rndmX1);
rndmX2 = rndNum.nextInt(list.size());
//Добавление карты в колоду игрока
listOfP2.add(list.get(rndmX2));
//Удаление карты из основной колоды
list.remove(rndmX2);

P.S. создавать Random каждый раз не рекомендуется. Создавайте один раз в глобальную переменную и сделайте её static.

READ ALSO
Запись/Чтение строкового массива в Java, Android

Запись/Чтение строкового массива в Java, Android

Есть строковый массив test, нужно сохранить его в папке на телефоне, чтобы его можно было увидеть из проводникаА потом считать его из папки...

268
Изменение полей ошибки

Изменение полей ошибки

Если при запросе что-то пошло не так, то RestController выкинет json такого вида:

275
Голосовые сообщения в Android

Голосовые сообщения в Android

Как в андроид можно реализовать голосовые сообщенияЕсть ли какие-нибудь библиотеки или хотя бы просто алгоритм что нужно для создания и отправки...

251
Получение всех методов пакета

Получение всех методов пакета

Как узнать все методы пакета? С помощью Reflections понял, как получить методы класса, но как получить все методы пакета?

315