[RESOLVIDO] Jogo da Batalha Naval Simplificado [AJUDA]

12 respostas
N

Boa tarde.

Tenho que fazer o seguinte jogo mais estou com umas pequenas complicações que vou passar a explicar mais à frente:

[list]O Utilizador joga contra o Computador.
O objectivo é apenas afundar os barcos do computador no menor número de tentativas.
Ao contrário de um jogo real de Batalha Naval, o utilizador não coloca os seus barcos.
O computador coloca aleatoriamente 3 barcos de 3 numa grelha 7x7.
O computador pede uma tentativa e o utilizador digita “B3”, “F6”, etc.
O computador responde “Acertou”, “Falhou”, ou “Afundou”.
O jogo termina quando afunda os três barcos.
O utilizador é classificado através do número de tentativas gastas.
Pense que tipos de objectos o programa necessita para realizar o jogo.
Construa um programa usando interacção com o utilizador em modo de texto.
Como melhoramentos pode não contar tentativas em células já atingidas e usar nomes para os barcos.
[/list]

Eu utilizei 3 Classes: Barco, Grelha e a Classe Main TesteBatalhaNaval

Não faço a menor ideia como irei fazer os 3 barcos ocuparem 3 posições cada um na grelha (matriz [7][7]).
Utilizei um código para me gerar aleatoriamente as posições dos 3 barcos nas grelha, mas o problema é que cada barco só ocupa uma coordenada da grelha em vez de ocupar 3 coordenadas como me pede o exercício.

Para já são essas as minhas dúvidas.
Vou deixar aqui o código referente a cada classe que eu criei.
Gostava que me pudessem ajudar.
Obrigado.
Cumprimentos

public class Grelha {
    //instância da Classe Grelha
    private Object [][]mat = new Object[7][7];

    //método para colocar barcos
    public Object[][] colocarBarcos(Barco b[]) {
        int lin;
        int col;
        //atribuir aleatoriamente as coordenadas dos barcos
        for (int i = 0; i < b.length; i++) {
            lin = 0 + (int) (6*Math.random());
            col = 0 + (int) (6*Math.random());
            mat[lin][col]=b[i];//o mapa recebe um barco aletoriamente colocado
        }
        return mat;
    }
}
public class Barco {
    //váriável de classe

    //instãncias da Classe Barco
    private String nome;
    private boolean acerto;
    private String coordenadas;
    private int estadoDoBarco;
    private boolean afundou;

    //construtores
    public Barco(String nome) {
        this.nome = nome;
        this.acerto = false;
        this.coordenadas = "";
        this.estadoDoBarco = 3;
        this.afundou = false;
    }

    //Getter && Setter
    public boolean getAcerto() {
        return acerto;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getCoordenadas(Object[][] mat) {
        for (int i = 0; i < mat.length; i++) {
            for (int j = 0; j < mat[i].length; j++) {
                if (mat[i][j] != null) {
                    coordenadas = converterCoordenadas(i) + j;
                }
            }
        }
        return coordenadas;
    }

    public int getEstadoDoBarco() {
        return estadoDoBarco;
    }

//métodos
    
    //método para disparar
    public String disparar(String coord, Object[][] mapa) {
        coord.toUpperCase();//coordenadas por parâmetro
        char coord1 = coord.charAt(0);
        //conversão das coordenadas para int
        switch (coord1) {
            case 'A':
                coord1 = 0;
                break;
            case 'B':
                coord1 = 1;
                break;
            case 'C':
                coord1 = 2;
                break;
            case 'D':
                coord1 = 3;
                break;
            case 'E':
                coord1 = 4;
                break;
            case 'F':
                coord1 = 5;
                break;
            case 'G':
                coord1 = 6;
                break;
            default:
                String.format("Erro! Coordenada inválida. Coordenada 0 colocada por omissão");
                coord1 = 0;
        }
        int lin = (int)coord1;
        int col = (int) coord.charAt(1);
        String txt = "";
        acerto = verificarDisparo(lin, col, mapa);
        if (acerto == true) {
            estadoDoBarco--;
            txt = String.format("ACERTOU!");
            if (estadoDoBarco == 0) {
                afundou = true;
                txt = String.format("AFUNDOU!");
            }
        } else {
            txt = String.format("FALHOU!");
        }
        return txt;
    }

    //método para verificar o disparo
    private boolean verificarDisparo(int lin, int col, Object mapa[][]) {
        boolean flag = false;
        if (mapa[lin][col] != null) {
            flag = true;
        }
        return flag;
    }

    //método para converter as coordenadas
    private String converterCoordenadas(int i) {
        String txt="";
        switch (i) {
            case 0:
                txt = "A";
                break;
            case 1:
                txt = "B";
                break;
            case 2:
                txt = "C";
                break;
            case 3:
                txt = "D";
                break;
            case 4:
                txt = "E";
                break;
            case 5:
                txt = "F";
                break;
            case 6:
                txt = "G";
                break;
        }
        return txt;
    }
}
import javax.swing.JOptionPane;

public class TesteBatalhaNaval {

