Erro java.util.InputMismatchException

3 respostas
java
3648087
Tenho um código que ao executar verifica-se que tem um erro:

Exception in thread main java.util.InputMismatchException

at java.base/java.util.Scanner.throwFor(Scanner.java:947)

at java.base/java.util.Scanner.next(Scanner.java:1602)

at java.base/java.util.Scanner.nextInt(Scanner.java:2267)

at java.base/java.util.Scanner.nextInt(Scanner.java:2221)

at Main.readStepsLn(Main.java:458)

at Main.gameFunction(Main.java:496)

at Main.main(Main.java:532)

Como faço para corrigir? Neste projeto não devo usar nem in.hasNextInt, nem try/catch, nem integers, nem classes…

Aqui está o meu código:

/**
 * @author Inês Isabel Veiga da Silva (NUMBER)
 */

import java.util.Scanner;

//Default messages
final String MSG_OVER = "The game is over!";
final String MSG_LOST = "You lost the game!";
final String MSG_WON = "You won the game!";
final String MSG_NOT_OVER_YET = "The game was not over yet!";
final String MSG_END_WON = "Goodbye: You won the game!";
final String MSG_END_LOST = "Goodbye: You lost the game!";

final String ENEMY_TYPE_LOOPER = "looper";
final String ENEMY_TYPE_ZIGZAGGER = "zigzagger";

//Directions
final String RIGHT_DIRECTION = "right";
final String LEFT_DIRECTION = "left";
final String MSG_INVALID = "Invalid command";
final String QUIT_GAME = "quit";
String direction;

//Steps
int steps;

//Layouts
char [] layoutDungeonLevel1;
char [] layoutDungeonLevel2;
final int SIZE_LIMIT = 101;  //4 <= size <= 100
int layoutLengthLevel1;
int layoutLengthLevel2;

//Positions
int playerPosition;
int playerLevel;
int stairPosLevel1;
int stairPosLevel2;
int escapePosition;

//Arrays that define how many steps enemies will move
int[] looperSteps = {1};
int[] zigzaggerSteps = {1, 2, 3, 4, 5};
final int DEFAULT_CAPACITY = 2;

//Arrays that save the enemies positions and also the levels in which they are
int[] looperPositions;
int[] looperLevel;
int[] zigzaggerPositions;
int[] zigzaggerLevel;
int currentZigzaggerStep;

//Number of each enemy
int nLooper;
int nZigzagger;

//Treasures (arrays to that save the positions in each level, the number of treasures
//won and also the total in both levels)
int[] treasuresPositionsLevel1;
int[] treasuresPositionsLevel2;
int numTreasuresWon;
int totalTreasures;

//Boolean variables that will analyse the state's game
boolean didPlayerWon;
boolean isPlayerCaught;
boolean isOver;
boolean isValid;
boolean isQuit;

/**
 * Initializes each variable.
 */
void initState (){
    layoutLengthLevel1 = 0;
    layoutLengthLevel2 = 0;

    //The program stars with the positions of each element outside the layout.
    playerPosition = -1;
    playerLevel = -1;
    stairPosLevel1 = -1;
    stairPosLevel2 = -1;
    escapePosition = -1;

    looperPositions = new int [DEFAULT_CAPACITY];
    zigzaggerPositions = new int [DEFAULT_CAPACITY];
    looperLevel = new int [DEFAULT_CAPACITY];
    zigzaggerLevel = new int [DEFAULT_CAPACITY];
    currentZigzaggerStep = 0;
    nLooper = 0;
    nZigzagger = 0;

    treasuresPositionsLevel1 = new int [SIZE_LIMIT];
    treasuresPositionsLevel2 = new int [SIZE_LIMIT];
    numTreasuresWon = 0;
    totalTreasures = 0;

    //When the program starts the user haven't won the game yet or get caught, so the
    // boolean variable initialize 'false'
    didPlayerWon = false;
    isPlayerCaught = false;
    isOver = false;
    isValid = false;
    isQuit = false;
}

/**
 * Analyse the player, the enemies and the stairs positions.
 */
