Modificar um vetor de outra classe

Boa noite pessoal!

Estou com um problema que não consigo resolver…

Criei uma classe tabuleiro para um projeto de dama. Porém, criei uma classe chamada Movimento para preencher o tabuleiro com as primeiras peças e posteriormente, movimentar as peças.
Quando executo o metodo, não atribui as alterações no tabuleiro… :no_mouth:

Segue o codigo:

package tabuleiro;

public class Tabuleiro {

private String[][] matriz;
private int tamanho = 10;


public Tabuleiro() {
	tamanho++;
	this.matriz = new String[tamanho][tamanho];
	this.matriz[0][0] = "  ";
	for (int i = 0; i < tamanho; i++) {
		for (int j = 0; j < tamanho; j++) {
			matriz[i][j] = "-";
		}
	}
}

public void imprimeTab() {
	System.out.println("\n             1   2   3   4   5   6   7   8   9   10  ");

	for (int linha = tamanho - 1; linha > 0; linha--) {
		if (linha < 10) {
			System.out.println();
			System.out.print("        " + linha + " ");
		} else {
			System.out.println();
			System.out.print("       " + linha + " ");

		}
		for (int coluna = 1; coluna < tamanho; coluna++) {
			System.out.print("   " + matriz[linha][coluna]);

		}

		System.out.println();
	}
	
	
}

public String[][] getMatriz() {
	return matriz;
}

public void setMatriz(String[][] matriz) {
	this.matriz = matriz;
}

public int getTamanho() {
	return tamanho;
}

}

=======

package tabuleiro;

import entidades.Peao;

public class Movimento {

private Tabuleiro tabuleiro = new Tabuleiro();
private Peao peao = new Peao();

public Movimento() {
	
}

public void colocarPecaNoTabuleiro() {
	
	String[][] aux;
	aux = tabuleiro.getMatriz();
	
	for (int i = 2; i < tabuleiro.getTamanho() ; i += 2) {
			aux[1][i] = "P1";
			
		for (int j = 1; j < tabuleiro.getTamanho(); j += 2) {
			aux[2][j] = peao.jogador1();
		}

		for (int v = 2; v < tabuleiro.getTamanho(); v += 2) {
			aux[3][v] = peao.jogador1();
		}

		for (int x = 1; x < tabuleiro.getTamanho(); x += 2) {
			aux[8][x] = peao.jogador2();
		}

		for (int h = 2; h < tabuleiro.getTamanho(); h += 2) {
			aux[9][h] = peao.jogador2();
		}
		for (int b = 1; b < tabuleiro.getTamanho(); b += 2) {
			aux[10][b] = peao.jogador2();
		}

	}
	
	tabuleiro.setMatriz(aux);
}

}

====

package entidades;

import Enum.Cor;

public class Peao {

private Cor cor;

public Peao() {
	
}

public String jogador1() {
	return "J1";
}

public String jogador2() {
	return "J2";
}

public Cor getCor() {
	return cor;
}

public void setCor(Cor cor) {
	this.cor = cor;
}

}

====

package programa;

import tabuleiro.Movimento;
import tabuleiro.Tabuleiro;

public class Programa {
public static void main(String[] args) {

Tabuleiro tab = new Tabuleiro();
Movimento mov = new Movimento();
tab.imprimeTab();
mov.colocarPecaNoTabuleiro();

}
}

===

Alguem poderia me ajudar? O codigo não da nenhum erro, más não atribui as variaveis “P1” e “P2” no tabuleiro, só na variavel aux, como esta no codigo.

Tabuleiro:

         1   2   3   4   5   6   7   8   9   10  

   10    -   -   -   -   -   -   -   -   -   -

    9    -   -   -   -   -   -   -   -   -   -

    8    -   -   -   -   -   -   -   -   -   -

    7    -   -   -   -   -   -   -   -   -   -

    6    -   -   -   -   -   -   -   -   -   -

    5    -   -   -   -   -   -   -   -   -   -

    4    -   -   -   -   -   -   -   -   -   -

    3    -   -   -   -   -   -   -   -   -   -

    2    -   -   -   -   -   -   -   -   -   -

    1    -   -   -   -   -   -   -   -   -   -