    public static void main(String[] args) {
        //instância de um vector de três barcos
        Barco vec[] = new Barco[3];

        //instância da Classe Grelha
        Grelha g1 = new Grelha();

        //mapa onde serão colocados os barcos aleatóriamente
        Object mapa[][] = new Object[7][7];

        //instânciação de 3 barcos da Classe Barco
        Barco b1 = new Barco("E.U.A.");
        Barco b2 = new Barco("AFEGANISTÃO");
        Barco b3 = new Barco("VENEZUELA");

        vec[0] = b1;
        vec[1] = b2;
        vec[2] = b3;

        int numTentativas = 0;

        mapa = g1.colocarBarcos(vec);//mapa com os barcos colocados aleatóriamente

        String finalizar = "";
        while ((vec[0].getEstadoDoBarco() > 0 && vec[1].getEstadoDoBarco() > 0 && vec[2].getEstadoDoBarco() > 0) || finalizar.equalsIgnoreCase("F")) {
            String coordenadas = JOptionPane.showInputDialog("Digite as coordenadas do alvo a abater: ");
            numTentativas++;
            for (int i = 0; i < mapa.length; i++) {
                if (vec[i].getEstadoDoBarco() > 0) {
                    JOptionPane.showMessageDialog(null, vec[i].disparar(coordenadas, mapa), "\nNúmero de tentativas utilizadas: %d", numTentativas);
                }
            }
            finalizar = JOptionPane.showInputDialog("Deseja tentar novamente ou continuar a jogar?\nT - Tentar Novamente\nF - Finalizar Jogo");
            if (finalizar.equalsIgnoreCase("F")) {
                JOptionPane.showMessageDialog(null, "Jogo finalizado!\n"
                        + "Coordenadas dos barcos: "
                        + vec[0].getNome() + " Coordenadas: " + vec[0].getCoordenadas(mapa)
                        + vec[2].getNome() + " Coordenadas: " + vec[1].getCoordenadas(mapa)
                        + vec[2].getNome() + " Coordenadas: " + vec[2].getCoordenadas(mapa));
            }
        }
    }
}

Quase me esquecia, quando mando correr o programa ele pede para eu inserir uma coordenada e eu insiro por exemplo A1 e ele gera o seguinte erro:

[list]run:

Exception in thread main java.lang.ArrayIndexOutOfBoundsException: 49

at Barco.verificarDisparo(Barco.java:102)

at Barco.disparar(Barco.java:85)

at TesteBatalhaNaval.main(TesteBatalhaNaval.java:35)

Java Result: 1

BUILD SUCCESSFUL (total time: 6 seconds)[/list]

12 Respostas

otaviojava

tenta ser o mais objetivo possível, assim fica mais fácil das pessoas te ajudarem,
sobre ocupar vários locais, tenta coloca o mesmo objeto em locais diferentes na matriz

N

Ok… vou tentar ser mais objectivo, mas amigo, pode dizer onde eu não fui suficientemente claro? Assim eu poderia começar por tornar essa parte mais objectiva.

Eu alterei a classe Grelha para para ela me colocar cada barco em 3 posições:

public class Grelha {
    //instância da Classe Grelha

    private Object[][] mat = new Object[7][7];

    //método para colocar barcos
    public Object[][] colocarBarcos(Barco b[]) {
        int lin, col, lin1=0, col1=0, lin2=0, col2=0;
        //atribuir aleatoriamente as coordenadas dos barcos
        for (int i = 0; i < b.length; i++) {
            lin = 0 + (int) (6 * Math.random());
            col = 0 + (int) (6 * Math.random());
            //para fazer o barco ocupar 3 posições na grelha
            switch (lin) {//para as linhas
                case 0:
                    lin1 = lin + 1;
                    lin2 = lin + 2;
                    break;
                case 1:
                    lin1 = lin - 1;
                    lin2 = lin + 1;
                    break;
                case 2:
                    lin1 = lin + 1;
                    lin2 = lin + 2;
                    break;
                case 3:
                    lin1 = lin + 1;
                    lin2 = lin + 2;
                    break;
                case 4:
                    lin1 = lin + 1;
                    lin2 = lin + 2;
                    break;
                case 5:
                    lin1 = lin + 1;
                    lin2 = lin + 2;
                    break;
                case 6:
                    lin1 = lin - 1;
                    lin2 = lin - 2;
                    break;
            }
            switch (col) {//para as colunas
                case 0:
                    col1 = col + 1;
                    col2 = col + 2;
                    break;
                case 1:
                    col1 = col - 1;
                    col2 = col + 1;
                    break;
                case 2:
                    col1 = col + 1;
                    col2 = col + 2;
                    break;
                case 3:
                    col1 = col + 1;
                    col2 = col + 2;
                    break;
                case 4:
                    col1 = col + 1;
                    col2 = col + 2;
                    break;
                case 5:
                    col1 = col + 1;
                    col2 = col + 2;
                    break;
                case 6:
                    col1 = col - 1;
                    col2 = col - 2;
                    break;
            }
            //o mapa recebe as 3 partes do barco aletoriamente colocado
            mat[lin][col] = b[i];
            mat[lin1][col1] = b[i];
            mat[lin2][col2] = b[i];
        }
        return mat;
    }
}

Mas quando corro o programa e insiro a primeira coordenada para disparar, por exemplo: A1 ele rebenta logo com o seguinte erro:

run:

Exception in thread main java.lang.ArrayIndexOutOfBoundsException: 49

at Barco.verificarDisparo(Barco.java:102)

at Barco.disparar(Barco.java:85)

at TesteBatalhaNaval.main(TesteBatalhaNaval.java:35)

Java Result: 1

BUILD SUCCESSFUL (total time: 4 seconds)

Eu quero que os barcos sejam colocados no mapa aleatóriamente, e quando faço o disparo ele diz que as coordenadas que eu coloquei lá são maiores que o limite do array, por isso acho que não estou a gerar bem os números aleatórios da colocação dos barcos para estarem num intervalo entre 0 e 6.

Agora já dá para ajudar?
Cumprimentos

N

Bem fiz umas alterações na Classe Main TesteBatalhaNaval e na Classe Grelha:

import javax.swing.JOptionPane;

public class TesteBatalhaNaval {

