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();
}