void analysePositions() {
    //Level 1
    for (int i = 0; i < layoutLengthLevel1; i++) {
        switch (layoutDungeonLevel1[i]) {
            case 'P' -> {
                playerPosition = i;
                playerLevel = 1;
            }
            case 'L' -> {
                looperPositions[nLooper] = i;
                looperLevel[nLooper] = 1;
                nLooper++;
            }
            case 'Z' -> {
                zigzaggerPositions[nZigzagger] = i;
                zigzaggerLevel[nZigzagger] = 1;
                nZigzagger++;
            }
            case 'S' -> stairPosLevel1 = i;
            case 'E' -> escapePosition = i;
        }
    }

    //Level 2
    for (int i = 0; i < layoutLengthLevel2; i++) {
        switch (layoutDungeonLevel2[i]) {
            case 'P' -> {
                playerPosition = i;
                playerLevel = 2;
            }
            case 'L' -> {
                looperPositions[nLooper] = i;
                looperLevel[nLooper] = 2;
                nLooper++;
            }
            case 'Z' -> {
                zigzaggerPositions[nZigzagger] = i;
                zigzaggerLevel[nZigzagger] = 2;
                nZigzagger++;
            }
            case 'S' -> stairPosLevel2 = i;
            case 'E' -> escapePosition = i;
        }
    }
}

/**
 * Reads the length layout of each level.
 */
void gameLayoutLength (){
    layoutLengthLevel1 = layoutDungeonLevel1.length;
    layoutLengthLevel2 = layoutDungeonLevel2.length;
}

/**
 * Analyse the treasures positions and calculates the total of treasures.
 */
void treasuresPositions (){
    //Level 1
    for (int i = 0; i < layoutLengthLevel1; i++) {
        if (layoutDungeonLevel1[i] == 'T') {
            treasuresPositionsLevel1[totalTreasures] = i;
            totalTreasures++;
        }
    }
    //Level 2
    for (int i = 0; i < layoutLengthLevel2; i++) {
        if (layoutDungeonLevel2[i] == 'T') {
            treasuresPositionsLevel2[totalTreasures] = i;
            totalTreasures++;
        }
    }
}

/**
 * Analyse the player position after the user command.
 */
void playerPositionUpdate() {
    switch (direction) {
        case RIGHT_DIRECTION -> {
            playerPosition += steps;

            if (playerLevel == 1) {
                if (playerPosition >= layoutLengthLevel1) { //Off limits
                    playerPosition = layoutLengthLevel1 - 1; //Stays in the last room
                }
            }
            else if (playerLevel == 2) {
                if (playerPosition >= layoutLengthLevel2) { //Off limits
                    playerPosition = layoutLengthLevel2 - 1; //Stays in the last room
                }
            }
        }

        case LEFT_DIRECTION -> {
            playerPosition -= steps;
            if (playerPosition < 0) { //Off
                playerPosition = 0; // Stays in the last room
            }
        }
    }
}

/**
* Analyse the case when the player uses the stairs.
*/
void stairsCase() {
    if (playerLevel == 1 && playerPosition == stairPosLevel1) {
        playerPosition = stairPosLevel2; //Moves the player to the stairs position (level 2)
        playerLevel = 2; //Player level changes to 2

    } else if(playerLevel == 2 && playerPosition == stairPosLevel2) {
        playerPosition = stairPosLevel1; //Moves the player to the stairs position (level 1)
        playerLevel = 1; //Player level changes to 1
    }
}

/**
 * Updates looper position.
 */
void looperPositionUpdate() {
    for (int i = 0; i < nLooper; i++) {

        if (looperLevel[i] == 1) {
            looperPositions[i] += looperSteps[0];  //Update position of looper
            if (looperPositions[i] >= layoutLengthLevel1)  //Off limits
                looperPositions[i] = looperPositions[i] % layoutLengthLevel1;
        }

        else if (looperLevel[i] == 2) {
            looperPositions[i] += looperSteps[0];
            if (looperPositions[i] >= layoutLengthLevel2)
                looperPositions[i] = looperPositions[i] % layoutLengthLevel2;
        }
    }
}

/**
 * Updates zigzagger position.
 */
void zigzaggerPositionUpdate() {
    //Cycle through zigzagger steps
    currentZigzaggerStep = currentZigzaggerStep % zigzaggerSteps.length;

    for (int i = 0; i < nZigzagger; i++) {

        if (zigzaggerLevel[i] == 1) {
            zigzaggerPositions[i] += zigzaggerSteps[currentZigzaggerStep];
            if (zigzaggerPositions[i] >= layoutLengthLevel1) { //Off limits
                zigzaggerPositions[i] = zigzaggerPositions[i] % layoutLengthLevel1;
            }
        }

        if (zigzaggerLevel[i] == 2) {
            zigzaggerPositions[i] += zigzaggerSteps[currentZigzaggerStep];
            if (zigzaggerPositions[i] >= layoutLengthLevel2) { //Off limits
                zigzaggerPositions[i] = zigzaggerPositions[i] % layoutLengthLevel2;
            }
        }
    }
    currentZigzaggerStep++;
}

/**
 * Counts the number of won treasures.
 */