    public static void main(String[] args) {
        //instância de um vector de três barcos
        Barco vec[] = new Barco[3];

        //instância da Classe Grelha
        Grelha g1 = new Grelha();

        //mapa onde serão colocados os barcos aleatóriamente
        Object mapa[][] = new Object[7][7];

        //instânciação de 3 barcos da Classe Barco
        Barco b1 = new Barco("E.U.A.");
        Barco b2 = new Barco("AFEGANISTÃO");
        Barco b3 = new Barco("VENEZUELA");

        vec[0] = b1;
        vec[1] = b2;
        vec[2] = b3;

        int numTentativas = 0;

        mapa = g1.colocarBarcos(vec);//mapa com os barcos colocados aleatóriamente

        String finalizar = "";
        while ((vec[0].getEstadoDoBarco() > 0 && vec[1].getEstadoDoBarco() > 0 && vec[2].getEstadoDoBarco() > 0) || finalizar.equalsIgnoreCase("F")) {
            String coordenadas = JOptionPane.showInputDialog("Combinações de coordenadas possíveis:"
                    + "\nLinhas:    A B C D E F G"
                    + "\nColinhas:  0 1 2 3 4 5 6"
                    + "\nDigite as coordenadas do alvo a abater: ");
            char coord1 = coordenadas.charAt(0);
            char coord2 = coordenadas.charAt(1);
            numTentativas++;
            for (int i = 0; i < mapa.length; i++) {
                if (vec[i].getEstadoDoBarco() > 0) {
                    JOptionPane.showMessageDialog(null, vec[i].disparar(coord1,coord2, mapa), "\nNúmero de tentativas utilizadas: %d", numTentativas);
                }
            }
            finalizar = JOptionPane.showInputDialog("Deseja tentar novamente ou continuar a jogar?\nT - Tentar Novamente\nF - Finalizar Jogo");
            if (finalizar.equalsIgnoreCase("F")) {
                JOptionPane.showMessageDialog(null, "Jogo finalizado!\n"
                        + "Coordenadas dos barcos: "
                        + vec[0].getNome() + " Coordenadas: " + vec[0].getCoordenadas(mapa)
                        + vec[2].getNome() + " Coordenadas: " + vec[1].getCoordenadas(mapa)
                        + vec[2].getNome() + " Coordenadas: " + vec[2].getCoordenadas(mapa));
            }
        }
    }
}
public class Grelha {
    //instância da Classe Grelha

    private Object[][] mat = new Object[7][7];

    //método para colocar barcos
    public Object[][] colocarBarcos(Barco b[]) {
        int lin, col, lin1 = 0, col1 = 0, lin2 = 0, col2 = 0;
        //atribuir aleatoriamente as coordenadas dos barcos
        for (int i = 0; i < b.length; i++) {
            lin = 0 + (int) (6 * Math.random());
            col = 0 + (int) (6 * Math.random());
            //para fazer o barco ocupar 3 posições na grelha
            switch (lin) {//para as linhas
                case 0:
                    lin1 = lin + 1;
                    lin2 = lin + 2;
                    break;
                case 1:
                    lin1 = lin - 1;
                    lin2 = lin + 1;
                    break;
                case 2:
                    lin1 = lin - 1;
                    lin2 = lin + 2;
                    break;
                case 3:
                    lin1 = lin - 1;
                    lin2 = lin + 2;
                    break;
                case 4:
                    lin1 = lin - 1;
                    lin2 = lin + 2;
                    break;
                case 5:
                    lin1 = lin - 1;
                    lin2 = lin + 2;
                    break;
                case 6:
                    lin1 = lin - 1;
                    lin2 = lin - 2;
                    break;
            }
            switch (col) {//para as colunas
                case 0:
                    col1 = col + 1;
                    col2 = col + 2;
                    break;
                case 1:
                    col1 = col - 1;
                    col2 = col + 1;
                    break;
                case 2:
                    col1 = col + 1;
                    col2 = col + 2;
                    break;
                case 3:
                    col1 = col + 1;
                    col2 = col + 2;
                    break;
                case 4:
                    col1 = col + 1;
                    col2 = col + 2;
                    break;
                case 5:
                    col1 = col + 1;
                    col2 = col + 2;
                    break;
                case 6:
                    col1 = col - 1;
                    col2 = col - 2;
                    break;
            }
            //o mapa recebe as 3 partes do barco aletoriamente colocado
            mat[lin][col] = b[i];
            mat[lin1][col1] = b[i];
            mat[lin2][col2] = b[i];
        }
        return mat;
    }
}
public class Barco {
    //váriável de classe

    //instãncias da Classe Barco
    private String nome;
    private boolean acerto;
    private String coordenadas;
    private int estadoDoBarco;
    private boolean afundou;

    //construtores
    public Barco(String nome) {
        this.nome = nome;
        this.acerto = false;
        this.coordenadas = "";
        this.estadoDoBarco = 3;
        this.afundou = false;
    }

