Loading...
Pafo37 avatar Pafo37 21 Точки

Pokemon Trainer[Java OOP]

Ще ми трябва малко помощ относно задачата.Това е кода - http://pastebin.com/Q0SthWNc .И имам няколко въпроса.Първо защо като въведа нулевият тест ми пропуска 1-вия ред и 3-тия ако не се лъжа и после ми гърми защото е indexOutOfBoundary,но това е защото while цикъла не спира когато readera е равен на Tournament(не знам защо ).По условието искат треньора да има колекция от покемони, разбирам го List от покемони.В главната програма правя два Lista, в който запазвам покемоните и треньорите и после идеята ми беше по някакъв начин да получа достъп до името на елемента на покемона и дали е равно на това, което се въвежда от конзолата, но не мога да го направя.Също така треньорите имат име, баджове и колекция от покемони и в началото всеки има по 0 баджове.Правилно ли съм направил конструктура, защото не съм сигурен дали е така.Като цяло това са ми въпросите, имам доста неясни неща, но няма друг начин да ги науча освен да питам тук.

Тагове:
0
C# OOP Basics
Alex0101 avatar Alex0101 374 Точки

Първото , което видях е, че четеш ред в while и после четеш друг, реално пропускаш ред през един. Пробвай да изнесеш четенето в стринг и да четеш точно 1 път на итерация. Четеш преди while в стринг , проверяваш стринга , ако е ок влизаш в цикъла и обработваш този инпут. След това минава логиката и накрая четеш пак, ако е ок завърташ пак цикъла и така.

0
27/06/2016 18:18:16
Pafo37 avatar Pafo37 21 Точки

Разбрах ти идеята, донякъде, но не напълно.Пропуска през едно защото и във 2-рия цикъл чета.Как тогава да го направя, тази част не ти разбрах?

0
27/06/2016 18:53:17
Alex0101 avatar Alex0101 374 Точки
while(!reader.readLine().equals("Tournament")){   <-----readline
            String[] information=reader.readLine().split(" ");  <-----readline
            //somecode
        }
        while(!reader.readLine().equals("End")){    <------readline
            String element=reader.readLine();       <------readline
            //some code
            }

На тези места метеш от конзолата. 

Аз бих го заменил със следното.

String input=reader.readLine();  //<-----readline
while(!input.equals("Tournament")){   // <-----check
            String[] information=input.split(" ");  //<-----use already red data
            //somecode
          input=reader.readLine();  //<--update
        }
        input=reader.readLine(); //<-----readline
        while(!input.equals("End")){    //<------check
            String element=input;       //<-----use already red data
            //some code
         input=reader.readLine(); // <--update

            }

Възприемай го като псевдокод, защото нямам компилатор пред себе си.

Идаята е , че като стигнеш турнамент , трябва да прочетеш още един ред, защото е ясно, че този намя да го ползваш от втория цикъл

0
Pafo37 avatar Pafo37 21 Точки

Окей това го оправих, но по-важното самата задача, не знам как да я довърша.

0
kosio197 avatar kosio197 104 Точки

Привет,

Ще ти дам малко насоки, поне от това което виждам аз. Погледни и качи новия код с преправките:

Класът 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, който да прекъсне цикъла.

0
kaloyannikov avatar kaloyannikov 531 Точки

Защо не трябва да ползва foreach a stream api?

0
kosio197 avatar kosio197 104 Точки

Привет,

защото ще трие елементи. Ако върви по итератор и трие елементи ще получи Runtime Exception (Някой даже вече се оплака от това в друга тема по същата задача). Не е задължително да е stream api, просто го написах като лесен според мен вариант.  Ако е все пак се ползва  foreach той трябва да събере елементите, които ще трие в друг list и после да мине да ги трие във втори цикъл.  Ако се помисли сигурно и още варианти за решение ще излязат ...

0
kaloyannikov avatar kaloyannikov 531 Точки

Ще получи ConcurrentModificationException който може да се избегне по няколко начина

аз в тази задача конкретно го направих ->

 currentTrainer.getPokemonList().removeIf(pokemon -> pokemon.getHealth()<=0);

друг вариант е  да се направи iterator от листа примерно

Iterator<Pokemon> iterator = this.pokemonList.iterator();

и с цикъл while(iterator.hasNext())

вътре слагаш условието if(iterator.next().getHealth()<=0) и при него да маха покемон.

 

0
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.