Mudanças entre as edições de "Pensamento Computacional - Arrays Multidimensionais no Java"
Linha 121: | Linha 121: | ||
<syntaxhighlight lang=java> | <syntaxhighlight lang=java> | ||
+ | import java.util.Scanner; | ||
import java.util.Random; | import java.util.Random; | ||
− | |||
public class BatalhaNaval { | public class BatalhaNaval { | ||
Linha 130: | Linha 130: | ||
private static final int LIVRE = 0; | private static final int LIVRE = 0; | ||
− | |||
private static final int PORTA_AVIOES = 1; | private static final int PORTA_AVIOES = 1; | ||
private static final int FRAGATA = 2; | private static final int FRAGATA = 2; | ||
private static final int SUBMARINO = 3; | private static final int SUBMARINO = 3; | ||
− | |||
− | |||
− | |||
− | |||
private static final int PONTUACAO_PORTA_AVIOES = 10; | private static final int PONTUACAO_PORTA_AVIOES = 10; | ||
+ | private static final int PONTUACAO_FRAGATA = 3; | ||
private static final int PONTUACAO_SUBMARINO = 5; | private static final int PONTUACAO_SUBMARINO = 5; | ||
− | private static final int | + | |
+ | private static final int QUANTIDADE_PORTA_AVIOES = 1; | ||
+ | private static final int QUANTIDADE_FRAGATA = 4; | ||
+ | private static final int QUANTIDADE_SUBMARINO = 5; | ||
private static final int PONTUACAO_TOTAL_PARA_VITORIA = | private static final int PONTUACAO_TOTAL_PARA_VITORIA = | ||
Linha 148: | Linha 147: | ||
(QUANTIDADE_SUBMARINO * PONTUACAO_SUBMARINO); | (QUANTIDADE_SUBMARINO * PONTUACAO_SUBMARINO); | ||
− | private static int[][] | + | private static int[][] zonaDeGuerra = new int[TAM_MAT][TAM_MAT]; |
− | private static int | + | private static int contadorTiros = 0; |
− | private static int | + | private static int pontuacaoFinal; |
private static String nome; | private static String nome; | ||
− | private static int | + | private static int linhaTiro; |
− | private static int | + | private static int colunaTiro; |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
private static void zerarMatriz() { | private static void zerarMatriz() { | ||
for (int i = 0; i < TAM_MAT; i++) | for (int i = 0; i < TAM_MAT; i++) | ||
for (int j = 0; j < TAM_MAT; j++) | for (int j = 0; j < TAM_MAT; j++) | ||
− | + | zonaDeGuerra[i][j] = LIVRE; | |
} | } | ||
private static void sortearCasa() { | private static void sortearCasa() { | ||
− | |||
do { | do { | ||
− | + | linhaTiro = (int) (Math.random() * TAM_MAT); | |
− | + | colunaTiro = (int) (Math.random() * TAM_MAT); | |
− | } while ( | + | } while (zonaDeGuerra[linhaTiro][colunaTiro] != LIVRE); |
} | } | ||
Linha 188: | Linha 170: | ||
for (int i = 0; i < QUANTIDADE_FRAGATA; i++) { | for (int i = 0; i < QUANTIDADE_FRAGATA; i++) { | ||
sortearCasa(); | sortearCasa(); | ||
− | + | zonaDeGuerra[linhaTiro][colunaTiro] = FRAGATA; | |
} | } | ||
} | } | ||
Linha 195: | Linha 177: | ||
for (int i = 0; i < QUANTIDADE_SUBMARINO; i++) { | for (int i = 0; i < QUANTIDADE_SUBMARINO; i++) { | ||
sortearCasa(); | sortearCasa(); | ||
− | + | zonaDeGuerra[linhaTiro][colunaTiro] = SUBMARINO; | |
} | } | ||
} | } | ||
private static void posicionarPortaAvioes() { | private static void posicionarPortaAvioes() { | ||
− | + | sortearCasa(); | |
− | + | zonaDeGuerra[linhaTiro][colunaTiro] = PORTA_AVIOES; | |
− | |||
− | |||
} | } | ||
Linha 215: | Linha 195: | ||
System.out.print(" "); | System.out.print(" "); | ||
for (int j = 0; j < TAM_MAT; j++) { | for (int j = 0; j < TAM_MAT; j++) { | ||
− | System.out.printf("| %2d ", | + | System.out.printf("| %2d ", zonaDeGuerra[linha][j]); |
} | } | ||
System.out.println("|"); | System.out.println("|"); | ||
Linha 224: | Linha 204: | ||
System.out.print(" "); | System.out.print(" "); | ||
for (int j = 0; j < TAM_MAT; j++) { | for (int j = 0; j < TAM_MAT; j++) { | ||
− | if ( | + | if (zonaDeGuerra[linha][j] >= 0 && zonaDeGuerra[linha][j] <= 3) |
System.out.print("| -- "); | System.out.print("| -- "); | ||
else | else | ||
− | System.out.printf("| %2d ", | + | System.out.printf("| %2d ", zonaDeGuerra[linha][j]); |
} | } | ||
System.out.println("|"); | System.out.println("|"); | ||
Linha 243: | Linha 223: | ||
for (int i = 0; i < TAM_MAT; i++) | for (int i = 0; i < TAM_MAT; i++) | ||
imprimeLinhaEscondida(i); | imprimeLinhaEscondida(i); | ||
+ | } | ||
+ | |||
+ | private static void imprimeResultadoJogo() { | ||
+ | System.out.println("Resultado final do jogo:"); | ||
+ | System.out.println("Jogador: " + nome); | ||
+ | System.out.println("Tiros dados: " + contadorTiros); | ||
+ | System.out.println("Pontuação final: " + pontuacaoFinal); | ||
} | } | ||
private static int tiro() { | private static int tiro() { | ||
− | + | ||
} | } | ||
− | + | ||
− | System.out.println(" | + | public static void main(String[] args) { |
− | System.out.println(" | + | |
− | System.out.println(" | + | System.out.println("Bem-vindo à Batalha Naval!"); |
+ | |||
+ | zerarMatriz(); | ||
+ | posicionarNavios(); | ||
+ | |||
+ | System.out.println("Iniciando jogo..."); | ||
+ | |||
+ | imprimeMatrizEscondida(); | ||
+ | |||
+ | int situacao; | ||
+ | do { | ||
+ | situacao = tiro(); | ||
+ | } while (situacao == 0); | ||
+ | |||
+ | // Implementar aqui o tratamento final da variável situação | ||
+ | if (situacao == 1) { | ||
+ | System.out.println("Parabéns! Você venceu!"); | ||
+ | } else { | ||
+ | System.out.println("Fim de jogo, " + nome + ". Obrigado por jogar!"); | ||
+ | } | ||
} | } | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> |
Edição das 19h20min de 4 de dezembro de 2023
Como definir e operar com matrizes no Java
Na aula anterior estudamos os vetores, que são estruturas de dados que permitem organizar os dados tal como
se fossem uma tabela unidimensional. O acesso a cada elemento do vetor é realizado pela indexação do mesmo, ou seja , um número inteiro que permite identificar a posição de um determinado vetor.
De forma similar ao vetor, pode-se criar arranjos multidimensionais. Por exemplo, uma matriz bidimensional pode ser definida usando um nome seguido de suas dimensões (de uma dupla de colchetes para indicar linha e a coluna). Os elementos da matriz serão todos de um mesmo tipo.
Um Exemplo de Soma de Matrizes da Matemática
A soma de duas matrizes na matemática é realizada pela soma dos elementos de mesma linha e coluna.
A dimensão das matrizes deve ser a mesma. Podemos usar os arranjos bidimensionais no Java para acomodar estas matrizes.
OBSERVAR que a operação de soma deve ser realizada elemento por elemento. Dois loops aninhados serão usados para iterar sobre as linhas e colunas.
Vejamos o exemplo abaixo.
PROBLEMA: Definir duas matrizes de inteiros de dimensão 2x3 e computar a soma das mesmas. As matrizes serão iniciadas na definição.
:Dados de Entrada: Matrizes mA[2][3] e mB[2][3] de inteiros. Por questões de facilidade, já serão iniciadas na definição.
:Dados de Saída: Matriz mC[2][3] resultante da soma de mA com mB
Exemplo 1 - Soma de Matrizes
Implementar um programa para calcular a média de todos elementos da matriz C do exemplo acima.
public class SomaMatrizes {
public static void main(String[] args) {
// Exemplo de matrizes
int[][] matrizA = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int[][] matrizB = {{9, 8, 7}, {6, 5, 4}, {3, 2, 1}};
// Chamando o método para somar as matrizes
int[][] matrizC = somarMatrizes(matrizA, matrizB);
// Exibindo a matriz resultante
System.out.println("Matriz Resultante:");
imprimirMatriz(matrizC);
}
// Método para somar duas matrizes
public static int[][] somarMatrizes(int[][] matrizA, int[][] matrizB) {
int linhas = matrizA.length;
int colunas = matrizA[0].length;
// Verificando se as matrizes têm as mesmas dimensões
if (linhas != matrizB.length || colunas != matrizB[0].length) {
throw new IllegalArgumentException("As matrizes devem ter as mesmas dimensões para serem somadas.");
}
int[][] resultado = new int[linhas][colunas];
// Iterando sobre as matrizes e realizando a soma
for (int i = 0; i < linhas; i++) {
for (int j = 0; j < colunas; j++) {
resultado[i][j] = matrizA[i][j] + matrizB[i][j];
}
}
return resultado;
}
// Método para imprimir uma matriz
public static void imprimirMatriz(int[][] matriz) {
for (int i = 0; i < matriz.length; i++) {
for (int j = 0; j < matriz[0].length; j++) {
System.out.print(matriz[i][j] + " ");
}
System.out.println();
}
}
}
DISCUSSÃO: Observe a forma como são declarados os arranjos bidimensionais. A dimensão não é informada:
public static int[][] somarMatrizes(int[][] matrizA, int[][] matrizB)
É importante lembrar que arranjos são passados como REFERÊNCIA. Desta forma, quando o método é invocado, os arranjos passados na chamada serão os próprios arranjos manipulados pelo método (no caso matrizA e matrizB. Desta forma, é possível consulatar a propriedade length destes arranjos para que sejam processados devidamente.
Desta forma, o primeiro processamento do método é justamente verificar se as dimensões dos dois arranjos são iguais. Isto deve ser realizado comparando o números de linhas e o número de colunas dos mesmos. Aqui é importante verificar que para acessar o número de linhas de matrizA, por exemplo, basta acessar 'matrizA.length', Já para consultar o número de colunas bastaria consultar o número de colunas da linha 0.
Uma forma de pensar sobre isso é inaginar que o arranjo bidimensional pode ser visto como um vetor de linhas.
Uma instrução que ainda não conhecemos está sendo usada aqui:
throw new IllegalArgumentException("As matrizes devem ter as mesmas dimensões para serem somadas.");
Por enquanto vamos entender esta instrução como uma forma de AVISAR que algo errado aconteceu (uma exceção gerada) e, neste caso o programa se encerra. Futuramente será visto como tratar esta exceção.
Após a verificação inicial, o procedimento de adição é realizado, iterando sobre cada elemento usando a indexação de linha (usando variável auxiliar i) e indexação de coluna (usando variável auxiliar j).
// Iterando sobre as matrizes e realizando a soma for (int i = 0; i < linhas; i++) { for (int j = 0; j < colunas; j++) { resultado[i][j] = matrizA[i][j] + matrizB[i][j]; } }
Note a matriz resultado foi criada anteriormente usando o operador new():
int[][] resultado = new int[linhas][colunas];
Após todo o processamento, esta matriz (sua referência) é retornada.
Exercício 1 - Multiplicação de matrizes
Implementar um método para multiplicação de duas matrizes com dimensões compatíveis com a operação. Prever um teste de compatibilidade, gerando exceção se for o caso. O método deve retornar a matriz resultante.
A batalha naval é um jogo clássico que nas décadas passadas era jogado no papel. Uma pessoa desenhava e posicionava navios em um tabuleiro. Uma outra pessoa tentava adivinhar a posição onde estava cada navio. Ao acertar, recebia uma pontuação, que dependia do tipo navio.
A figura abaixo ilustra um tabuleiro contendo os navios. O tabuleiro é relacionado com uma matriz de inteiros no Java:
private static int[][] ZonaDeGuerra = new int[TAM_MAT][TAM_MAT];
Vamos implementar um jogo similar a batalha naval da seguinte forma.
- Crie uma matriz de inteiros global chamada ZonaDeGuerra com 10x10 posições (iniciada com 0).
- Construa uma função para gerar randomicamente a posição de 1 porta-aviões (colocando 1 na sua posição), 5 fragatas (número 2) e 5 submarinos (número 3). Assuma que a cada casa onde o inimigo alvejar será somado 10 ao número da casa.
- Crie um contador global de tiros iniciado com 0.
- Crie uma função de tiro. Esta função deve ler a posição de tiro, verificar se a casa ainda não foi alvejada. Se alvejada pergunta novamente a posição. Se a posição for válida e tiver um navio então o usuário ganha pontos da seguinte forma: 10 para o porta aviões, 5 para o submarino e 3 para fragata. A função deve retornar 0 se o jogo continua, 1 se o usuário atingiu todos os navios ou 2 se o usuário teve um número máximo de tiros ultrapassado (assumir 30 tiros).
- Ao final do jogo é mostrado o nome do jogador, o número de tiros dados e a pontuação obtida.
import java.util.Scanner;
import java.util.Random;
public class BatalhaNaval {
private static final int TAM_MAT = 10;
private static final int MAX_TIROS = 30;
private static final int LIVRE = 0;
private static final int PORTA_AVIOES = 1;
private static final int FRAGATA = 2;
private static final int SUBMARINO = 3;
private static final int PONTUACAO_PORTA_AVIOES = 10;
private static final int PONTUACAO_FRAGATA = 3;
private static final int PONTUACAO_SUBMARINO = 5;
private static final int QUANTIDADE_PORTA_AVIOES = 1;
private static final int QUANTIDADE_FRAGATA = 4;
private static final int QUANTIDADE_SUBMARINO = 5;
private static final int PONTUACAO_TOTAL_PARA_VITORIA =
(QUANTIDADE_PORTA_AVIOES * PONTUACAO_PORTA_AVIOES) +
(QUANTIDADE_FRAGATA * PONTUACAO_FRAGATA) +
(QUANTIDADE_SUBMARINO * PONTUACAO_SUBMARINO);
private static int[][] zonaDeGuerra = new int[TAM_MAT][TAM_MAT];
private static int contadorTiros = 0;
private static int pontuacaoFinal;
private static String nome;
private static int linhaTiro;
private static int colunaTiro;
private static void zerarMatriz() {
for (int i = 0; i < TAM_MAT; i++)
for (int j = 0; j < TAM_MAT; j++)
zonaDeGuerra[i][j] = LIVRE;
}
private static void sortearCasa() {
do {
linhaTiro = (int) (Math.random() * TAM_MAT);
colunaTiro = (int) (Math.random() * TAM_MAT);
} while (zonaDeGuerra[linhaTiro][colunaTiro] != LIVRE);
}
private static void posicionarFragatas() {
for (int i = 0; i < QUANTIDADE_FRAGATA; i++) {
sortearCasa();
zonaDeGuerra[linhaTiro][colunaTiro] = FRAGATA;
}
}
private static void posicionarSubmarinos() {
for (int i = 0; i < QUANTIDADE_SUBMARINO; i++) {
sortearCasa();
zonaDeGuerra[linhaTiro][colunaTiro] = SUBMARINO;
}
}
private static void posicionarPortaAvioes() {
sortearCasa();
zonaDeGuerra[linhaTiro][colunaTiro] = PORTA_AVIOES;
}
private static void posicionarNavios() {
posicionarPortaAvioes();
posicionarFragatas();
posicionarSubmarinos();
}
private static void imprimeLinha(int linha) {
System.out.print(" ");
for (int j = 0; j < TAM_MAT; j++) {
System.out.printf("| %2d ", zonaDeGuerra[linha][j]);
}
System.out.println("|");
System.out.println(" +----+----+----+----+----+----+----+----+----+----+");
}
private static void imprimeLinhaEscondida(int linha) {
System.out.print(" ");
for (int j = 0; j < TAM_MAT; j++) {
if (zonaDeGuerra[linha][j] >= 0 && zonaDeGuerra[linha][j] <= 3)
System.out.print("| -- ");
else
System.out.printf("| %2d ", zonaDeGuerra[linha][j]);
}
System.out.println("|");
System.out.println(" +----+----+----+----+----+----+----+----+----+----+");
}
private static void imprimeMatrizTudo() {
System.out.println(" +----+----+----+----+----+----+----+----+----+----+");
for (int i = 0; i < TAM_MAT; i++)
imprimeLinha(i);
}
private static void imprimeMatrizEscondida() {
System.out.println(" +----+----+----+----+----+----+----+----+----+----+");
for (int i = 0; i < TAM_MAT; i++)
imprimeLinhaEscondida(i);
}
private static void imprimeResultadoJogo() {
System.out.println("Resultado final do jogo:");
System.out.println("Jogador: " + nome);
System.out.println("Tiros dados: " + contadorTiros);
System.out.println("Pontuação final: " + pontuacaoFinal);
}
private static int tiro() {
}
public static void main(String[] args) {
System.out.println("Bem-vindo à Batalha Naval!");
zerarMatriz();
posicionarNavios();
System.out.println("Iniciando jogo...");
imprimeMatrizEscondida();
int situacao;
do {
situacao = tiro();
} while (situacao == 0);
// Implementar aqui o tratamento final da variável situação
if (situacao == 1) {
System.out.println("Parabéns! Você venceu!");
} else {
System.out.println("Fim de jogo, " + nome + ". Obrigado por jogar!");
}
}
}