    //Getter && Setter
    public boolean getAcerto() {
        return acerto;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getCoordenadas(Object[][] mat) {
        for (int i = 0; i < mat.length; i++) {
            for (int j = 0; j < mat[i].length; j++) {
                if (mat[i][j] != null) {
                    coordenadas = converterCoordenadas(i) + j;
                }
            }
        }
        return coordenadas;
    }

    public int getEstadoDoBarco() {
        return estadoDoBarco;
    }

//métodos
    //método para disparar
    public String disparar(char coord1, char coord2, Object[][] mapa) {
        //conversão das coordenadas para int
        switch (coord1) {
            case 'A':
            case 'a':
                coord1 = 0;
                break;
            case 'B':
            case 'b':
                coord1 = 1;
                break;
            case 'C':
            case 'c':
                coord1 = 2;
                break;
            case 'D':
            case 'd':
                coord1 = 3;
                break;
            case 'E':
            case 'e':
                coord1 = 4;
                break;
            case 'F':
            case 'f':
                coord1 = 5;
                break;
            case 'G':
            case 'g':
                coord1 = 6;
                break;
            default:
                String.format("Erro! Coordenada inválida. Coordenada 0 colocada por omissão");
                coord1 = 0;
        }
        String txt_lin = String.valueOf(coord1);//converter char para String
        String txt_col = String.valueOf(coord2);
        int lin = Integer.valueOf(txt_lin).intValue();//converter String para int
        int col = Integer.valueOf(txt_col).intValue();
        String txt = "";
        acerto = verificarDisparo(lin, col, mapa);
        if (acerto == true) {
            estadoDoBarco--;
            txt = String.format("ACERTOU!");
            if (estadoDoBarco == 0) {
                afundou = true;
                txt = String.format("AFUNDOU!");
            }
        } else {
            txt = String.format("FALHOU!");
        }
        return txt;
    }

    //método para verificar o disparo
    private boolean verificarDisparo(int lin, int col, Object mapa[][]) {
        boolean flag = false;
        if (mapa[lin][col] != null) {
            flag = true;
        }
        return flag;
    }

    //método para converter as coordenadas
    private String converterCoordenadas(int i) {
        String txt = "";
        switch (i) {
            case 0:
                txt = "A";
                break;
            case 1:
                txt = "B";
                break;
            case 2:
                txt = "C";
                break;
            case 3:
                txt = "D";
                break;
            case 4:
                txt = "E";
                break;
            case 5:
                txt = "F";
                break;
            case 6:
                txt = "G";
                break;
        }
        return txt;
    }
}

E agora após colocar uma coordenada A1 gera um novo erro:

run:

Exception in thread main java.lang.NumberFormatException: For input string: " "

at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)

at java.lang.Integer.parseInt(Integer.java:449)

at java.lang.Integer.valueOf(Integer.java:554)

at Barco.disparar(Barco.java:88)

at TesteBatalhaNaval.main(TesteBatalhaNaval.java:37)

Java Result: 1

BUILD SUCCESSFUL (total time: 5 seconds)

Alguém pode ajudar?

Cumprimentos

R

o problema parece estar no método disparar

tente usar Integer.parseInt() pra converter de string pra int

int lin = Integer.parseInt(txt_lin);

outra coisa… vc cria um case cujo valor default não atribui nada à coordenada 2 né? e depois tenta converter para int… dependendo do que vier ali pode dar erro na conversão… ideal seria vc verificar os valores antes de converter ou colocar a conversão dentro de um try catch e atribuir um valor qualquer dentro da exception sei la… =)

Ironlynx
vec[i].disparar(coord1,coord2, mapa)

Humm… o ideal é vc seguir a dica redr4gon de verificar as variáveis antes de usar e garantir que nunca seja passada uma variável com valor nulo ao parseInt e qualquer outro método que vc venha a utilizar. :wink:

N

Viva…

redr4gon, usei a sua dica do:

int lin = Integer.parseInt(txt_lin);

e o programa rebenta na mesma. A que case é que você se está referindo?

Agora o erro que está sendo gerado é este:

run:

Exception in thread main java.lang.ArrayIndexOutOfBoundsException: 7

at Grelha.colocarBarcos(Grelha.java:78)

at TesteBatalhaNaval.main(TesteBatalhaNaval.java:27)

Java Result: 1

BUILD SUCCESSFUL (total time: 0 seconds)

Mas não tem muita lógica porque antes de eu ter feito essas alterações o programa passava à frente essa parte e pedia-me as coordenadas. Agora nem sequer chego a introduzi-las pois ele crasha logo :frowning:

Eu mandei ele gerar nº aleatórios entre 0 e 6, não entendo porque ele diz que ultrapassei os limites do array.

Aceitam-se sugestões para o problema em geral.
Obrigado pessoal.
Cumps

R

repara que na classe Grelha, no metodo carregarBarcos, no case vc faz uma linha do tipo:

lin2 = lin + 2;

veja bem… se vc gerou um numero de 0 a 6, isso dae pode resultar em 8… isso em posições… pq ja que o array tem tamanho 7, ele tem 6 posições pq o 0 tb conta. Ou seja… vc exigiu colocar um barco numa posicao q nao existia =)

pra arrumar isso vc pode mudar as posicoes que insere os barcos ou aumentar o array

ou tratar… se for inserir fora da grelha, “puxa” o barco pra dentro da grelha

N

OLá redr4gon.

O que você diz tem a sua lógica, e eu reparei no ciclo case com mais atenção e só tinha prestado atenção a esses 4 casos:

lin = 6 eu tenho que lin1 = lin-1; lin2 = lin-2;
lin = 0 eu tenho que lin1 = lin+1; lin2 = lin+2;

col = 6 eu tenho que col1 = col - 1; col2 = col - 2;
col = 0 eu tenho que col1 = col + 1; col2 = col + 2;

Tanto para “col” como para “lin” e os nº gerados agora de certeza absoluta que só variam entre 0 e 6 pois já concertei esse erro.

Obrigado pela sua ajuda e paciência.

O novo código da classe Grelha é este:

public class Grelha {
    //instância da Classe Grelha

    private Object[][] mat = new Object[7][7];

    //método para colocar barcos
    public Object[][] colocarBarcos(Barco b[]) {
        int lin, col, lin1 = 0, col1 = 0, lin2 = 0, col2 = 0;
        //atribuir aleatoriamente as coordenadas dos barcos
        for (int i = 0; i < b.length; i++) {
            lin = 0 + (int) (6 * Math.random());
            col = 0 + (int) (6 * Math.random());
            //para fazer o barco ocupar 3 posições na grelha
            switch (lin) {//para as linhas
                case 0:
                    lin1 = lin + 1;
                    lin2 = lin + 2;
                    break;
                case 1:
                    lin1 = lin - 1;
                    lin2 = lin + 1;
                    break;
                case 2:
                    lin1 = lin - 1;
                    lin2 = lin + 1;
                    break;
                case 3:
                    lin1 = lin - 1;
                    lin2 = lin + 1;
                    break;
                case 4:
                    lin1 = lin - 1;
                    lin2 = lin + 1;
                    break;
                case 5:
                    lin1 = lin - 1;
                    lin2 = lin + 1;
                    break;
                case 6:
                    lin1 = lin - 1;
                    lin2 = lin - 2;
                    break;
            }
            switch (col) {//para as colunas
                case 0:
                    col1 = col + 1;
                    col2 = col + 2;
                    break;
                case 1:
                    col1 = col - 1;
                    col2 = col + 1;
                    break;
                case 2:
                    col1 = col + 1;
                    col2 = col + 1;
                    break;
                case 3:
                    col1 = col + 1;
                    col2 = col + 1;
                    break;
                case 4:
                    col1 = col + 1;
                    col2 = col + 1;
                    break;
                case 5:
                    col1 = col + 1;
                    col2 = col + 1;
                    break;
                case 6:
                    col1 = col - 1;
                    col2 = col - 2;
                    break;
            }
            //o mapa recebe as 3 partes do barco aletoriamente colocado
            mat[lin][col] = b[i];
            mat[lin1][col1] = b[i];
            mat[lin2][col2] = b[i];
        }
        return mat;
    }
}

