Оптимизация кода программы

206
31 мая 2018, 05:20

Всем привет. Недавно начал свой путь в освоении Java. Написал небольшую програмку по следующему условию:

Герой компьютерной игры, обладающий силой в 25 баллов, находится в круглом зале, из которого ведут 10 закрытых дверей. За каждой дверью героя ждет либо магический артефакт, дарующий силу от 10 до 80 баллов, либо монстр, имеющий силу от 5 до 100 баллов, с которым герою нужно сразиться.

В моем случае игра считается выигранной, если все двери открыты и сила героя больше 0. Я осваиваю ООП, поэтому вопрос следующий:

  1. Реализация кода соответствует основным принципам ООП?
  2. Если нет, укажите на недостатки.

P.S. В классе doors два массива ArrayList объявлены как глобальные переменные. А если их объявить в методе getDoor(), то они работают некорректно (данные не заносятся в массив и не удаляются из него). Почему так происходит, ведь эти массивы используются только в этом методе или я не прав?

class main

public class Hero_and_Doors {
    static boolean first = true;
    public static void main(String[] args) {
        int countOpenDoors = 0;
        doors doorsObject = new doors();
        do {
            doorsObject.getDoor();
            first = false;
            countOpenDoors ++;
        }while(countOpenDoors != 10);
        System.out.println("Congratulation you're win");
   }
}

class doors

import java.util.Random;
import java.util.Scanner;
import java.util.ArrayList;
public class doors {
private hero heroObject = new hero();
private monster monsterObject = new monster();
private ArrayList<Integer> openDoors = new ArrayList<>(10);
private ArrayList<String> closeDoors = new ArrayList<>();
private void setCloseDoor(){
    for(int i = 0; i < 10; i++){
        closeDoors.add(Integer.toString(i + 1));
    }
}
public void getDoor() {
    int pick;                                           // number of door
    String[] choice = {"magic artifact", "monster"};    // what you'll see behind the doors
    if(Hero_and_Doors.first)
        setCloseDoor();
    System.out.println("Which door do you choose?");
    System.out.println("You may to open the next door: " + closeDoors.toString());
    Scanner scn = new Scanner(System.in);
    pick = scn.nextInt();
    // You must input value from 1 to 10
    int permit = 0;
    do {
        if(pick >= 1 && pick <= 10 )
            permit = 1;
        while (pick < 1 || pick > 10) {
            permit = 0;
            System.out.println("Oops, it seems you made a mistake with door, let's try once again.\n");
            System.out.println("Which door do you choose?");
            System.out.println("You may to open the next door: " + closeDoors.toString());
            pick = scn.nextInt();
        }
        // If door have opened you can't open it twice
        while (openDoors.contains(pick)) {
            permit = 0;
            System.out.println(pick + " door have been opened, please open other door\n");
            System.out.println("Which door do you choose?");
            System.out.println("You may to open the next door: " + closeDoors.toString());
            pick = scn.nextInt();
        }
    }while(permit == 0);
    openDoors.add(pick);                                    // add opened door in array
    closeDoors.remove(Integer.toString(pick));              // delete opened door from array
    // what will be from the door?
    Random rnd = new Random();
    int temp = rnd.nextInt(2);
    System.out.println("You opened door number " + pick + ". From this door you see a " + choice[temp]);
    // If this a magic artifact
    if(temp == 0) {
        // If you opened first door
        if(Hero_and_Doors.first){
            heroObject.setHeroStrength();
        }
        // For not first time
        heroObject.findArtifact();
    }
    // If this a monster
    if(temp == 1) {
        // If you opened first door
        if(Hero_and_Doors.first){
            heroObject.setHeroStrength();
        }
        // For not first time
        monsterObject.findMonster();
        System.out.println("Strength hero = " + heroObject.getHeroStrength() + ". Strength monster = " + monsterObject.getMonsterStrength());
        fight();
        System.out.println("Strength hero after fighting = " +  fight());
        monster.winMonster(fight());
    }
    System.out.println("");
}
private int fight(){
    return heroObject.getHeroStrength() - monsterObject.getMonsterStrength();
}

}

class hero

import java.util.Random;
public class hero {
    private final int initHeroStrength = 25;
    private int heroStrength;
    // For first opening door strength of hero is set by default
    public void setHeroStrength() {
        this.heroStrength = initHeroStrength;
    }
    // For other opening
    private void setHeroStrength(int heroStrength) {
        this.heroStrength += heroStrength;
    }
    // If behind the door there is an artifact
    public void findArtifact(){
        Random rnd = new Random();
        System.out.println("Strength hero before get power from artifact = " + getHeroStrength() + ".");
        setHeroStrength(10 + rnd.nextInt(71));
        System.out.println("Strength hero after get power from artifact " + this.heroStrength + ".");
    }
    public int getHeroStrength(){
        return heroStrength;
    }
}

