Untitled

 avatar
unknown
java
5 months ago
12 kB
3
Indexable
/**
 * @author Simão Gonçalves
 */



import java.util.Scanner;

final char TREASURE_ROOM_SYMBOL = 'T';
final char LOOPER_ROOM_SYMBOL = 'L';
final char STARTING_POSITION_SYMBOL = 'P';
final char ESCAPE_ROOM_SYMBOL = 'E';
final char STAIR_ROOM_SYMBOL = 'S';
final char ZIGZAGGER_ROOM_SYMBOL = 'Z';
final char EMPTY_ROOM_SYMBOL = '.';
final int LEVEL1 = 0;
final int LEVEL2 = 1;
final int NUMBER_OF_LEVELS = 2;
final int looperSteps = 1;

final String MOVE_RIGHT = "right";
final String MOVE_LEFT = "left";
final String QUIT = "quit";
final String PLAYER_LEVEL = "Player: level ";
final String PLAYER_ROOM = ", room ";
final String PLAYER_TREASURES = ", treasures ";
final String ENEMY_LEVEL = "Level ";
final String ENEMY = " enemy: ";
final String ENEMY_ROOM = ", room ";
final String LOOPER = "looper";
final String ZIGZAGGER = "zigzagger";
final String INVALID_COMMAND = "Invalid command";
final String AFTER_END_GAME = "The game is over";
final String LOST_THE_GAME_MESSAGE = "You lost the game!";
final String WON_THE_GAME_MESSAGE = "You won the game!";
final String GOODBYE_WIN = "Goodbye: You won the game!";
final String GOODBYE_LOSS = "Goodbye: You lost the game!";
final String GOODBYE_QUIT = "The game was not over yet!";


char[][] dungeon = new char[NUMBER_OF_LEVELS][];
char[][] enemyPositions = new char[NUMBER_OF_LEVELS][];
int zigzaggerSteps;
int totalTreasures;
int treasuresCollected;
int currentRoom;
int currentLevel;
int[] escapePosition = new int[2];
boolean gameOver;
boolean quitGame;
boolean winGame;
boolean lostTheGameAnnounced = false;
boolean winTheGameAnnounced = false;



//Este método tem como função reiniciar/inicializar as variáveis globais do jogo, de forma a poder iniciá-lo
void initState() {
    treasuresCollected = 0;
    gameOver = false;
    winGame = false;
    currentRoom = 0;
    currentLevel = 0;
    quitGame = false;
    winTheGameAnnounced = false;
    lostTheGameAnnounced = false;
    zigzaggerSteps = 1;
    countTotalTreasures();
    findPositions();

}

/*Este método tem como função encontrar as posição inicial do jogador e posição da saída recorrendo a do while loops que
percorrem os dois níveis e todas as salas à procura de cada uma dessas posições, acabando de iterar quando isso acontece,
guardando a posção inicial em duas variáveisdistintas que correspondem ao nível atual e à sala atual e
a posição de saída num vetor unidimensional com duas posições
 */
void findPositions() {
    boolean foundStartingPosition = false;
    boolean foundEscapePosition = false;
    int i = 0;
    do {
        int j = 0;
        do {
            char symbol = dungeon[i][j];
            if (symbol == STARTING_POSITION_SYMBOL) {
                currentLevel = i;
                currentRoom = j;
                foundStartingPosition = true;
            }
            if (symbol == ESCAPE_ROOM_SYMBOL) {
                escapePosition[0] = i;
                escapePosition[1] = j;
                foundEscapePosition = true;
            }
            if (foundStartingPosition && foundEscapePosition) {
                break;
            }
            j++;
        } while (j < dungeon[i].length);
        if (foundStartingPosition && foundEscapePosition) {
            break;
        }
        i++;
    } while (i < dungeon.length);
}

/*Este método conta todos os tesouros do mapa iterando com um for loop todas as salas de cada nível do mapa e adicionando
um valor à contagem total dos tesouros do mapa cada vez que encontra um
 */
void countTotalTreasures() {
    totalTreasures = 0;
    for (int i = 0; i < dungeon.length; i++) {
        for (int j = 0; j < dungeon[i].length; j++) {
            if (dungeon[i][j] == TREASURE_ROOM_SYMBOL) {
                totalTreasures++;
            }
        }
    }
}