O da classe barco é o seguinte:

public class Barco {
    //váriável de classe

    //instãncias da Classe Barco
    private String nome;
    private boolean acerto;
    private String coordenadas;
    private int estadoDoBarco;
    private boolean afundou;

    //construtores
    public Barco(String nome) {
        this.nome = nome;
        this.acerto = false;
        this.coordenadas = "";
        this.estadoDoBarco = 3;
        this.afundou = false;
    }

    //Getter && Setter
    public boolean getAcerto() {
        return acerto;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getCoordenadas(Object[][] mat) {
        for (int i = 0; i < mat.length; i++) {
            for (int j = 0; j < mat[i].length; j++) {
                if (mat[i][j] != null) {
                    coordenadas += converterCoordenadas(i) + j+" ";
                }
            }
        }
        return coordenadas;
    }

    public int getEstadoDoBarco() {
        return estadoDoBarco;
    }

//métodos
    //método para disparar
    public String disparar(char coord1, char coord2, Object[][] mapa) {
        int lin=0;
        //conversão das coordenadas para int
        switch (coord1) {
            case 'A':
            case 'a':
                lin = 0;
                break;
            case 'B':
            case 'b':
                lin = 1;
                break;
            case 'C':
            case 'c':
                lin = 2;
                break;
            case 'D':
            case 'd':
                lin = 3;
                break;
            case 'E':
            case 'e':
                lin = 4;
                break;
            case 'F':
            case 'f':
                lin = 5;
                break;
            case 'G':
            case 'g':
                lin = 6;
                break;
            default:
                String.format("Erro! Coordenada inválida. Coordenada 0 colocada por omissão");
                coord1 = 0;
        }
        String txt_col = String.valueOf(coord2);//converter char para String
        int col = Integer.parseInt(txt_col);//converter String para int
        String txt = "";
        acerto = verificarDisparo(lin, col, mapa);
        if (acerto == true) {
            estadoDoBarco--;
            txt = String.format("ACERTOU no barco %s",nome,"!");
            if (estadoDoBarco == 0) {
                afundou = true;
                txt = String.format("AFUNDOU o barco %s",nome,"!");
            }
        } else {
            txt = String.format("FALHOU!");
        }
        return txt;
    }

    //método para verificar o disparo
    private boolean verificarDisparo(int lin, int col, Object mapa[][]) {
        boolean flag = false;
        if (mapa[lin][col] != null) {
            flag = true;
        }
        return flag;
    }

    //método para converter as coordenadas
    private String converterCoordenadas(int i) {
        String txt = "";
        switch (i) {
            case 0:
                txt = "A";
                break;
            case 1:
                txt = "B";
                break;
            case 2:
                txt = "C";
                break;
            case 3:
                txt = "D";
                break;
            case 4:
                txt = "E";
                break;
            case 5:
                txt = "F";
                break;
            case 6:
                txt = "G";
                break;
        }
        return txt;
    }
}

e o da classe TesteBatalhaNaval está assim:

import javax.swing.JOptionPane;

public class TesteBatalhaNaval {