void treasureCounter (char[] layout){
    if (layout [playerPosition] == 'T'){
        numTreasuresWon++;
        layout [playerPosition] = '.';  //No treasure ('T') = Empty room ('.')
    }
}

/**
 * Updates the game state.
 */
void analyseWinOrLoss() {
    //Check if the player is caught by any looper or zigzagger (if the player is in level 1)
    for (int i = 0; i < nLooper; i++) {
        if (playerPosition == looperPositions[i] && playerLevel == looperLevel[i]) {
            isPlayerCaught = true;
            isOver = true;
            didPlayerWon = false;
        }
    }
    //Check if the player is caught by any looper or zigzagger (if the player is in level 2)
    for (int i = 0; i < nZigzagger; i++) {
        if (playerPosition == zigzaggerPositions[i] && playerLevel == zigzaggerLevel[i]) {
            isPlayerCaught = true;
            isOver = true;
            didPlayerWon = false;
        }
    }
}

void analyseTreasuresWinOrLoss() {
    // Verifica se o jogador ganhou
    if (nLooper == 1 && nZigzagger == 1) {
        if (numTreasuresWon == totalTreasures && playerPosition == escapePosition &&
                escapePosition != -1 && playerPosition != looperPositions[0] &&
                playerPosition != zigzaggerPositions[0]) {
            didPlayerWon = true;
            isOver = true;
        }
    }

    if (nLooper == 2) {
        if (numTreasuresWon == totalTreasures && playerPosition == escapePosition &&
                escapePosition != -1 && playerPosition != looperPositions[0] &&
                playerPosition != looperPositions[1]) {
            didPlayerWon = true;
            isOver = true;
        }
    }

    if (nZigzagger == 2) {
        if (numTreasuresWon == totalTreasures && playerPosition == escapePosition &&
                escapePosition != -1 && playerPosition != zigzaggerPositions[0] &&
                playerPosition != zigzaggerPositions[1]) {
            didPlayerWon = true;
            isOver = true;
        }
    }
}

/**
 * Writes the win or lost message.
 */
void winOrLostAnswer (){
    if (isPlayerCaught)
        System.out.println(MSG_LOST);

    else if (didPlayerWon)
        System.out.println(MSG_WON);
}

/**
 * Writes a message if the game is not over yet.
 */
void gameNotOver() {
    System.out.println(MSG_NOT_OVER_YET);
}

/**
 * Writes a message if the game is over.
 */
void gameOver() {
    if (isOver)
        System.out.println(MSG_OVER);
}

/**
 * Writes a goodbye message depending on the situation.
 */
void goodbyeAnswer () {
    if (didPlayerWon)
        System.out.println(MSG_END_WON);

    if (isPlayerCaught)
        System.out.println(MSG_END_LOST);
}

/**
 * Writes the positions of each element.
 */
void programAnswer() {
    //Player
    System.out.println("Player: level " + playerLevel + ", room " + (playerPosition + 1) +
            ", treasures " + numTreasuresWon);

    // Primeiro imprime os inimigos de nível 1 (Zigzaggers e Loopers)
    for (int i = 0; i < nZigzagger; i++) {
        if (zigzaggerLevel[i] == 1) { // Somente Zigzaggers de nível 1
            System.out.println("Level 1 enemy: " + ENEMY_TYPE_ZIGZAGGER + ", room " +
                    (zigzaggerPositions[i] + 1));
        }
    }

    for (int i = 0; i < nLooper; i++) {
        if (looperLevel[i] == 1) { // Somente Loopers de nível 1
            System.out.println("Level 1 enemy: " + ENEMY_TYPE_LOOPER + ", room " +
                    (looperPositions[i] + 1));
        }
    }

    // Depois imprime os inimigos de nível 2 (Zigzaggers e Loopers)
    for (int i = 0; i < nZigzagger; i++) {
        if (zigzaggerLevel[i] == 2) { // Somente Zigzaggers de nível 2
            System.out.println("Level 2 enemy: " + ENEMY_TYPE_ZIGZAGGER + ", room " +
                    (zigzaggerPositions[i] + 1));
        }
    }

    for (int i = 0; i < nLooper; i++) {
        if (looperLevel[i] == 2) { // Somente Loopers de nível 2
            System.out.println("Level 2 enemy: " + ENEMY_TYPE_LOOPER + ", room " +
                    (looperPositions[i] + 1));
        }
    }
}

/**
 * Reads the layout.
 */
void readLayoutLn (Scanner in){
    layoutDungeonLevel2 = in.nextLine().toCharArray();
    layoutDungeonLevel1 = in.nextLine().toCharArray();
}

