Pokemon Trainer[Java OOP]
Ще ми трябва малко помощ относно задачата.Това е кода - http://pastebin.com/Q0SthWNc .И имам няколко въпроса.Първо защо като въведа нулевият тест ми пропуска 1-вия ред и 3-тия ако не се лъжа и после ми гърми защото е indexOutOfBoundary,но това е защото while цикъла не спира когато readera е равен на Tournament(не знам защо ).По условието искат треньора да има колекция от покемони, разбирам го List от покемони.В главната програма правя два Lista, в който запазвам покемоните и треньорите и после идеята ми беше по някакъв начин да получа достъп до името на елемента на покемона и дали е равно на това, което се въвежда от конзолата, но не мога да го направя.Също така треньорите имат име, баджове и колекция от покемони и в началото всеки има по 0 баджове.Правилно ли съм направил конструктура, защото не съм сигурен дали е така.Като цяло това са ми въпросите, имам доста неясни неща, но няма друг начин да ги науча освен да питам тук.
Разбрах ти идеята, донякъде, но не напълно.Пропуска през едно защото и във 2-рия цикъл чета.Как тогава да го направя, тази част не ти разбрах?
На тези места метеш от конзолата.
Аз бих го заменил със следното.
Възприемай го като псевдокод, защото нямам компилатор пред себе си.
Идаята е , че като стигнеш турнамент , трябва да прочетеш още един ред, защото е ясно, че този намя да го ползваш от втория цикъл
Окей това го оправих, но по-важното самата задача, не знам как да я довърша.
Привет,
Ще ти дам малко насоки, поне от това което виждам аз. Погледни и качи новия код с преправките:
Класът Pokemon:
1. Не са ти необходими set методите. Нито едно от полетата на покемона не е нужно да се презаписва.
2. Единствения функционален метод от който има нужда този клас е такъв който може да намали кръвта. Тоест имаш 2 варианта:
или нещо от типа decreaseHealth(int value) {health = health-value;} или пък да оставиш все пак setHealth(int health) метода с идеята да го викнеш отвън примерно pokemon.setHealth(pokemon.getHealth() - 10)
Класът Trainer:
1. Конструкторите приемат List<Pokemon>, което в случая не е необходимо и според мен излишно ги усложнява. Един конструктор по name е напълно достатъчен. Също така тук е мястото на което да инизиализираш празен списък от Pokemon, а не в главния клас.
2. Полетата са ОК, но отново set методите са излишни.
3. Липсват функционалните методи. По - добре би било да бъдат в този клас, но има и вариант да използваш getPokemons() метода и да направиш цялата логика в главния клас. Да разгледаме обаче, случая когато те са в този клас:
3.1. Мeтод, който по дадени параметри за pokemon може да добави такъв към pokemonts list-a - разбира се, този метод може да приеме както параметър от тип Pokemon, така и name, element, health и вътре да създава нов обект от тип Pokemon. При всички случаи накрая го добавя към списъка.
3.2. Метод, който приема на вход element и връща boolean: Обхожда списъка pokemons и ако на някой от тях елемента съвпада с подадения връща true, ако не - false.
3.3. Метод, който да обходи листа pokemons и да намали кръвна на всеки pokemon с дадено value - тук ползваш функционалния метод от предния клас.
3.4. Метод, който обхожда листа с pokemons и маха тези на които кръвта им е по - малка или равна на 0 - Тук при обхождането не трябва да ползваш foreach. Moже да го направиш най - лесно със stream api-то.
3.5 Метод, който да увеличава badges (badges++)
Главния клас:
1. Колегите вече написаха как да си прочетеш входа.
2. Както писах по - горе List<Pokemon> pokemons=new ArrayList<>(); този лист не му е мястото тук. Класът Trainer ще се грижи за него.
3. List<Trainer> trainers=new ArrayList<>(); - Това може да го направи на Map<String, Trainer> за да ти е по - лесно да проверяваш дали текущия треньор вече го няма
4. Четем входа до Tournament:
Ако Trainer t = trainers.get(TrainerName) - Ако t != null, значи треньора вече го има и ползваме метода 3.1 за да добавим покемона към вече съществуващия списък на този треньор. Ако пък е null, правим нов треньор и пак същия метод.
5. След това:
for (Trainer trainer : trainers.values()) {
ако trainer има покемон с element (метод 3.2) -> метод 3.5, иначе методи 3.3 и 3.4
}
6. Сортираш trainers.
Нулев тест 3 не го гледай, той е с чисто празен вход и съответно изобщо няма Tournament, който да прекъсне цикъла.
Защо не трябва да ползва foreach a stream api?
Привет,
защото ще трие елементи. Ако върви по итератор и трие елементи ще получи Runtime Exception (Някой даже вече се оплака от това в друга тема по същата задача). Не е задължително да е stream api, просто го написах като лесен според мен вариант. Ако е все пак се ползва foreach той трябва да събере елементите, които ще трие в друг list и после да мине да ги трие във втори цикъл. Ако се помисли сигурно и още варианти за решение ще излязат ...
Ще получи ConcurrentModificationException който може да се избегне по няколко начина
аз в тази задача конкретно го направих ->
друг вариант е да се направи iterator от листа примерно
Iterator<Pokemon> iterator = this.pokemonList.iterator();
и с цикъл while(iterator.hasNext())
вътре слагаш условието if(iterator.next().getHealth()<=0) и при него да маха покемон.