Word hunter can not find the word

6

Well, I'm trying to make a hunting game in java, but I can not find the word, can anyone help?

Follow the code:

import java.io.BufferedReader; 
import java.io.FileReader;
import java.io.IOException; 
import java.util.Scanner;

public class File {
public static void main(String[]args) throws Exception{
//        File arquivo = new File ("C:\teste01.txt");

FileReader arquivo = new FileReader ("C:\teste01.txt");
    BufferedReader br = new BufferedReader(arquivo);
    Scanner sc = new Scanner(System.in);

char[][] matriz = null;
    String entrada = null;
    int coluna = 0;
    boolean primeira = true;
    while (br.ready()){
        String linha = br.readLine();
        if(primeira) {
            String []b = linha.split(" ");
            int a = Integer.parseInt(b[0]);
            int d = Integer.parseInt(b[1]);
            matriz = new char[a][d];
            primeira = false;
        } else {
            char[] auxLinha = linha.toCharArray();

            for (int i = 0; i < auxLinha.length; i++) {
                matriz[coluna][i] = auxLinha[i];
            }

            coluna++;
        }
    }

    for (int i = 0; i < matriz.length; i++) {
        for (int j = 0; j < matriz[i].length; j++) {
            System.out.print(matriz[i][j]+" ");
        }
        System.out.println("\n");
    }

br.close();



   int i, j, k, n = 0, p = 0, t; //Contadores

int encontrada = 0; // SIM = 1. NÃO = 0.

 char palavra[][] = null ;
for (i = 0; i < p; i++)
     System.out.println("DIGITE A PALAVRA:\n");
        String palavraNextLine = sc.nextLine(); //Armazena as palavras que serão buscadas na matriz.

System.out.println("RESULTADO:\n");

for (k = 0; k < p; k++) //Para cada palavra
{
    //Inicialmente a palavra é considerada Não-Encontrada.
    encontrada = 0;

    for (i = 0; i < n; i++) //Para cada linha da matriz
    {
        for (j = 0; j < n; j++) //Para cada coluna da matriz
        {
            if (palavra[k][0] == matriz[i][j]) //Se a primeira letra for encontrada
            {
                if (palavra[k][1] == matriz[i - 1][j]) //Se a segunda letra for encontrada acima (Norte)
                {
                    encontrada = 1;

                    for (t = 0; t < (palavra[k]).length; t++)
                        if (palavra[k][t] != matriz[i - t][j])
                            encontrada = 0;

                    if (encontrada == 1){
                        break;
                }else{
                    return;
                    }
                }

                if (palavra[k][1] == matriz[i + 1][j]) //Se a segunda letra for encontrada abaixo (Sul)
                {
                    encontrada = 1;

                    for (t = 0; t < (palavra[k].length); t++)
                        if (palavra[k][t] != matriz[i + t][j])
                            encontrada = 0;

                     if (encontrada == 1){
                        break;
                }else{
                    return;
                    }
                }

                if (palavra[k][1] == matriz[i][j + 1]) //Se a segunda letra for encontrada a direita (Leste)
                {
                    encontrada = 1;

                    for (t = 0; t < (palavra[k].length); t++)
                        if (palavra[k][t] != matriz[i][j + t])
                            encontrada = 0;

                     if (encontrada == 1){
                        break;
                }else{
                    return;
                    }
                }

                if (palavra[k][1] == matriz[i][j - 1]) //Se a segunda letra for encontrada a esquerda (Oeste)
                {
                    encontrada = 1;

                    for (t = 0; t < (palavra[k].length); t++)
                        if (palavra[k][t] != matriz[i][j - t])
                            encontrada = 0;

                    if (encontrada == 1){
                        break;
                }else{
                    return;
                    }
                }

                if (palavra[k][1] == matriz[i - 1][j + 1]) //Se a segunda letra for encontrada acima-direita (Nordeste)
                {
                    encontrada = 1;

                    for (t = 0; t < (palavra[k].length); t++)
                        if (palavra[k][t] != matriz[i - t][j + t])
                            encontrada = 0;

                     if (encontrada == 1){
                        break;
                }else{
                    return;
                    }
                }

                if (palavra[k][1] == matriz[i - 1][j - 1]) //Se a segunda letra for encontrada acima-esquerda (Noroeste)
                {
                    encontrada = 1;

                    for (t = 0; t < (palavra[k].length); t++)
                        if (palavra[k][t] != matriz[i - t][j - t])
                            encontrada = 0;

                    if (encontrada == 1){
                        break;
                }else{
                    return;
                    }
                }

                if (palavra[k][1] == matriz[i + 1][j + 1]) //Se a segunda letra for encontrada abaixo-direita (Sudeste)
                {
                    encontrada = 1;

                    for (t = 0; t < (palavra[k].length); t++)
                        if (palavra[k][t] != matriz[i + t][j + t])
                            encontrada = 0;

                    if (encontrada == 1){
                        break;
                }else{
                    return;
                    }
                }

                if (palavra[k][1] == matriz[i + 1][j - 1]) //Se a segunda letra for encontrada abaixo-esquerda (Sudoeste)
                {
                    encontrada = 1;

                    for (t = 0; t < (palavra[k].length); t++)
                        if (palavra[k][t] != matriz[i + t][j - t])
                            encontrada = 0;
                     if (encontrada == 1){
                        break;
                }else{
                    return;
                    }
                }
            }
        }

                     if (encontrada == 1){
                        break;
                }else{
                    return;
                    }
                }
    }

    //Depois da verificação ele diz se a palavra foi encontrada ou não, então passa para a verificação da próxima palavra.
    if (encontrada == 1){
        System.out.println(" PALAVRA ENCONTRADA\n");
    }else{
        System.out.println(" PALAVRA NAO ENCONTRADA\n");
}
}
}
    