Nas classes Programa e Movimento você instancia Tabuleiro, ou seja, são objetos diferentes. Alterando um, não altera o outro.

Você pode passar esse Tabuleiro que instanciou em Programa para a classe Movimento via construtor. Ex:

public class Movimento {
    private Tabuleiro tabuleiro;
    public Movimento(Tabuleiro tabuleiro) {
       this.tabuleiro = tabuleiro;
    }
    //resto
}

//Classe Programa
Tabuleiro tabuleiro = new Tabuleiro();
Movimento movimento = new Movimento(tabuleiro);
}

Fiz este procedimento, más continua não alterando… :neutral_face:

Mostre o código atualizado

Ou bota o método/variável como static e você conseguirá acessar esses metodos/variáveis utilizando assim por exemplo:
Tabuleiro.imprimeTab();

1 curtida

Provavelmente é porque você está imprimindo o tabuleiro antes de preenchê-lo.

Fazendo a alteração proposta acima (para corrigir o problema de estar criando um tabuleiro fora da classe Movimento) e trocando a ordem em que as coisas são feitas:

// mudar o construtor da classe Movimento, para que ele receba o tabuleiro
public Movimento(Tabuleiro tabuleiro) {
    this.tabuleiro = tabuleiro;
}

----------------------------------
// no main
Tabuleiro tab = new Tabuleiro();
Movimento mov = new Movimento(tab);
// primeiro coloca as peças, depois imprime
mov.colocarPecaNoTabuleiro();
tab.imprimeTab();

O resultado é:

      1   2   3   4   5   6   7   8   9   10  

10    J2   -   J2   -   J2   -   J2   -   J2   -
 
 9    -   J2   -   J2   -   J2   -   J2   -   J2
 
 8    J2   -   J2   -   J2   -   J2   -   J2   -
 
 7    -   -   -   -   -   -   -   -   -   -
 
 6    -   -   -   -   -   -   -   -   -   -
 
 5    -   -   -   -   -   -   -   -   -   -
 
 4    -   -   -   -   -   -   -   -   -   -
 
 3    -   J1   -   J1   -   J1   -   J1   -   J1
 
 2    J1   -   J1   -   J1   -   J1   -   J1   -
 
 1    -   P1   -   P1   -   P1   -   P1   -   P1

Aí basta ajustar a formatação. Sugestão:

public void imprimeTab() {
    // o cabeçalho deve respeitar o tamanho do tabuleiro (em vez de imprimir de 1 a 10 sempre)
    System.out.print("\n          ");
    for (int i = 1; i < tamanho; i++) {
        System.out.printf("%4d", i);
    }
    for (int linha = tamanho - 1; linha > 0; linha--) {
        System.out.printf("\n%9d ", linha);
        for (int coluna = 1; coluna < tamanho; coluna++) {
            System.out.printf("%4s", matriz[linha][coluna]);
        }
        System.out.println();
    }
}

Usando printf dá para controlar o tamanho que cada coluna ocupa, deixando o código mais flexível, e sem precisar ficar contando espaços (além de já tratar os casos em que o valor tem mais de um caractere/dígito, etc).

Assim fica desse jeito:

             1   2   3   4   5   6   7   8   9  10
       10   J2   -  J2   -  J2   -  J2   -  J2   -

        9    -  J2   -  J2   -  J2   -  J2   -  J2

        8   J2   -  J2   -  J2   -  J2   -  J2   -

        7    -   -   -   -   -   -   -   -   -   -

        6    -   -   -   -   -   -   -   -   -   -

        5    -   -   -   -   -   -   -   -   -   -

        4    -   -   -   -   -   -   -   -   -   -

        3    -  J1   -  J1   -  J1   -  J1   -  J1

        2   J1   -  J1   -  J1   -  J1   -  J1   -

        1    -  P1   -  P1   -  P1   -  P1   -  P1

