Java. Помогите связать три класса между собой с помощью переменных
Делаю проект, состоящий из пяти игр. На логику каждой игры - один класс. Есть класс App, есть Engine. По заданию в классе App - тупо список игр и вызов другого класса с логикой. В классе Engine должна быть общая логика игр.
В каждой игре 3 раунда. Последовательность происходящего:
- приветствие(общее)
- объяснение сути игры(разное для каждой игры)
- вопрос(математическое выражение/число - всегда разное)
- два варианта исхода (положительный, если ответ пользователя совпал с заранее вычисленным результатом / отрицательный, если пользователь ввел неверный ответ)
Пока код Engine выглядит так и не работает:
public class Engine {
public static String question;
public static String result;
public static String greeting;
public static int index = 0; //нужны для вычислений в классах
public static int sum = 0; //нужны для вычислений в классах
public static Random random = new Random();
public static Scanner scanner = new Scanner(System.in);
public static String userName;
public static String wrong = " is wrong answer ;(. Correct answer was ";
public static String wrong2 = "Let's try again, ";
public static int raunds = 0; //нужны для вычислений в классах
public static void comunication() {
System.out.println("");
System.out.println("Welcome to the Brain Games!");
System.out.print("May I have your name? ");
Scanner scanner = new Scanner(System.in);
String userName = scanner.next();
System.out.println("Hello, " + userName + "!");
if (App.choise().equals("2")) { //пытаюсь сослаться на метод, где я сначала задавал переменную
greeting = ParityCheck.greeting; //ссылка на отдельные значения в нужные классы, которые выведены в отдельные методы и посчитаны
question = Integer.toString(ParityCheck.question());
result = ParityCheck.result();
}
if (App.choise().equals("3")) {
Calculator.calculate(); //здесь и ниже в усл. конструкциях - старый синтаксис, еще не переделанный
}
if (App.choise().equals("4")) {
GCD.divide();
}
if (App.choise().equals("5")) {
Progression.progression();
}
if (App.choise().equals("6")) {
Prime.prime();
}
System.out.println(greeting);
for (var i = 0; i < 3; i++) {
System.out.println("Question: " + question);
System.out.print("Your answer: ");
String answer = scanner.next();
if (answer.equals(result)) {
System.out.println("Correct!");
} else {
System.out.println("'" + answer + "'" + wrong + "'" + result + "'");
System.out.println(wrong2 + userName);
break;
}
raunds++;
}
if (Engine.raunds == 3) {
System.out.println("Congratulations, " + userName + "!");
}
}
}
Ниже код класса App:
public class App {
static Scanner scan = new Scanner(System.in);
public static String choise() {
String userChoice = scan.next();
return userChoice;
}
public static void main(String[] args) {
System.out.println("Please enter the game number and press Enter.");
System.out.println("1 - Greet");
System.out.println("2 - Even");
System.out.println("3 - Calc");
System.out.println("4 - GCD");
System.out.println("5 - Progression");
System.out.println("6 - Prime");
System.out.println("0 - Exit");
System.out.print("Your choice: ");
choise();
Engine.comunication();
}
}
Код работает корректно до момента с выводом System.out.println(greeting). Это программа уже не делает. Понимаю, что видимо в переменной userChoice в методе choise() не остается значений пользователя, что он ввел и поэтому программа не может двигаться дальше, но как сделать так, чтоб оставались значения?
Так как мне очень нужны эти значения для работы условных конструкций и правильного вызова нужных значений из разных классов
Важно! Мне необходимо реализовать эту логику "в лоб", используя только статические методы (без абстракций, интерфейсой, ООП и пр.) Если не запрещено правилами, я приложу ссылку на свой гитхаб, там старая версия игры, когда класс App ссылается на каждую игру и в каждом игре прописана вся логика. Сейчас я хочу общую логику вынести в класс Engine, оставив в классах игр только вычисления. https://github.com/DEGTEVUWU/java-project-61
Ответы (1 шт):
Если я правильно понял, то вам надо прописать разную логику для разных игр. Почему бы не использовать для этого ООП?
Предлагаю следующую архитектуру:
- Класс
Appуправляет общим интерфейсом, выбором игры и т. п. - Класс
Engineимеет общие методы для каждой игры, которые переопределяются в дочерних классах (которые являются классами самих игр)
Поскольку все игры состоят из определённого числа шагов, то логику игры можно оставить внутри класса App, а в Engine хранить только информацию об игре и метод для проверки правильности ответа.
Реализуем класс Engine на основе указанных этапов:
// Так как Engine является лишь базовым классом
// сделаем его абстрактным, что бы его нельзя было создавать
abstract class Engine {
// Имя игры (по умолчанию - имя класса)
public String GetName() {return this.getClass().getSimpleName();}
// Описание игры
public abstract String GetDescription();
// Генерация и сохранение вопроса и ответа
public abstract void GenerateQuestion();
public abstract String GetQuestion();
public abstract boolean IsAnswerCorrect(String answer);
// Рандом (на всякий случай)
final Random random = new Random();
}
Для примера реализуем одну игру - калькулятор:
class Calculator extends Engine {
@Override
public String GetDescription() {
return "This is a calculator game. I'm write mathematical example and you provide answer.";
}
int num1 = 0;
int num2 = 0;
@Override
public void GenerateQuestion(){
num1 = random.nextInt(10);
num2 = random.nextInt(10);
}
@Override
public String GetQuestion(){
return num1 + " + " + num2 + " = ";
}
@Override
public boolean IsAnswerCorrect(String answer){
return answer.equals(Integer.toString(num1 + num2));
}
}
Теперь создадим класс App который будет хранить список игр
class App {
// Инициализируем App и запускаем Start()
public static void main(String[] args){
App app = new App();
app.Start();
}
public ArrayList<Engine> games = new ArrayList<Engine>();
public void Start(){
games.add(new Calculator());
}
}
Ну и реализовываем логику этапов игры:
class App {
// Инициализируем App и запускаем Start()
public static void main(String[] args){
App app = new App();
app.Start();
}
// Некоторые константы:
final String sucAns = "Good job!";
final String wrongAns = "Wrong... Try again next time!";
public ArrayList<Engine> games = new ArrayList<Engine>();
public void Start(){
Scanner in = new Scanner(System.in);
games.add(new Calculator());
// Выводим список игр и их индекс+1 (что бы отсчёт начинался с 1)
System.out.println("Please select game: ");
for (int i = 0; i < games.size(); i++){
System.out.println((i+1) + " - " + games.get(i).GetName());
}
System.out.println("0 - Exit");
int gameIndex = in.nextInt();
if (gameIndex == 0) {return;}
// Так как отсчёт игр начинался с одного
// Вычитаем единицу
Engine game = games.get(gameIndex-1);
// Выводим название и описание игры
System.out.println(game.GetName());
System.out.println(game.GetDescription());
// Генерируем вопрос
game.GenerateQuestion();
// Выводим вопрос
System.out.println("Question: " + game.GetQuestion());
// Запрашиваем ответ от пользователя
String ans = in.next();
// Проверяем, правильный ли ответ
boolean isCorrect = game.IsAnswerCorrect(ans);
if (isCorrect) { System.out.println(sucAns); }
else { System.out.println(wrongAns); }
}
}
Полный код можно запустить тут. Все комментарии там есть.
Надеюсь на этой основе вы сможете решить данную задачу более элегантным способом)