void playGame(Scanner scanner) {

    while (!quitGame) {

        if (gameOver) {
            if (!lostTheGameAnnounced) {
                System.out.println(LOST_THE_GAME_MESSAGE);
                lostTheGameAnnounced = true;
            }

            handlePostGameInput(scanner);
            continue;
        }

        if (winGame) {
            if (!winTheGameAnnounced) {
                System.out.println(WON_THE_GAME_MESSAGE);
                winTheGameAnnounced = true;
            }

            handlePostGameInput(scanner);
            continue;
        }

        String direction = getInputDirection(scanner);
        if (direction.equals(QUIT)) {
            quitGame = true;
            break;
        }

        int steps = getInputSteps(scanner);
        processGameTurn(direction, steps);
    }

    endingGameMessage();

}

void endingGameMessage() {

    if (winGame) {
        System.out.println(GOODBYE_WIN);
    } else if (gameOver) {
        System.out.println(GOODBYE_LOSS);
    } else {
        System.out.println(GOODBYE_QUIT);
    }
}

void processGameTurn(String direction, int steps) {

    movePlayer(direction, steps);

    checkForTreasure();

    checkForStairs();

    moveEnemies();

    checkForEnemyCollision();


    if (checkWin()) {
        winGame = true;
    }
    if (!gameOver && !quitGame && !winGame)
        displayGameInformation();
}

void movePlayer(String direction, int steps) {
    if (direction.equals(MOVE_RIGHT)) {
        currentRoom = Math.min(currentRoom + steps, dungeon[currentLevel].length - 1);
    } else if (direction.equals(MOVE_LEFT)) {
        currentRoom = Math.max(currentRoom - steps, 0);
    }
}

void checkForTreasure() {
    if (dungeon[currentLevel][currentRoom] == TREASURE_ROOM_SYMBOL) {
        treasuresCollected++;
        dungeon[currentLevel][currentRoom] = EMPTY_ROOM_SYMBOL;
    }
}

void moveEnemies() {

    char[][] enemyPositionsBuffer = cloneEnemyPositions(enemyPositions);


    moveLoopers(enemyPositionsBuffer);


    moveZigzaggers(enemyPositionsBuffer);
    zigzaggerSteps++;

    for (int i = 0; i < enemyPositions.length; i++) {
        enemyPositions[i] = enemyPositionsBuffer[i].clone();
    }

}

char[][] cloneEnemyPositions(char[][] enemyPositions) {
    char[][] buffer = new char[enemyPositions.length][];
    for (int i = 0; i < enemyPositions.length; i++) {
        buffer[i] = enemyPositions[i].clone();
    }
    return buffer;
}

void moveLoopers(char[][] enemyPositionsBuffer) {
    int i = 0;
    int j = 0;


    do {

        while (j < dungeon[i].length) {
            if (enemyPositions[i][j] == LOOPER_ROOM_SYMBOL) {
                enemyPositionsBuffer[i][j] = EMPTY_ROOM_SYMBOL;


                if (j + looperSteps >= dungeon[i].length) {
                    enemyPositionsBuffer[i][0] = LOOPER_ROOM_SYMBOL;
                } else {
                    enemyPositionsBuffer[i][j + looperSteps] = LOOPER_ROOM_SYMBOL;
                }
            }
            j++;
        }

        j = 0;
        i++;
    } while (i < dungeon.length);
}

void moveZigzaggers(char[][] enemyPositionsBuffer) {
    int i = 0;
    int j = 0;

    do {
        while (j < dungeon[i].length) {
            if (zigzaggerSteps > 5) {
                zigzaggerSteps = 1;
            }
            if (enemyPositions[i][j] == ZIGZAGGER_ROOM_SYMBOL) {
                enemyPositionsBuffer[i][j] = EMPTY_ROOM_SYMBOL;


                int newPosition = j + zigzaggerSteps;


                while (newPosition >= dungeon[i].length) {
                    newPosition = newPosition % dungeon[i].length;
                }


                enemyPositionsBuffer[i][newPosition] = ZIGZAGGER_ROOM_SYMBOL;


            }
            j++;
        }
        j = 0; //
        i++; //
    } while (i < dungeon.length);
}

void checkForStairs() {
    if (dungeon[currentLevel][currentRoom] == STAIR_ROOM_SYMBOL) {
        if (currentLevel == LEVEL1)
            currentLevel = LEVEL2;
        else currentLevel = LEVEL1;

        currentRoom = findStairPosition(currentLevel);
    }
}

int findStairPosition(int level) {
    int i = 0;
    do {
        if (dungeon[level][i] == STAIR_ROOM_SYMBOL) {
            return i;
        }
        i++;
    } while (i < dungeon[level].length);

    return -1;
}