Dito isso, essa modelagem está bem estranha. Não sei se faz sentido uma classe chamada Movimento (que pelo nome, deveria representar um movimento apenas, ou seja, o ato de se movimentar uma peça), que é responsável por controlar todo o tabuleiro. Sem contar que ficar obtendo a matriz do tabuleiro, para depois setá-la de volta, não me parece uma boa. A matriz é detalhe de implementação do Tabuleiro, e só deveria ser manipulada ali dentro (da forma que está, qualquer classe consegue obtê-la e alterá-la de qualquer jeito, inclusive deixando-a em um estado inválido). Eu acho que o Tabuleiro deveria ser o único responsável por alterar a matriz.

Aliás, o próprio construtor do tabuleiro já poderia posicionar as peças no lugar. Faz sentido você ter uma instância do tabuleiro sem as peças? Talvez sim, mas eu entendo que não, então faça no construtor tudo que precisa ser feito para que o tabuleiro já esteja em um estado válido. Não dependa de ter que chamar outros métodos (ainda mais em outras classes) para ter uma instância válida.

Outro ponto é que um tabuleiro de damas é 8x8, mas tudo bem, deixar genérico não tem tanto problema assim. Quem sabe o construtor poderia receber o tamanho como parâmetro.

Outro detalhe é que num jogo de damas somente metade das casas é ocupada (ou somente as casas pretas, ou somente as brancas). Sendo assim, dá para otimizar. Basta imaginar o tabuleiro como uma matriz, onde cada linha tem 8 colunas. Mas como nem todas as colunas são usadas (somente as pretas), então na verdade eu posso ter apenas 4 “colunas” por linha. Algo assim:

  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
--|---|---|---|---|---|---|---|---
0 | 0 |   | 1 |   | 2 |   | 3 |
1 |   | 0 |   | 1 |   | 2 |   | 3
2 | 0 |   | 1 |   | 2 |   | 3 |
3 |   | 0 |   | 1 |   | 2 |   | 3
4 | 0 |   | 1 |   | 2 |   | 3 |
5 |   | 0 |   | 1 |   | 2 |   | 3
6 | 0 |   | 1 |   | 2 |   | 3 |
7 |   | 0 |   | 1 |   | 2 |   | 3

Nas linhas pares, o elemento 0 está na coluna 0, o elemento 1 está na coluna 2, o elemento i está na coluna 2 * i.
Nas linhas ímpares, o elemento 0 está na coluna 1, o elemento 1 está na coluna 3, o elemento i está na coluna (2 * i) + 1.

Ou seja, para cada linha, só preciso guardar 4 valores para as “colunas” (podemos chamar de “coluna virtual”). E para saber a coluna correspondente do tabuleiro (a “coluna real”), basta saber que o elemento da coluna virtual i está na coluna real (2 * i) + (linha % 2).

Indo mais além, se o elemento está na posição (lin, col) (sendo que col é a “coluna virtual”), ele pode se mover para 4 posições (tomando o cuidado de verificar se está no canto, ou se a casa está ocupada, se pode capturar a peça, etc): (lin + 1, col + 1), (lin + 1, col - 1), (lin - 1, col + 1) e (lin - 1, col - 1). Ou seja, fazendo essas verificações, eu sei que a peça pode fazer um movimento simples.

Se a peça for uma dama, você pode considerar que ela pode se mover várias casas, até encontrar um canto ou uma casa ocupada por uma peça que não pode ser capturada (seja porque está no canto, ou porque tem outra peça logo depois, ou porque é uma peça do mesmo jogador). Para isso, você pode fazer um loop até encontrar um ponto em que ela não pode mais se mover (usando a mesma lógica do movimento simples acima, afinal, se mover várias casas é o mesmo que fazer vários movimentos simples).

Claro que tem uma lógica adicional: se você capturar uma peça, tem direito a um movimento extra, desde que ele seja para capturar outra peça. Para peças simples é mais fácil (só ver se tem uma peça adversária próxima), já para damas você tem que fazer loops em todas as direções para ver se há alguma captura possível.

Mas claro, são só ideias… Vc vê se faz sentido mudar ou não.

1 curtida

Faz total sentido. Eu estava fazendo desta forma, colocando as coisas relacionadas a matriz direto no tabuleiro em outro projeto de damas, más falaram que estava errado…
Por isso mudei tudo :smile:

Foi de grande ajuda! De verdade! muito obrigado mesmo :smiling_face_with_three_hearts: