Dando sequência ao artigo Desenhando um tabuleiro de damas em HTML/CSS/JS, veremos agora como implementar a movimentação das peças no jogo, trabalhando o deslocamento simples e a “comida”.

Não iremos, aqui, nos aprofundar em detalhes como “de quem é a vez da jogada” ou “quem venceu”, porém isso não é complicado de implementar.

Com base no artigo anterior (citado logo acima), a estrutura do arquivo index.html mudou muito pouco. Apenas a lista contida na div “info” ganhou mais dois itens conforme mostra a Listagem 1:


<ul>
	<li>Pontuação pretas:<span id="info_pontos_pretas"/></li>
<li>Pontuação brancas:<span id="info_pontos_brancas"/></li>
	<li>Casa selecionada: <span id="info_casa_selecionada"/></li>
	<li>Peça selecionada: <span id="info_peca_selecionada"/></li>
</ul>
Listagem 1. Nova estrutura do html

O arquivo estilo.css não precisou sofrer alterações, porém o leitor pode customizá-lo da forma que preferir.

No arquivo montarTabuleiro.js (que agora poderia até ganhar outro nome como “damas.js”, mas não vamos alterar para simplificar o entendimento), criamos mais duas variáveis globais. A declaração passa, então, a ter a seguinte forma:


var casa_selecionada = null;
var peca_selecionada = null;
//Novas variáveis para armazenar a pontuação
var pontos_pretas = 0;
var pontos_brancas = 0;
Listagem 2. Declaração das variáveis globais