    public static void main(String[] args) {
        //instância de um vector de três barcos
        Barco vec[] = new Barco[3];

        //instância da Classe Grelha
        Grelha g1 = new Grelha();

        //mapa onde serão colocados os barcos aleatóriamente
        Object mapa[][] = new Object[7][7];

        //instânciação de 3 barcos da Classe Barco
        Barco b1 = new Barco("E.U.A.");
        Barco b2 = new Barco("AFEGANISTÃO");
        Barco b3 = new Barco("VENEZUELA");

        vec[0] = b1;
        vec[1] = b2;
        vec[2] = b3;

        mapa = g1.colocarBarcos(vec);//mapa com os barcos colocados aleatóriamente

        String finalizar = "";
        String coordenadasUtilizadas[] = new String[100];
        int k = 0;
        int numTentativas = 1;

        //consola
        while ((vec[0].getEstadoDoBarco() > 0 && vec[1].getEstadoDoBarco() > 0 && vec[2].getEstadoDoBarco() > 0) || finalizar.equalsIgnoreCase("F")) {
            String coordenadas = JOptionPane.showInputDialog("Combinações de coordenadas possíveis:"
                    + "\nLinhas:    A B C D E F G"
                    + "\nColinhas:  0 1 2 3 4 5 6"
                    + "\nDigite as coordenadas do alvo a abater: ");
            String cd = coordenadas;
            char coord1 = coordenadas.charAt(0);
            char coord2 = coordenadas.charAt(1);
            String txt = "";
            //disparar nos barcos
            for (int i = 0; i < vec.length; i++) {
                if (vec[i].getEstadoDoBarco() > 0) {
                    txt = vec[i].disparar(coord1, coord2, mapa);
                    JOptionPane.showMessageDialog(null, txt, "\nNúmero de tentativas utilizadas: %d", numTentativas);//o programa no output nao escreve o valor desta variavel e fica simplesmente %d
                }
            }


            finalizar = JOptionPane.showInputDialog("Deseja tentar novamente ou terminar o jogo?\nT - Tentar Novamente\nF - Finalizar Jogo");
            if (finalizar.equalsIgnoreCase("F")) {
                JOptionPane.showMessageDialog(null, "Jogo finalizado!\n"
                        + "Coordenadas dos barcos:\n"
                        + vec[0].getNome() + " Coordenadas: " + vec[0].getCoordenadas(mapa) + "\n"
                        + vec[1].getNome() + " Coordenadas: " + vec[1].getCoordenadas(mapa) + "\n"
                        + vec[2].getNome() + " Coordenadas: " + vec[2].getCoordenadas(mapa) + "\n"
                        + "Tentativas utilizadas: " + numTentativas);
            }

            //incrementatação das tentativas em coordenadas ainda não atingidas
            String cU = "";
            for (int i = 0; i < numTentativas; i++) {
                cU = coordenadasUtilizadas[i];
                if (cU.equalsIgnoreCase(cd)) {//erro aqui... a variável cU fica-me sempre a null
                    numTentativas++;
                } else {
                    k++;
                    coordenadasUtilizadas[k] = cd;
                }
            }

        }
    }
}

Agora já consigo arrancar com o programa, inserir uma coordenada e o programa diz-me se acertei ou falhei no alvo. Depois o programa pergunta-me se quero finalizar o jogo o jogo ou continuar… Se escolher finalizar o jogo ele termina mas verifico que tenho mais que 3 coordenadas para cada barco, e além disso as coordenadas são iguais em todos os barcos. Se escolher tentar novamente o programa dá o seguinte erro:

run:

Exception in thread main java.lang.NullPointerException

at TesteBatalhaNaval.main(TesteBatalhaNaval.java:65)

Java Result: 1

BUILD SUCCESSFUL (total time: 32 seconds)

Outra coisa que me está a chatear é que quando eu disparo ele diz 3 vezes se acertei ou se falhei quando só deveria dizer uma.

Se me quiser continuar a ajudar a corrigir isto eu agradeço.
Valeu amigo.
Cumprimentos

Aguardando mais ajuda.
Cumprimentos

N

Viva.

Já resolvi esse problema…

Agora onde estou à rasca é que cada barco tem de ter 3 posições, mas elas são bem mais de 3 e ainda por cima são todas iguais (os barcos têm o mais de 3 posições no mapa quando só deviam ter 3, e também têm a mesma localização).

Outra coisa que não entendo é no meu ciclo while() da classe Main TesteBatalhaNaval, quando eu primo “F” para finalizar o jogo ele não termina logo e roda mais uma vez voltando a pedir ao utilizador as coordenadas para um novo disparo.

Podem ajudar?

Cumprimentos

R

então…

primeiro erro: está inserindo 3 coordenadas por causa do seu Barco vec[]… o tamanho dele é 3 dae na parte:

for (int i = 0; i < vec.length; i++)

vc percorre o vetor 3x, disparando 3x a mesma coordenada.

segundo: o nullpointer é pq vc ta criando a variavel de array coordenadasUtilizadas e nunca atribuindo nada a ela… todos os valores nela sao sempre null dae qndo vc verifica

cU = coordenadasUtilizadas[i];
if (cU.equalsIgnoreCase(cd)) …

ele ta null.

aconselho vc a criar um arrayList pras coordenadas utilizadas… vc nao delimita tamanho, soh vai inserindo

R

ops… respondi e nem vi q resolveu os problemas antes :stuck_out_tongue:

sobre os barcos ae, vc vai ter que mudar a logica do modo que insere eles…

sugiro trabalhar com HashMap: cria uma classe BeanBarco com variaveis que identificam o barco, os locais onde esta esse barco e a situação de cada local que ele está… dae vc insere no HashMap e pronto…

se vc nao sabe trabalhar com HashMap, colocaria essas classes BeanBarco num array do tipo BeanBarco e faria o negocio todo com ele =)

sobre o segundo problema, experimenta colocar após o JOptionPane dentro do
if (finalizar.equalsIgnoreCase(“F”))…

System.exit(0);
N

Viva.

redr4gon, não sei trabalhar com HashMap, mas consegui meter o programa a rodar, apenas ficou com as seguintes falhas:

Adiante, o código está comentado, incluindo as zonas que precisam de ser melhoradas.

Por exemplo, quando falho um disparo em todos os barcos não haveria hipótese de em vez de estar a dizer para todos os barcos que falhei dizer um  vez falhou?(Classe Barco método disparar() )

Não sei se a variável numTentativas está a incrementar bem.(Main Classe)

Tenho  um ciclo if() para quando o utilizador não introduz nenhuma coordenada que acho que o programa não está a passar por  por causa de inserir coordenadas repetidas e o programa continuar sempre a rodar sem me notificar com o devido outup. (Main Classe)

Deixo em baixo as últimas alterações que fiz no meu código, Se me conseguirem ajudar mais muito obrigado.
Cumprimentos

Classe Barco

public class Barco {
    //váriável de classe

    //instãncias da Classe Barco
    private String nome;
    private boolean acerto;
    private String coordenadas;
    private int estadoDoBarco;
    private boolean afundou;

    //construtores -------------------------------------------------------------
    public Barco(String nome) {
        this.nome = nome;
        this.acerto = false;
        this.coordenadas = "";
        this.estadoDoBarco = 3;
        this.afundou = false;
    }

    //Gets ---------------------------------------------------------------------
    public boolean getAcerto() {
        return acerto;
    }

    public String getNome() {
        return nome;
    }

    public String getCoordenadas() {
        return coordenadas;
    }

    public int getEstadoDoBarco() {
        return estadoDoBarco;
    }
    
    //Sets ---------------------------------------------------------------------
    public void setNome(String nome) {
        this.nome = nome;
    }

