Индекс вне связанной исключительной ситуации Java - PullRequest
0 голосов
/ 10 июня 2018

У меня проблема с увеличением массива.

Мой логический класс игрока:

public class Player {
public static final List<String> pointsDescriptions  = Arrays.asList("0", "15", "30", "40");

private int score;

public int getScore(){return score;}

String name;
public String getName(){return name;}

public void winBall(){this.score += 1;}

public Player(String name){this.name = name;}

public String getScoreDescription(){return pointsDescriptions.get(score);}
}

Логика игры:

public class TennisGame {

private Player server;
private Player receiver;

public TennisGame(Player server, Player receiver){
    this.server = server;
    this.receiver = receiver;
}

public String getScore(){
    if (server.getScore() >= 3 && receiver.getScore() >= 3){
        if(Math.abs(receiver.getScore() - server.getScore()) >= 2){
            String winner;
            winner = getLeadPlayer().getName() + " won";
            return winner;
        } else if (server.getScore() - receiver.getScore() >= 1) {
            String serverAdvantage;
            serverAdvantage = "A" + ":" + receiver.getScoreDescription();
            return serverAdvantage;
        } else if (receiver.getScore() - server.getScore() >= 1) {
            String receiverAdvantage;
            receiverAdvantage = server.getScoreDescription() + ":" + "A";
            return receiverAdvantage;
        } else {
            String deuce;
            deuce = "40:40";
            return deuce;
        }
    } else {
        return server.getScoreDescription() + ":" + receiver.getScoreDescription();
    }
}

public Player getLeadPlayer() {
    return (server.getScore() > receiver.getScore()) ? server : receiver;
}
}

Игра в теннис, так что есть вероятность счета: PlayerOne: PlayerTwo ->40:40 -> PlayerOne winBall -> Преимущество: 40 -> PlayerTwo winBall -> 40:40 -> PlayerTwo winBall -> 40: преимущество

При увеличении счета для PlayerTwo я должен получить PlayerTwo Won, но вместо правильногоУ меня есть приращение:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
    at java.util.Arrays$ArrayList.get(Arrays.java:3841)
    at com.company.Main.Player.getScoreDescription(Player.java:30)
    at com.company.Main.TennisGame.getScore(TennisGame.java:23)
    at com.company.Main.Main.main(Main.java:33)

Я знаю, что проблема в длине массива, но я не знаю, как это исправить.

Код от основного:

Scanner s = new Scanner(System.in);
    Player server = new Player("server");
    Player receiver = new Player("receiver");
    TennisGame tennisGame = new TennisGame(server, receiver);

    System.out.println("Server=1");
    System.out.println("Server=2");
    System.out.println("Please enter the player that wins the point");
    System.out.println("The score is: " + tennisGame.getScore());

    do {
        tennisGame.getScore();
        String userInput = s.nextLine();
        if (userInput.equals("1")) {
            server.winBall();
        } else if (userInput.equals("2")) {
            receiver.winBall();
        } else {
            System.out.println("Wrong value, please enter 1 or 2");
        }
        System.out.println(tennisGame.getScore());
    } while (!(Math.abs(receiver.getScore() - server.getScore()) >= 2));

Ответы [ 2 ]

0 голосов
/ 10 июня 2018

Во-первых, у вас возникла логическая проблема:

} while (!(Math.abs(receiver.getScore() - server.getScore()) >= 2));

, если один игрок имеет преимущество в 2 очка, это не значит, что он выигрывает игру, так как счет может быть 30: 0, 0:30, 40:15 и т. Д.
Вместо этого я предлагаю сохранить статус игры внутри класса TennisGame:

public boolean isFinished;

public boolean isFinished() {
    return isFinished;
}

и установить его, когда один из игроков выиграет игру и использует ее.вот так:

} while(!tennisGame.isFinished)

Во-вторых, чтобы избежать сбоев и следовать логике игры в теннис, я предлагаю внести следующие изменения:

public static final List<String> pointsDescriptions  = Arrays.asList("0", "15", "30", "40", "A");

Также сделаны некоторые оптимизации, чтобы избежать использования многих переменных:

public String getScore(){
        String score;
        if (server.getScore() >= 3 && receiver.getScore() >= 3){
            if(Math.abs(receiver.getScore() - server.getScore()) >= 2){
                score = getLeadPlayer().getName() + " won";
                isFinished = true;
            } else if (server.getScore() - receiver.getScore() >= 1) {
                score = "A" + ":" + receiver.getScoreDescription();
            } else if (receiver.getScore() - server.getScore() >= 1) {
                score = server.getScoreDescription() + ":" + "A";
            } else {
                score = "40:40";
            }
        } else if (server.getScore() > 3 || receiver.getScore() > 3) {
            score = getLeadPlayer().getName() + " won";
            isFinished = true;
        } else {
            score = server.getScoreDescription() + ":" + receiver.getScoreDescription();
        }
        return score;
    }
0 голосов
/ 10 июня 2018

У вас есть логическая ошибка здесь,

if (server.getScore() >= 3 && receiver.getScore() >= 3){

ваш if будет введен, только если оба из server и receiver имеют оценку больше илиравно трем.Вы хотите ввести эту логику, когда либо равно true.Например,

if (server.getScore() >= 3 || receiver.getScore() >= 3){

Также , я бы посоветовал вам удалить временные переменные в ветвях return.Например,

if(Math.abs(receiver.getScore() - server.getScore()) >= 2){
    return getLeadPlayer().getName() + " won";
} else if (server.getScore() - receiver.getScore() >= 1) {
    return "A" + ":" + receiver.getScoreDescription();
} else if (receiver.getScore() - server.getScore() >= 1) {
    return server.getScoreDescription() + ":" + "A";
} else {
    return "40:40";
}

и , мы могли бы упростить , что далее с парой локальных переменных.И мы можем исключить некоторые из блоков else - так как мы return, когда условие выполняется.Мол,

public String getScore() {
    final int rScore = receiver.getScore(), sScore = server.getScore();
    if (sScore >= 3 || rScore >= 3) {
        if (Math.abs(rScore - sScore) >= 2) {
            return getLeadPlayer().getName() + " won";
        } else if (sScore - rScore >= 1) {
            return "A:" + receiver.getScoreDescription();
        } else if (rScore - sScore >= 1) {
            return server.getScoreDescription() + ":A";
        }
        return "40:40";
    }
    return server.getScoreDescription() + ":" + receiver.getScoreDescription();
}
...