/**
 * Reads the length fo each layout.
 */
void numberOfSamples (){
    for (int i = 0; i <= SIZE_LIMIT; i++) {

        if (layoutDungeonLevel1[i] != 0)
            layoutLengthLevel1++;

        if (layoutDungeonLevel2[i] != 0)
            layoutLengthLevel2++;
    }
}

///**
// * Reads the direction.
// */
//String readDirectionLn (Scanner in){
//    return in.next();
//}
//
///**
// * Reads the steps.
// */
//int readStepsLn(Scanner in) { //edit
//    steps = in.nextInt();
//    in.nextLine();  //reads the line until the end
//    return steps;
//}


///**
//* Reads the direction and the steps.
//*/
//void readCommands (Scanner in){
//    direction = in.next();
//    steps = in.nextInt();
//    in.nextLine(); //reads the line until the end
//}

void analyseCommands(Scanner in) {
    while (!isValid) {
        direction = in.next();

        if (RIGHT_DIRECTION.equals(direction) || LEFT_DIRECTION.equals(direction)) {
            steps = in.nextInt();
            in.nextLine();
            isValid = true;
        }
        else if (QUIT_GAME.equals(direction)) {
            steps = 0;
            isQuit = true;
            isValid = true;
        }
        else {
            System.out.println(MSG_INVALID);
            in.nextLine();
        }
    }
}

/**
 * Calls the methods to update enemies and player position.
 */
void updatePositions (){
    looperPositionUpdate();
    zigzaggerPositionUpdate();

    if (playerLevel == 1) treasureCounter(layoutDungeonLevel1);
    if (playerLevel == 2) treasureCounter(layoutDungeonLevel2);
}

void quitCase(){
    if (!isOver)
        System.out.println(MSG_NOT_OVER_YET);

    if (didPlayerWon)
        System.out.println(MSG_END_WON);

    if (isPlayerCaught)
        System.out.println(MSG_END_LOST);
}


/**
 * Join all calls to make the game run normally.
 */
void gameFunction(Scanner in) {
    analyseCommands(in);

    while (!isOver && !isQuit){

        //If user writes 'right' or 'left'
        if (RIGHT_DIRECTION.equals(direction) || LEFT_DIRECTION.equals(direction)) {

            //Updates the positions
            playerPositionUpdate();
            stairsCase();
            updatePositions();

            //Analyse: victory or loss
            analyseWinOrLoss();
            analyseTreasuresWinOrLoss();
            winOrLostAnswer();


            if (!isPlayerCaught && !didPlayerWon) {
                programAnswer();
            }
        }
        if (!isOver && !isQuit) {
            isValid = false;
            analyseCommands(in);
        }
    }
}

void main() {
    Scanner in = new Scanner(System.in);

    initState();

    readLayoutLn(in);
    gameLayoutLength();
    analysePositions();
    treasuresPositions();

    gameFunction(in);

    if (!isQuit) {
        isValid = false;
        analyseCommands(in);

        if (QUIT_GAME.equals(direction)) {
            quitCase();
        } else {

            while (!QUIT_GAME.equals(direction)) {
                if (RIGHT_DIRECTION.equals(direction) || LEFT_DIRECTION.equals(direction)) {
                    gameOver();
                }
                if (!QUIT_GAME.equals(direction)) {
                    isValid = false;
                    analyseCommands(in);
                }
            }
            quitCase();
        }
    }
    else
        quitCase();

    in.close();
}

3 Respostas

staroski

Edite sua postagem e formate o código direito, utilize o botão “</>” pra isso, ou cole seu código entre marcadores, assim:
```java
seu código aqui
```

3648087

Já está.
Realmente fica mais visível do jeito que disse.

hugokotsubo

Não entendi. Vc diz que não pode usar, mas no método analyseCommands tem um nextInt.


Enfim, InputMismatchException ocorre quando o Scanner tenta ler determinada informação mas ela não corresponde ao tipo/formato esperado. Se o problema foi no nextInt, é porque ele tentou ler um número, mas a informação digitada/disponível não é um número.

Talvez - e esse é um grande chute, pois vc não disse como está testando o programa, quais dados digitou, etc - o problema ocorra porque vc está misturando nextLine com next e nextInt. Tem uma descrição bem detalhada sobre isso no link abaixo:

E lá também cita as formas de resolver (resumindo, para ler dados do teclado, use nextLine e converta para os tipos que precisar). Talvez seja isso (e sem mais detalhes sobre como vc está testando, é o máximo que dá pra sugerir).

Criado 23 de outubro de 2024
Ultima resposta 23 de out. de 2024
Respostas 3
Participantes 3