    public void setCoordenadas(String coordenadas) {
        this.coordenadas = coordenadas;
    }

//métodos ----------------------------------------------------------------------
    //método para disparar
    public String disparar(char coord1, char coord2, Object[][] mapa) {
        int lin = 0;
        //conversão das coordenadas para int
        switch (coord1) {
            case 'A':
            case 'a':
                lin = 0;
                break;
            case 'B':
            case 'b':
                lin = 1;
                break;
            case 'C':
            case 'c':
                lin = 2;
                break;
            case 'D':
            case 'd':
                lin = 3;
                break;
            case 'E':
            case 'e':
                lin = 4;
                break;
            case 'F':
            case 'f':
                lin = 5;
                break;
            case 'G':
            case 'g':
                lin = 6;
                break;
            default:
                String.format("Erro! Coordenada inválida. Coordenada 0 colocada por omissão");
                coord1 = 0;
        }
        String txt_col = String.valueOf(coord2);//converter char para String
        int col = Integer.parseInt(txt_col);//converter String para int
        String txt = "";
        acerto = verificarDisparo(lin, col);
        if (acerto == true) {
            estadoDoBarco--;
            txt = String.format("ACERTOU no barco %s", nome, "!");
            if (estadoDoBarco == 0) {
                afundou = true;
                txt = String.format("AFUNDOU o barco %s", nome, "!");
            }
        } else {
            txt = String.format("FALHOU o barco %s", nome, "!");
        }
        return txt;
    }

    //método para verificar o disparo
    private boolean verificarDisparo(int lin, int col) {
        boolean flag = false;
        String coordBarco [] = new String [3];
        String cb="";
        //transporte das coordenadas para um array de Strings
        for (int i = 0; i < coordBarco.length; i++) {
            cb = getCoordenadas();
            coordBarco = cb.split(",");
        }
        //verificação das coordenadas de cada barco
        String disp = converterCoordenadas(lin)+col;
        for (int i = 0; i < coordBarco.length; i++) {
            if(disp.equalsIgnoreCase(coordBarco[i])){
                flag=true;
            }
        }
        return flag;
    }

    //método para converter as coordenadas
    public String converterCoordenadas(int i) {
        String txt = "";
        switch (i) {
            case 0:
                txt = "A";
                break;
            case 1:
                txt = "B";
                break;
            case 2:
                txt = "C";
                break;
            case 3:
                txt = "D";
                break;
            case 4:
                txt = "E";
                break;
            case 5:
                txt = "F";
                break;
            case 6:
                txt = "G";
                break;
        }
        return txt;
    }
}

Classe Grelha

public class Grelha {
    //instância da Classe Grelha

    private Object[][] mat = new Object[7][7];

    //método para colocar barcos
    public Object[][] colocarBarco(Barco[] b) {
        int lin, col, lin1 = 0, col1 = 0, lin2 = 0, col2 = 0;
        //atribuir aleatoriamente as coordenadas dos barcos
        for (int i = 0; i < 3; i++) {
            lin = 0 + (int) (6 * Math.random());
            col = 0 + (int) (6 * Math.random());
            //para fazer o barco ocupar 3 posições na grelha
            switch (lin) {//para as linhas
                case 0:
                    lin1 = lin + 1;
                    lin2 = lin + 2;
                    break;
                case 1:
                    lin1 = lin - 1;
                    lin2 = lin + 1;
                    break;
                case 2:
                    lin1 = lin - 1;
                    lin2 = lin + 1;
                    break;
                case 3:
                    lin1 = lin - 1;
                    lin2 = lin + 1;
                    break;
                case 4:
                    lin1 = lin - 1;
                    lin2 = lin + 1;
                    break;
                case 5:
                    lin1 = lin - 1;
                    lin2 = lin + 1;
                    break;
                case 6:
                    lin1 = lin - 1;
                    lin2 = lin - 2;
                    break;
            }
            switch (col) {//para as colunas
                case 0:
                    col1 = col + 1;
                    col2 = col + 2;
                    break;
                case 1:
                    col1 = col - 1;
                    col2 = col + 1;
                    break;
                case 2:
                    col1 = col + 1;
                    col2 = col + 1;
                    break;
                case 3:
                    col1 = col + 1;
                    col2 = col + 1;
                    break;
                case 4:
                    col1 = col + 1;
                    col2 = col + 1;
                    break;
                case 5:
                    col1 = col + 1;
                    col2 = col + 1;
                    break;
                case 6:
                    col1 = col - 1;
                    col2 = col - 2;
                    break;
            }
            //o mapa recebe as 3 partes do barco aletoriamente colocado
            //3 partes do barco na matriz
            mat[lin][col] = b[i];
            mat[lin1][col1] = b[i];
            mat[lin2][col2] = b[i];

            //3 partes do barco a serem convertidas
            String lin_txt = b[i].converterCoordenadas(lin);
            String lin_txt1 = b[i].converterCoordenadas(lin1);
            String lin_txt2 = b[i].converterCoordenadas(lin2);

            //envio das coordenadas para cada barco
            String coordenadasTotais_txt = lin_txt + col + "," + lin_txt1 + col1 + "," + lin_txt2 + col2;
            b[i].setCoordenadas(coordenadasTotais_txt);
        }
        return mat;
    }

    //método para converter as coordenadas
    public String converterCoordenadas(int i) {
        String txt = "";
        switch (i) {
            case 0:
                txt = "A";
                break;
            case 1:
                txt = "B";
                break;
            case 2:
                txt = "C";
                break;
            case 3:
                txt = "D";
                break;
            case 4:
                txt = "E";
                break;
            case 5:
                txt = "F";
                break;
            case 6:
                txt = "G";
                break;
        }
        return txt;
    }
}

Main Classe TesteBatalhaNaval

import java.util.ArrayList;
import javax.swing.JOptionPane;

public class TesteBatalhaNaval {