asked by anonymous 15.04.2015 / 21:18

2 answers

11
  • Use type boolean ! He is your friend and helps! Do not use int with 0 and 1 to represent true / false or yes / no values.

  • Learn how to indent the code. Just to see how you have positioned the else blocks, it gives me to understand that you put them in the wrong place and with that, you end up misunderstanding your own code.

  • That from here, which appears repeated nine times in your code DOES NOT do what you want:

            if (encontrada == 1) {
                break;
            } else {
                return;
            }
    

    In particular, return within the main method causes your program to abort immediately, regardless of whether or not it has found the word. In the case of your program, you should not use return anywhere.

  • You do not check the boundaries of the array before accessing its elements, and as a result will have some IndexOutOfBoundsException . For example, in this line:

    if (palavra[k][1] == matriz[i - 1][j]) //Se a segunda letra for encontrada acima (Norte)
    

    Guess what will happen if i has a value of 0? The correct thing is to check this before attempting to access the index:

    if (i > 0 && palavra[k][1] == matriz[i - 1][j]) //Se a segunda letra for encontrada acima (Norte)
    
  • You can name your for , while , and do-while loops. For example:

    a: for (int i = 0; i < n; i++) {
        b: for (int j = 0; j < n; j++) {
            // ... blablabla
            break a; // Interrompe o laço a (e também o laço b).
            // ... blablabla
        }
    }
    

    Using this, the logic of your program can be simplified a bit. The same goes for continue .

  • Giving your class name to File is a bad idea, after all this will give you a headache when you need the java.io.File class. Use a different name, such as CacaPalavras .

  • Use the try-with-resources syntax to read data from files, just like you do with your BufferedReader .

  • Prefer to declare the variables at the point where they will be used (within for ) than all of them together outside. The golden rule is not to let them have a larger scope than necessary.

  • The algorithm is much simpler if you break it down into several methods.

  • 15.04.2015 / 23:43
    9

    An object-oriented approach

    This problem can also be solved with a bit of good old object orientation, decreasing code repetition and the amount of loops and ifs / strong> in order to facilitate development and have a simpler end result:

    public class CacaPalavras {
    
        public static boolean palavraEncontrada(char[][] tabuleiro, String palavra) {
    
            for (int posicaoY = 0; posicaoY < tabuleiro.length; posicaoY++) {
    
                for (int posicaoX = 0; posicaoX < tabuleiro[posicaoY].length; posicaoX++) {
    
                    if (tabuleiro[posicaoY][posicaoX] == palavra.charAt(0)) {
    
                        for(Direcao direcao: Direcao.values()) {
                            if (TabuleiroNavegavel.existePalavra(palavra, tabuleiro, direcao, 
                                    posicaoY, posicaoX)) {
                                return true;
                            }
                        }
                    }
                }
            }
            return false;
        }
    }
    

    I used the same logic as you proposed: scroll through the board from left to right and from top to bottom, and when you find a letter that matches the first letter of the searched word, you scroll through the board in many different directions to see if the whole word is found.

    The rest of the code that makes the magic happen is below:

    class TabuleiroNavegavel {
        public static boolean existePalavra(String palavra, char[][] tabuleiro, 
                        Direcao direcao, int posicaoInicialY, int posicalInicialX) {
    
            StringBuilder palavraEncontrada = new StringBuilder();
    
            NavegadorLetras letras = direcao.letras(tabuleiro, 
                                        posicaoInicialY, posicalInicialX);
    
            int qtdLetrasLidas = 0;
    
            while(letras.temProxima() && qtdLetrasLidas <= palavra.length()) {
                palavraEncontrada.append(letras.proxima());
                qtdLetrasLidas++;
            }
            return palavraEncontrada.toString().equals(palavra);
        }
    }
    
    interface NavegadorLetras {
        boolean temProxima();
        char proxima();
    }
    
    interface LetrasNavegaveis {
        NavegadorLetras navegador(final char[][] tabuleiro, 
                final int posicaoInicialY, final int posicalInicialX);
    }
    
    enum Direcao {
        LESTE(new Leste()), 
        SUDESTE(new Sudeste()),
        SUL(new Sul()),
        NORDESTE(new Nordeste());
    
        private LetrasNavegaveis letrasNavegaveis;
    
        Direcao(LetrasNavegaveis letrasNavegaveis) {
            this.letrasNavegaveis = letrasNavegaveis; 
        }
        public NavegadorLetras letras(char[][] tabuleiro, 
                                int posicaoInicialY, int posicalInicialX){
            return letrasNavegaveis.navegador(tabuleiro, posicaoInicialY, posicalInicialX);
        }
    }
    
    class Leste implements LetrasNavegaveis {
    
        public NavegadorLetras navegador(final char[][] tabuleiro, 
                                final int posicaoInicialY, final int posicalInicialX) {
    
            return new NavegadorLetras() {
                int posicaoX = posicalInicialX; 
                int posicaoY = posicaoInicialY;
    
                public boolean temProxima() {
                    return posicaoX < tabuleiro[posicaoY].length;
                }
                public char proxima() {
                    char letra = tabuleiro[posicaoY][posicaoX];
                    posicaoX++;
                    return letra;
                }
            };
        }
    }
    
    class Sudeste implements LetrasNavegaveis {
    
        public NavegadorLetras navegador(final char[][] tabuleiro, 
                                final int posicaoInicialY, final int posicalInicialX) {
    
            return new NavegadorLetras() {
    
                int posicaoY = posicaoInicialY;
                int posicaoX = posicalInicialX;
    
                public boolean temProxima() {
                    return posicaoY >= 0 && posicaoY < tabuleiro.length
                        && posicaoX >= 0 && posicaoX < tabuleiro[posicaoY].length;
                }
                public char proxima() {
                    char letra = tabuleiro[posicaoY][posicaoX];
                    posicaoY++;
                    posicaoX++;
                    return letra;
                }
            };
        }
    }
    
    class Sul implements LetrasNavegaveis {
    
        public NavegadorLetras navegador(final char[][] tabuleiro, final int posicaoInicialY,
                                final int posicalInicialX) {
    
            return new NavegadorLetras() {
                int posicaoY = posicaoInicialY;
                int posicaoX = posicalInicialX;
    
                public boolean temProxima() {
                    return posicaoY >= 0 && posicaoY < tabuleiro.length;
                }
                public char proxima() {
                    char letra = tabuleiro[posicaoY][posicaoX];
                    posicaoY++;
                    return letra;
                }
            };
        }
    }
    
    class Nordeste implements LetrasNavegaveis {
    
        public NavegadorLetras navegador(final char[][] tabuleiro, 
                                final int posicaoInicialY, final int posicalInicialX) {
    
            return new NavegadorLetras() {
                int posicaoY = posicaoInicialY;
                int posicaoX = posicalInicialX;
    
                public boolean temProxima() {
                    return posicaoY >= 0 && posicaoY < tabuleiro.length
                        && posicaoX < tabuleiro[posicaoY].length;
                }
                public char proxima() {
                    char letra = tabuleiro[posicaoY][posicaoX];
                    posicaoY--;
                    posicaoX++;
                    return letra;
                }
            };
        }
    }
    

    An example consumer code:

    @Test
    public void cacaPalavras() {
    
        char[][] tabuleiro = new char[][] { 
                {'R','X','L','X','A'},
                {'X','A','U','X','X'},
                {'R','U','I','V','A'},
                {'X','A','Z','V','X'},
                {'C','X','A','X','A'}};
    
        assertTrue(CacaPalavras.palavraEncontrada(tabuleiro, "RUIVA"));
        assertTrue(CacaPalavras.palavraEncontrada(tabuleiro, "RAIVA"));
        assertTrue(CacaPalavras.palavraEncontrada(tabuleiro, "LUIZA"));
        assertTrue(CacaPalavras.palavraEncontrada(tabuleiro, "CAIXA"));
        assertFalse(CacaPalavras.palavraEncontrada(tabuleiro, "INEXISTENTE"));
    }
    

    You can wrap this code up with your logic to read the board from a file and request a list of user words: -)

    How to extend the solution

    See that I have only implemented the most western standard of reading, so to speak: east, south, southeast, northeast.

    But to implement more patterns is very simple. You do not need to enter code in the middle of a large, complex method or reprogram the program flow. Instead, you set a new reading direction in the enumeration and declare a specialized class to read in this direction.

    If you want to, for example, implement the southwest direction of reading, simply declare the following class:

    class Sudoeste implements LetrasNavegaveis {
    
        public NavegadorLetras navegador(final char[][] tabuleiro, final int posicaoInicialY,
                                final int posicalInicialX) {
    
            return new NavegadorLetras() {
                int posicaoY = posicaoInicialY;
                int posicaoX = posicalInicialX;
    
                public boolean temProxima() {
                    return posicaoY < tabuleiro.length
                        && posicaoX >= 0;
                }
                public char proxima() {
                    char letra = tabuleiro[posicaoY][posicaoX];
                    posicaoY++;
                    posicaoX--;
                    return letra;
                }
            };
        }
    }
    

    And add this new reading direction in the enumeration:

    SUDOESTE(new Sudoeste());
    

    Now, in the test below, the word "Red" will be found:

    @Test
    public void sudoeste() {
        char[][] tabuleiro = new char[][] { 
                {' ',' ',' ',' ','R'},
                {' ',' ',' ','U',' '},
                {' ',' ','I',' ',' '},
                {' ','V',' ',' ',' '},
                {'A',' ',' ',' ',' '}};
    
        assertTrue(CacaPalavras.palavraEncontrada(tabuleiro, "RUIVA"));
    }
    

    And soon: -)

    Conclusion

    I and many of our colleagues consider this code quite simple but I understand that you may not fully understand it yet.

    My suggestion, of course, is that you try to understand.

    Some Java features that were used there:

    • Interface
    • Enumeration.
    • Enumeration extension: I've added an attribute to each item in the enumeration, which is the specialized object to traverse the board in that direction.

    And although I do not consider total number of lines very important, I notice that although my code works it still has fewer rows than the original question code.

        
    16.04.2015 / 20:12