Bom dia.
Nosso jogo de Xadrez está evoluindo. Precisamos agora implementar as regras do jogo. E é aí que começa a ficar um pouco mais complicado.
No POST anterior, implementamos o movimento das peças, fazendo-as circular livremente por todo o tabuleiro. Mas eu e você sabemos que em um jogo verdadeiro de Xadrez, existem regras, e que essas regras impedem um determinado tipo de movimento para uma peça específica. Além disso, nenhuma peça pode "passar por cima" de outra peça, com exceção do poderoso Cavalo (minha peça preferida, diga-se de passagem).
O que precisamos agora é implementar, de alguma forma, a regra do movimento de cada peça. Por exemplo, a Torre não pode mover-se diagonalmente, enquanto que o Bispo não pode realizar movimentos horizontais/verticais, somente diagonais. O Cavalo, por sua vez, faz o movimento em "L", enquanto a Rainha herda a capacidade de movimento do Bispo + Torre.
São essas regras que vamos começar a implementar a partir de agora, e começaremos pelo mais fácil: a Torre.
Vamos fazer algumas modificações em nossas classes. Primeiramente, vamos tornar a nossa classe "PecaModel" uma classe abstrata. Por que isso? Veremos mais adiante que teremos um método em comum para todas as peças, que serão implementados de formas diferentes, e precisamos do Polimorfismo para fazer a "coisa" funcionar:
public abstract class PecaModel {...}
Não se assuste com os erros de compilação que você receberá a partir do momento que fizer isso.
Na sequência, vamos criar um método abstrato que deverá ser implementado por todas as classes filhas e que será responsável por validar o movimento daquela determinada peça:
public abstract boolean validaMovimento(int novaLinha, int novaColuna);
Basicamente vamos verificar se a peça pode se mover para a nova linha e a nova coluna desejada.
O próximo passo é começarmos a criar as classes de cada peça e implementarmos o método validaMovimento de acordo com a regra daquela peça. Vamos começar pela Torre, conforme dito no início:
public class Torre extends PecaModel {
@Override
public boolean validaMovimento(int novaLinha, int novaColuna) {
if (this.getColuna() != novaColuna && this.getLinha() == novaLinha) {
return true;
} else if (this.getLinha() != novaLinha && this.getColuna() == novaColuna) {
return true;
}
return false;
}
public Torre(String cor, int linha, int coluna, String corOriginal) {
super(cor,linha,coluna,corOriginal);
}
}
Vamos entender o que isso faz? Primeiramente, observe a anotação @Override que indica que estamos sobrescrevendo nosso método validaMovimento. Bom, sabemos que a Torre não pode realizar movimentos diagonais, então a lógica do método validaMovimento é verificar se isso é verdade ou não. Perceba que a lógica é muito boba. O primeiro if verifica se a coluna da peça que eu cliquei é diferente da coluna de destino. Se isso for verdade, a linha de destino tem que ser IGUAL a linha da peça selecionada. Ou seja, este primeiro if valida o movimento horizontal, já que a linha é a mesma. Já o else trata o inverso. Se a linha da peça que eu cliquei for diferente da linha de destino, a coluna de destino tem que ser IGUAL a coluna da peça que eu selecionei, ou seja, estamos validando o movimento vertical, já que a coluna é a mesma. Consegue entender a complexidade de movimento de outras peças, como por exemplo o poderoso Cavalo? Bom, eu ainda não quero pensar nisso. Continuando na classe Torre, vemos que temos um construtor que chama a versão da super classe. Isso é porque cada peça tem que instanciar os atributos padrão que todas as peças tem (linha, coluna, etc). Crie o atributo "corOriginal" na classe PecaModel para que possamos ter um valor somente com PRETA ou BRANCA, mais adiante veremos o motivo disso.
Feito isso, precisamos alterar a classe TabuleiroModel pois ela está instanciando objetos abstratos, o que está incorreto e nem compila. Precisamos alterar o método montaTabuleiro() para criar classes concretas, desta forma:
public void montaTabuleiro() {
pecas[0][0] = new Torre("TORREPRETO.gif", 0, 0, "PRETA");
pecas[0][1] = new Cavalo("CAVALOPRETO.gif", 0, 1, "PRETA");
pecas[5][0] = new Peao("PEAOBRANCO.gif", 5, 0, "BRANCA");
pecas[6][1] = new Peao("PEAOBRANCO.gif", 6, 1, "BRANCA");
}
OBS: Ainda não criamos a validação de movimento para as outras peças, mas coloque-as no tabuleiro para que você possa verificar se o movimento da Torre está correto.
Veja que o atributo que criamos "corOriginal" é somente para dizermos se a peça é PRETA ou BRANCA.
O último passo agora é passar a responsabilidade para o Tabuleiro, para que, ao tentar realizar o movimento, este pergunte à peça se ela pode se movimentar para o destino selecionado. Precisamos alterar o método realizaJogada() para que fique desta forma:
public void realizaJogada(int linha, int coluna) {
...
} else {
if (pecaSelecionada.validaMovimento(linha, coluna)) {
...
}
}
}
}
Não colocarei o método inteiro pois já temos no POST anterior, veja somente que a parte alterada foi no else, onde adicionamos a chamada do validaMovimento para a peça em questão. Todo o código do else só poderá ser executado se o movimento for válido!
Ah... temos ainda muito o que fazer. Esta foi a validação apenas da Torre, mas temos todas as outras ainda para fazer. Além do mais, você não se esqueceu de que a única peça que passa por "cima" de outra é o Cavalo, certo? Então prepare-se para isso, que no próximo POST vamos trabalhar nesta funcionalidade:
Um abraço e até a próxima!