A função MontarTabuleiro() e a chamada a ela continuam da mesma forma que no artigo anterior, o trecho de código que sofreu mais alterações foi a função do evento onclick das casas do tabuleiro, identificada por $(".casa").click(function(){...}.

Antes de vermos a nova aparência dessa função, vejamos como funciona a movimentação das peças.

Esquema de posicionamento de uma peça no tabuleiro
Figura 1. Esquema de posicionamento de uma peça no tabuleiro

Na Figura 1 podemos observar como se dá a movimentação simples (sem “comer” outra peça, apenas deslocando-se) de uma peça. Aqui consideraremos que as peças só se movem na direção do oponente, ou seja, a peça não se move “para trás”.

Considerando que a peça acima se encontra na casa (1,1), é fácil perceber que ela só pode se mover para as casas (0,0), (0,2) no caso das peças da parte inferior e (2,0) e (2,2) no caso das peças vindas da parte superior. Se subtrairmos as coordenadas X e Y da casa de origem e da casa destino, veremos que o resultado sempre será 1 ou -1. Por exemplo, considerando a casa origem (1,1) e a destino (0,2), a diferença entre as coordenadas X vale 1-0=1 e a diferença entre as coordenadas Y vale 1-2=-1. Ou seja, para que a jogada seja válida, é preciso que o valor absoluto (módulo) da diferença entre as coordenadas das duas casas seja 1 para o X e 1 para Y.

A Figura 2 mostra agora como funciona a “comida”:

Esquema de funcionamento da comida
Figura 2. Esquema de funcionamento da “comida”

Sabendo que a peça ilustrada acima se encontra na casa (2,2), ela pode “comer” peças que estejam nas casas marcadas com um círculo vermelho, ou seja, ela pode comer peças que estejam nas casas para onde ela poderia se mover normalmente. Após a comida, observamos que a peça estará uma casa após aquela na qual está a peça comida. Seguindo o mesmo raciocínio da movimentação simples, vemos que a diferença entre as coordenadas agora vale, em módulo, 2 e não 1. Ou seja, se a peça ilustrada for do jogador da parte superior, ela poderia comer as peças abaixo dela e passar para as casas (4,0) e (4,4). Já se a peça for do jogador da parte inferior do tabuleiro, ela poderia comer as peças acima dela e passar às casas (0,0) e (0,4).

Agora que entendemos a teoria, vejamos o código:


$(".casa").click(function(){
	var aI, aJ, nI, nJ, dI, dJ;
	var casa_anterior, peca_anterior;
	if(peca_selecionada != null){
		aI = parseInt(casa_selecionada.substr(5, 1));
		aJ = parseInt(casa_selecionada.substr(7, 1));
		
		nI = parseInt($(this).attr("id").substr(5, 1));
		nJ = parseInt($(this).attr("id").substr(7, 1));

		dI = parseInt(((aI - nI) < 0?(aI - nI)*(-1):(aI - nI)));
		dJ = parseInt(((aJ - nJ) < 0?(aJ - nJ)*(-1):(aJ - nJ)));
	}

	$("#"+casa_selecionada).removeClass("casa_selecionada");
	casa_anterior = casa_selecionada;
	peca_anterior = peca_selecionada;
	casa_selecionada = $(this).attr("id");
	$("#"+casa_selecionada).addClass("casa_selecionada");
	peca_selecionada = $("#"+casa_selecionada).children("img").attr("id");

	if(peca_selecionada==null){
		$("#info_peca_selecionada").text("NENHUMA PECA SELECIONADA");
		if(peca_anterior != null){
			if (((peca_anterior.indexOf("preta") >= 0) && (nI > aI)) ||
			((peca_anterior.indexOf("branca") >= 0) && (nI < aI))){
				var obj = $("#"+peca_anterior);
				if((dI == 1) && (dJ == 1)){
				$("#"+casa_anterior).remove("#"+peca_anterior);
					$("#"+casa_selecionada).append(obj);
				}else
				if((dI == 2) && (dJ == 2)){	
					if((peca_anterior.indexOf("branca") >= 0))	{
						var casa_meio = null, peca_meio = null;
						if(nJ < aJ){
							casa_meio = "#casa_"+(nI+1).toString()+"_"+(nJ+1).toString();

						}else{
							casa_meio = "#casa_"+(nI+1).toString()+"_"+(nJ-1).toString();
						}
						if($(casa_meio).children().size()>0)
						peca_meio = $(casa_meio).children("img");
						
						if(peca_meio != null){
							$("#compila").append(peca_meio);
							peca_meio.remove();
							pontos_brancas++;
							$("#info_pontos_brancas").text(pontos_brancas.toString());
							$("#"+casa_anterior).remove("#"+peca_anterior);
							$("#"+casa_selecionada).append(obj);
						}
					}else
					if((peca_anterior.indexOf("preta") >= 0))	{
						var casa_meio = null, peca_meio = null;
						if(nJ < aJ){
							casa_meio = "#casa_"+(nI-1).toString()+"_"+(nJ+1).toString();

						}else{
							casa_meio = "#casa_"+(nI-1).toString()+"_"+(nJ-1).toString();
						}
						if($(casa_meio).children().size()>0)
						peca_meio = $(casa_meio).children("img");
						if(peca_meio != null){ 
							peca_meio.remove();
							pontos_pretas++;
							$("#info_pontos_pretas").text(pontos_pretas.toString());
							$("#"+casa_anterior).remove("#"+peca_anterior);
							$("#"+casa_selecionada).append(obj);
						}
					}			
				}
			}
		}
	}
	else{
		$("#info_peca_selecionada").text(peca_selecionada.toString());
	}


	if(pontos_pretas == 12 || pontos_brancas == 12){
		$("#info").html("<h1>Fim de jogo!</h1>");
	} 

}); 
Listagem 3. Implementação da função que trata o evento onclick das casa/peças

As variáveis aI e aJ representam, respectivamente, os índices I e J (coordenadas X e Y) da peça ou casa anteriormente selecionadas. As variáveis nI e nJ, por sua vez, representam as coordenadas da casa atualmente selecionada. Por fim, as variáveis dI e dJ representam as diferenças entre as coordenadas (que possuem sempre um valor positivo).

Utilizamos então as variáveis obtidas no início do código para identificar as casa e peças envolvidas na jogada (a anterior, a atual e a do meio, no caso da comida).

Caso o jogada seja de comida, identificamos a casa do meio e, se houver uma peça nela e essa peça pertencer ao adversário, ela desaparece do jogo e a pontuação de quem efetuou a jogada é incrementada.

Para finalizar, caso uma das pontuações atinja o valor 12, é exibida mensagem “Fim de Jogo” onde inicialmente havia as informações do jogo.

O código em si não é complexo, porém, explicar cada parte detalhadamente tornaria este artigo demasiadamente longo. Então, ponho-me à disposição para sanar qualquer dúvida que venha a surgir durante a leitura. O entendimento do código se torna mais fácil na prática, então o código-fonte está disponível no topo desta página para que possa ser baixado e testado.