void checkForEnemyCollision() {

    if (currentLevel >= 0 && currentLevel < enemyPositions.length &&
            currentRoom >= 0 && currentRoom < enemyPositions[currentLevel].length) {

        char symbol = enemyPositions[currentLevel][currentRoom];
        if (symbol == LOOPER_ROOM_SYMBOL || symbol == ZIGZAGGER_ROOM_SYMBOL) {
            gameOver = true;
        }
    }
}

boolean checkWin() {
    return treasuresCollected == totalTreasures && dungeon[currentLevel][currentRoom] == ESCAPE_ROOM_SYMBOL &&
            !gameOver;
}

void shouldContinue(String direction) {
    if (direction.equals(QUIT)) {
        quitGame = true;
    }
}

int findLevelEnemy(int level) {

    int i = 0;
    do {

        char symbol = enemyPositions[level][i];
        if (symbol == LOOPER_ROOM_SYMBOL || symbol == ZIGZAGGER_ROOM_SYMBOL) {

            return i;
        }

        i++;
    } while (i < enemyPositions[level].length);
    return -1;
}

String getEnemyFromType(char type) {
    if (type == LOOPER_ROOM_SYMBOL) return LOOPER;
    else return ZIGZAGGER;
}

void displayGameInformation() {
    System.out.println(PLAYER_LEVEL + (currentLevel + 1) + PLAYER_ROOM + (currentRoom + 1) + PLAYER_TREASURES + treasuresCollected);
    displayLevelEnemy(LEVEL1);
    displayLevelEnemy(LEVEL2);
}

void displayLevelEnemy(int level) {
    int enemyPosition = findLevelEnemy(level);
    char enemySymbol = enemyPositions[level][enemyPosition];
    System.out.println(ENEMY_LEVEL + (level + 1) + ENEMY + getEnemyFromType(enemySymbol) + ENEMY_ROOM + +(enemyPosition + 1));
}

int getInputSteps(Scanner scanner) {
    return scanner.nextInt();
}

char[] readLevel(Scanner scanner) {
    String input = scanner.nextLine();
    return levelsInChar(input);
}

char[] levelsInChar(String sLevel) {
    char[] level;
    level = sLevel.toCharArray();
    return level;
}

String getInputDirection(Scanner scanner) {
    String direction = scanner.next();

    if (direction.equals(QUIT)) {
        shouldContinue(direction);
        return direction;
    }

    if (!gameOver && !winGame && !direction.equals(MOVE_RIGHT) && !direction.equals(MOVE_LEFT)) {
        scanner.nextLine();
        System.out.println(INVALID_COMMAND);
    }

    while (!gameOver && !winGame && !direction.equals(MOVE_RIGHT) && !direction.equals(MOVE_LEFT)) {
        direction = scanner.next();

        if (direction.equals(QUIT)) {
            shouldContinue(direction);
            return direction;
        } else if (!direction.equals(MOVE_RIGHT) && !direction.equals(MOVE_LEFT)) {
            scanner.nextLine();
            System.out.println(INVALID_COMMAND);
        }
    }

    return direction;
}

void handlePostGameInput(Scanner scanner) {

    String direction = getInputDirection(scanner);


    if (direction.equals(QUIT)) {
        quitGame = true;
    } else if (!direction.equals(MOVE_RIGHT) && !direction.equals(MOVE_LEFT)) {
        scanner.nextLine();
        System.out.println(INVALID_COMMAND);
    } else {
        scanner.nextLine();
        System.out.println(AFTER_END_GAME);
    }
}

void getTheDungeonLevels(Scanner scanner) {
    dungeon[1] = readLevel(scanner);
    dungeon[0] = readLevel(scanner);
}

void makeTheEnemiesPosition() {
    enemyPositions = new char[NUMBER_OF_LEVELS][];
    for (int i = 0; i < dungeon.length; i++) {
        enemyPositions[i] = new char[dungeon[i].length];
        for (int j = 0; j < dungeon[i].length; j++) {
            enemyPositions[i][j] = dungeon[i][j];
        }
    }
}

void main() {
    Scanner scanner = new Scanner(System.in);
    getTheDungeonLevels(scanner);
    initState();
    makeTheEnemiesPosition();
    playGame(scanner);
    scanner.close();
}

/**
 * Guardar posições dos inimigos numa array como fiz com o movePlayer e não ter de procurar todas as vezes
 *
 *
 *
 *
 *
 *
 *
 */

Editor is loading...
Leave a Comment