    public static void main(String[] args) {
        //instância de um vector de três barcos
        Barco vec[] = new Barco[3];

        //instância da Classe Grelha
        Grelha g1 = new Grelha();

        //mapa onde serão colocados os barcos aleatóriamente
        Object mapa[][] = new Object[7][7];

        //instânciação de 3 barcos da Classe Barco
        Barco b1 = new Barco("E.U.A.");
        Barco b2 = new Barco("AFEGANISTÃO");
        Barco b3 = new Barco("VENEZUELA");

        vec[0] = b1;
        vec[1] = b2;
        vec[2] = b3;

        mapa = g1.colocarBarco(vec);//mapa com os barcos colocados aleatóriamente

        String opcao = "";
        boolean finalizar = false;
        boolean coordRep = false;
        int numTentativas = 1;
        ArrayList coordenadasUtilizadas = new ArrayList();
        String coordenadas = "";
        char coord1;
        char coord2;
        int h = 1;

        //output para o utilizador
        while ((b1.getEstadoDoBarco() > 0 && b2.getEstadoDoBarco() > 0 && b3.getEstadoDoBarco() > 0) || finalizar == true) {
            coordenadas = JOptionPane.showInputDialog("Combinações de coordenadas possíveis:"
                    + "\nLinhas:    A B C D E F G"
                    + "\nColunas:  0 1 2 3 4 5 6"
                    + "\nDigite as coordenadas do alvo a abater: ");
            coordenadasUtilizadas.add(coordenadas);


            if (h > 1) {
                //incrementatação das tentativas em coordenadas ainda não atingidas
                numTentativas = coordenadasRepetidas(numTentativas, coordenadas, coordenadasUtilizadas);
            }

            //se não forem inseridas coordenadas válidas
            //este if() não estão a funcionar
            if (coordenadas.equalsIgnoreCase("")) {
                JOptionPane.showMessageDialog(null, "Erro! Coordenada não inserida.\nPor omissão coordenada: A0");
                coordenadas = "A0";
            }

            //conversão variavel String coordenadas em duas variaveis char
            coord1 = coordenadas.charAt(0);
            coord2 = coordenadas.charAt(1);

            

            //disparar nos barcos
            String txt = "";
            for (int i = 0; i < vec.length; i++) {
                if (vec[i].getEstadoDoBarco() > 0) {
                    txt = vec[i].disparar(coord1, coord2, mapa);
                    JOptionPane.showMessageDialog(null, txt);
                }
            }

            //opção que condiciona o ciclo while onde o menu de jogo é exposto
            opcao = JOptionPane.showInputDialog("Deseja tentar novamente ou terminar o jogo?\nT - Tentar Novamente\nF - Finalizar Jogo\nC - Consultar estado dos barcos");

            //condição que termina o ciclo while()
            if (opcao.equalsIgnoreCase("F")) {
                JOptionPane.showMessageDialog(null, "Jogo finalizado!\n"
                        + "Coordenadas dos barcos:\n"
                        + b1.getNome() + " Coordenadas: " + b1.getCoordenadas() + "\n"
                        + b2.getNome() + " Coordenadas: " + b2.getCoordenadas() + "\n"
                        + b3.getNome() + " Coordenadas: " + b3.getCoordenadas() + "\n"
                        + "Tentativas utilizadas: " + numTentativas);
                finalizar = true;
                System.exit(0);//fecha a consola
            } else {
                //consultar o estado dos barcos
                while (opcao.equalsIgnoreCase("C")) {
                    if (opcao.equalsIgnoreCase("C")) {
                        JOptionPane.showMessageDialog(null, "Estado dos Barcos!\n"
                                + b1.getNome() + " Coordenadas: " + b1.getEstadoDoBarco() + "\n"
                                + b2.getNome() + " Coordenadas: " + b2.getEstadoDoBarco() + "\n"
                                + b3.getNome() + " Coordenadas: " + b3.getEstadoDoBarco() + "\n");
                        opcao = JOptionPane.showInputDialog("Deseja tentar novamente ou terminar o jogo?\nT - Tentar Novamente\nF - Finalizar Jogo\nC - Consultar estado dos barcos");
                    }
                }
            }
            h++;//variavel que aprova o acesso ao método coordenadasRepetidas() após o primeiro disparo
        }


    }

    //atribuir uma coordenada aletatoriamente
    public static int coordenadasRepetidas(int numTent, String coord, ArrayList coordUt) {
        coordUt = new ArrayList();
        String txt = "";
        do {
            for (Object obj : coordUt) {
                if (obj.equals(coord)) {//comparação do ArrayList com as coordenadas Inseridas.
                    JOptionPane.showMessageDialog(null, "Erro! Coordenada " + coord + " já inserida.");
                    //atribuição de um disparo aleatório
                    txt = coord;
                    coord = disparoAleatorio();
                } else {
                    coordUt.add(coord);
                    JOptionPane.showMessageDialog(null, "Cordenada inserida automáticamente: " + coord + "\nBoa sorte!");
                }
            }
        } while (coord.equalsIgnoreCase(txt));
        numTent++;
        return numTent;
    }

    //método para fazer disparo aleatório
    public static String disparoAleatorio() {
        String txt = "";
        int lin = 0 + (int) (6 * Math.random());
        int col = 0 + (int) (6 * Math.random());
        txt = converterCoordenadas(lin) + col;
        return txt;
    }

    //método para converter as coordenadas
    public static String converterCoordenadas(int i) {
        String txt = "";
        switch (i) {
            case 0:
                txt = "A";
                break;
            case 1:
                txt = "B";
                break;
            case 2:
                txt = "C";
                break;
            case 3:
                txt = "D";
                break;
            case 4:
                txt = "E";
                break;
            case 5:
                txt = "F";
                break;
            case 6:
                txt = "G";
                break;
        }
        return txt;
    }
}
Criado 22 de março de 2011
Ultima resposta 25 de mar. de 2011
Respostas 12
Participantes 4