class monster

import java.util.Random;
public class monster {
    private int monsterStrength;
    private void setMonsterStrength(int monsterStrength) {
        this.monsterStrength = monsterStrength;
    }
    // If behind the door there is an monster
    public void  findMonster(){
        Random rnd = new Random();
        setMonsterStrength(5 + rnd.nextInt(96));
    }
    public int getMonsterStrength() {
        return monsterStrength;
    }
    // If Strength of monster bigger than hero, you lose
    public static void winMonster(int heroStrength){
        if(heroStrength < 0){
            System.out.println("You lose");
            System.exit(100);
        }
    }
}
Answer 1

В вашем случае я бы делал так:

Game.java

public class Game {
    private Hero hero;
    private Hall circle_hall;
    public Game(Hero hero, Hall hall) {
        // создать героя и главный зал
    }
    public void startGame() {
        // Открыть все двери
    }
    public int getGameStatus() {
        // тут статус игры определяется, т.е. пускай вы возвратите 1, если игра ещё не начата, 2 если выиграна, 3 если проиграна и тд.
    }
    // так же getter-ы и sеtter-ы для наших полей (hero, circle_hall)
}

Hero.java

public class Hero{
    private String name;
    private int strength;
    private static final String defaultName = "Vasia Pupkin";
    private static final int strength = 25;
    public Hero() {
        // присвоить дефолтные значения
    }
    public Hero(String name, int strength) {
        // дать герою имя, присвоить силу
    }    
    // так же getter-ы и sеtter-ы для наших полей
}

Hall.java

public class Hall {
    private Door[] doors;
    public Hall() {
        // создать 10 дверей
    }
    public Hall(Door[] doors) {
        // в this.doors положить doors
    }
    public void openDoor(int doorIndex, Hero hero) {
        // открыть дверь под номером doorIndex
    }
    // так же getter-ы и sеtter-ы для наших полей
}

Door.java

public class Door {
    private Surprise surprise;
    public Door() {
        // создать дверь с кем угодно за ней
    }
    public Door(Surprise surprice){
        /* присвоить "сюрприз"
        тут используется полиморфизм. Cуть в том, что сюрпризом может быть 
        что угодно, как монстр, так и артефакт. Т.е. чтобы запустить этот 
        конструктор вы должны создать объект класса, который импелентирует 
        интерфейс Surprise (Monster или Artefact). 
        Т.е. где-то вы создатите монстра :
        Monster monster = new Monster("Alf", 100);
        а потом дверь:
        Door door = new Door(monster);
        и при попытке открытия двери:
        door.open(someHero);
        вы запустите метод action для монстра */
    }
    void open(Hero hero) {
        surprice.action(hero);
    }
    // так же getter-ы и sеtter-ы для наших полей
}

Surprise.java

// По сути это могло бы быть абыстрактным классом, но я сделал интерфейс
public interface Surprise {
    void action(Hero hero);
}

Monster.java

pubic class Monster implements Surprise {
    private String name;
    private int strength;
    private static final String defaultName = "Beetlejuice";
    private static final int strength = 10;
    public Monster() {
        // присвоить дефолтные значения
    }
    public Monster(String name, int strength) {
        // дать имя монстру и присвоить силу
    }
    void action(Hero hero) {
        // Прописать взаимодействие монстра с героем
    }
    // так же getter-ы и sеtter-ы для наших полей
}

Artifact.java

pubic class Artifact implements Surprise {
    private String name;
    private int strength;
    private static final String defaultName = "One Ring";
    private static final int strength = 50;
    public Artifact() {
        // присвоить дефолтные значения
    }
    public Artifact(String name, int strength) {
        // дать имя артефакту и присвоить мощь
    }
    void action(Hero hero) {
        // Прописать взаимодействие артефакта с героем
    }
    // так же getter-ы и sеtter-ы для наших полей
}
READ ALSO
ActionBar цвет фона [дубликат]

ActionBar цвет фона [дубликат]

На данный вопрос уже ответили:

214
Интервал между элементами RecyclerView

Интервал между элементами RecyclerView

Как увеличить отступ между элементами RecyclerView? У меня они находятся слишком близкоКак увеличь интервал между ними?

178
Как передать значение из двух разных активностей в третью?

Как передать значение из двух разных активностей в третью?

Допустим, я передаю из активности 1 в активность 3 некоторое значениеЗатем я передаю из активности 2 в активность 3 некоторое значение

171
POST запрос retrofit

POST запрос retrofit

Столкнулся с проблемой POST запроса, когда сервер посылает 1 строку:

221