|
@@ -217,7 +217,7 @@ function rever () { // vetorMovimentos = { clickDe + " " + clickPara, ... }
|
|
movaHaste(para); // 'clickPara' tem que estar com -1 para completar movimento
|
|
movaHaste(para); // 'clickPara' tem que estar com -1 para completar movimento
|
|
mensagem = msgReverProx; // clique novamente no 'Rever'
|
|
mensagem = msgReverProx; // clique novamente no 'Rever'
|
|
desenhaTudo();
|
|
desenhaTudo();
|
|
- console.lgo("rever(): final");
|
|
|
|
|
|
+ console.log("rever(): final");
|
|
} // rever()
|
|
} // rever()
|
|
// Fim --- Para rever movimentos ja' realizados
|
|
// Fim --- Para rever movimentos ja' realizados
|
|
|
|
|
|
@@ -246,7 +246,7 @@ function reiniciar (nD) {
|
|
redefineDiscos(nDiscos);
|
|
redefineDiscos(nDiscos);
|
|
mensagem = mensagem0;
|
|
mensagem = mensagem0;
|
|
desenhaTudo();
|
|
desenhaTudo();
|
|
- //console.lgo("reiniciar(nD): final");
|
|
|
|
|
|
+ console.log("reiniciar(nD): final");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -356,165 +356,109 @@ function pegaHaste (hi) {
|
|
// Devolve: 0=nao moveu tudo; 1=moveu tudo para haste B; 2=moveu tudo para haste B com minimo de movimentos;
|
|
// Devolve: 0=nao moveu tudo; 1=moveu tudo para haste B; 2=moveu tudo para haste B com minimo de movimentos;
|
|
// 3=moveu tudo par haste C; 4=moveu tudo par haste C com minimo de movimentos
|
|
// 3=moveu tudo par haste C; 4=moveu tudo par haste C com minimo de movimentos
|
|
function movimentoFinal (haste, num) {
|
|
function movimentoFinal (haste, num) {
|
|
- var topo = pegaTopoHaste(haste);
|
|
|
|
- if (topo == nDiscos - 1) // Moveu tudo
|
|
|
|
- {
|
|
|
|
- if (haste == 2) // Moveu para haste C
|
|
|
|
- {
|
|
|
|
- if (contador == 2^nDiscos - 1 || (nDiscos == 1 && contador == 1))
|
|
|
|
- { // Moveu para haste C com minimo
|
|
|
|
- return 4;
|
|
|
|
- }
|
|
|
|
- return 3; // Moveu para haste C
|
|
|
|
|
|
+ var topo = pegaTopoHaste(haste);
|
|
|
|
+ if (topo == nDiscos-1) { // moveu tudo!
|
|
|
|
+ if (haste == 2) { // moveu para haste C
|
|
|
|
+ if (contador == (2**nDiscos)-1) { // moveu para haste C com minimo
|
|
|
|
+ return 4;
|
|
}
|
|
}
|
|
- if (haste == 1)
|
|
|
|
- {
|
|
|
|
- if (contador == 2^nDiscos - 1 || (nDiscos == 1 && contador == 1))
|
|
|
|
- { // Moveu para haste B com minimo
|
|
|
|
- return 2;
|
|
|
|
- }
|
|
|
|
- return 1; // Moveu para a haste B
|
|
|
|
|
|
+ return 3; // moveu para haste C mas nao e' minimo
|
|
|
|
+ }
|
|
|
|
+ if (haste == 1) { // moveu para haste B
|
|
|
|
+ if (contador == (2**nDiscos)-1) { // moveu para haste B com minimo
|
|
|
|
+ return 2; // msgTeste2
|
|
}
|
|
}
|
|
|
|
+ return 1; // moveu para haste C mas nao e' minimo
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- return 0; //Falha em mover tudo
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* Atualizacao botao automático e velocidade
|
|
|
|
- * Resolve a torre de hanoi usando recursão
|
|
|
|
- * TODO: Solucionar renderização
|
|
|
|
- */
|
|
|
|
-function solve(n, origem, destino, aux)
|
|
|
|
-{
|
|
|
|
- //alert("Ciclo: " + counter + "; movimento: " + mov)
|
|
|
|
- if (n == 1)
|
|
|
|
- {
|
|
|
|
- // O menor disco (1) se move livremente em qualquer haste
|
|
|
|
- movaHaste(origem);
|
|
|
|
- movaHaste(destino);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- // Retirar discos menores "do caminho"
|
|
|
|
- solve(n - 1, origem, aux, destino);
|
|
|
|
-
|
|
|
|
- // Mover maior disco para o destino
|
|
|
|
- movaHaste(origem);
|
|
|
|
- movaHaste(destino);
|
|
|
|
-
|
|
|
|
- /* Problema: sleep() têm sucesso em atrasar o algoritmo
|
|
|
|
- * Porém a renderização por algum motivo não acontece em paralelo
|
|
|
|
- * Isso impede o aluno de assistir os movimentos acontecerem
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
- //Mover os discos menores para cima do maior novamente
|
|
|
|
- solve(n - 1, aux, destino, origem);
|
|
|
|
-}
|
|
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
|
|
-// Verifica posicao dos discos e chama a funcao recursiva
|
|
|
|
-function autoCheck()
|
|
|
|
-{
|
|
|
|
- reiniciar(nDiscos); //formula nao funciona caso os discos estejam desorganizados
|
|
|
|
- solve(nDiscos, 0, 2 ,1);
|
|
|
|
-}
|
|
|
|
|
|
|
|
// Mover disco do topo da haste 'clickDe' para a haste 'hi' (sem 'clickDe' definido)
|
|
// Mover disco do topo da haste 'clickDe' para a haste 'hi' (sem 'clickDe' definido)
|
|
-function movaHaste (hi)
|
|
|
|
-{
|
|
|
|
- var strHaste = pegaHaste(hi); //Retorna haste A, B ou C para 0, 1 e 2 respectivamente
|
|
|
|
- var de0 = clickDe, para0 = clickPara;
|
|
|
|
- if (clickDe == -1 && clickPara == -1) // Começo do movimento
|
|
|
|
- {
|
|
|
|
- clickDe = hi;
|
|
|
|
- topoDe = pegaTopoHaste(clickDe); // Pega disco no topo da haste
|
|
|
|
- if (topoDe == -1) // Erro: sem discos na haste
|
|
|
|
- {
|
|
|
|
- mensagem = "Haste " + strHaste + " está vazia! Por favor, selecione haste inicial com algum disco";
|
|
|
|
- clickDe = clickPara = -1;
|
|
|
|
- desenhaMensagem();
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- mensagem = "Origem: " + strHaste + " - Agora clique na haste destino";
|
|
|
|
- de0 = hi;
|
|
|
|
- desenhaMensagem();
|
|
|
|
|
|
+function movaHaste (hi) {
|
|
|
|
+ var strHaste = pegaHaste(hi);
|
|
|
|
+ var de0 = clickDe, para0 = clickPara;
|
|
|
|
+ if (clickDe==-1 && clickPara==-1) { // inicio movimento
|
|
|
|
+ clickDe = hi;
|
|
|
|
+ topoDe = pegaTopoHaste(clickDe); // pega disco no topo de haste
|
|
|
|
+ if (topoDe==-1) { // nao tem discos
|
|
|
|
+ mensagem = "Haste " + strHaste + " está vazia! Por favor, selecione haste inicial com algum disco";
|
|
|
|
+ clickDe = clickPara = -1;
|
|
|
|
+ desenhaMensagem();
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ mensagem = "Origem: " + strHaste + " - Agora clique na haste destino";
|
|
|
|
+ de0 = hi;
|
|
|
|
+ desenhaMensagem();
|
|
}
|
|
}
|
|
- else
|
|
|
|
- if (clickDe > -1 && clickPara == -1) // Final do movimento
|
|
|
|
- {
|
|
|
|
- clickPara = hi;
|
|
|
|
- para0 = hi;
|
|
|
|
- topoDe = pegaTopoHaste(clickDe); // devolve indice topo de haste
|
|
|
|
- topoPara = pegaTopoHaste(clickPara); // devolve indice topo de haste
|
|
|
|
-
|
|
|
|
- if (clickDe == clickPara) // Erro: origem e destino são iguais
|
|
|
|
- {
|
|
|
|
- str_haste = pegaHaste(clickDe);
|
|
|
|
- mensagem = msgDeParaIguais + " (haste " + str_haste + ")";
|
|
|
|
- console.log("Erro: Tentando mover disco para a mesma haste! (haste " + str_haste + ")");
|
|
|
|
- clickDe = clickPara = -1; // Restart no movimento
|
|
|
|
- desenhaMensagem();
|
|
|
|
- return -1;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (topoPara > -1 && matHastes[clickDe][topoDe] > matHastes[clickPara][topoPara]) // Erro: disco maior sobre menor
|
|
|
|
- {
|
|
|
|
- mensagem = mensagem2_1 + " (" + matHastes[clickDe][topoDe] + mensagem2_2 + matHastes[clickPara][topoPara] + ")";
|
|
|
|
- clickDe = clickPara = -1; // Restart no movimento
|
|
|
|
- desenhaMensagem();
|
|
|
|
- return -1;
|
|
|
|
- }
|
|
|
|
- vetorMovimentos.push(clickDe + " " + clickPara);
|
|
|
|
- if (topoDe < 0) { console.log("movaHaste("+hi+"): "+clickDe + " " + clickPara+": erro! undefined"); } // Debug
|
|
|
|
- atualizaTopos(topoDe, topoPara);
|
|
|
|
- contador++;
|
|
|
|
-
|
|
|
|
- /* 0 = nao moveu tudo
|
|
|
|
- * 1=moveu tudo para haste B; 2=moveu tudo para haste B com minimo de movimentos
|
|
|
|
- * 3=moveu tudo para haste C; 4=moveu tudo para haste C com minimo de movimentos
|
|
|
|
- */
|
|
|
|
- respostaMov = movimentoFinal(hi, contador);
|
|
|
|
-
|
|
|
|
- switch (respostaMov)
|
|
|
|
- {
|
|
|
|
- case 0: mensagem = mensagem3_1 + strHaste + mensagem3_2; break;
|
|
|
|
- case 1: mensagem = msgTeste1 + contador + mensagem1_2; break;
|
|
|
|
- case 2: mensagem = msgTeste2 + contador + mensagem1_2; break;
|
|
|
|
- case 3: mensagem = msgTeste3 + contador + mensagem1_2; break;
|
|
|
|
- case 4: mensagem = msgTeste4 + contador + mensagem1_2; break;
|
|
|
|
- mensagem = mensagem1_1 + contador + mensagem1_2;
|
|
|
|
- }
|
|
|
|
- desenhaTudo();
|
|
|
|
|
|
+ else
|
|
|
|
+ if (clickDe>-1 && clickPara==-1) { // final do movimento
|
|
|
|
+ clickPara = hi;
|
|
|
|
+ para0 = hi;
|
|
|
|
+ //D alert("De="+clickDe+", Para="+clickPara+", hi="+hi);
|
|
|
|
+ topoDe = pegaTopoHaste(clickDe); // devolve indice topo de haste
|
|
|
|
+ topoPara = pegaTopoHaste(clickPara); // devolve indice topo de haste
|
|
|
|
+ if (clickDe == clickPara) {
|
|
|
|
+ str_haste = pegaHaste(clickDe); // nome da haste: "A", "B" ou "C"
|
|
|
|
+ mensagem = msgDeParaIguais + " (haste " + str_haste + ")";
|
|
|
|
+ console.log("Erro: Tentando mover disco para a mesma haste! (haste " + str_haste + ")");
|
|
|
|
+ clickDe = clickPara = -1; // comeca novamente...
|
|
|
|
+ desenhaMensagem();
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ if (topoPara>-1 && matHastes[clickDe][topoDe]>matHastes[clickPara][topoPara]) { // disco maior sobre menor : proibido!
|
|
|
|
+ mensagem = mensagem2_1 + " (" + matHastes[clickDe][topoDe] + mensagem2_2 + matHastes[clickPara][topoPara] + ")";
|
|
|
|
+ //D alert("De="+clickDe+", Para="+clickPara+": "+topoDe+","+topoPara+": " + imprimeMovimentos(-1));
|
|
|
|
+ clickDe = clickPara = -1; // comeca novamente...
|
|
|
|
+ desenhaMensagem();
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ vetorMovimentos.push(clickDe + " " + clickPara);
|
|
|
|
+ if (topoDe<0) { console.log("movaHaste("+hi+"): "+clickDe + " " + clickPara+": erro! undefined"); } //DEBUG
|
|
|
|
+ atualizaTopos(topoDe, topoPara);
|
|
|
|
+ contador++;
|
|
|
|
+
|
|
|
|
+ // 0=nao moveu tudo; 1=moveu tudo para haste B; 2=moveu tudo para haste B com minimo de movimentos;
|
|
|
|
+ // 3=moveu tudo par haste C; 4=moveu tudo par haste C com minimo de movimentos
|
|
|
|
+ respostaMov = movimentoFinal(hi, contador);
|
|
|
|
+
|
|
|
|
+ switch (respostaMov) {
|
|
|
|
+ case 0: mensagem = mensagem3_1 + strHaste + mensagem3_2; break;
|
|
|
|
+ case 1: mensagem = msgTeste1 + contador + mensagem1_2; break;
|
|
|
|
+ case 2: mensagem = msgTeste2 + contador + mensagem1_2; break;
|
|
|
|
+ case 3: mensagem = msgTeste3 + contador + mensagem1_2; break;
|
|
|
|
+ case 4: mensagem = msgTeste4 + contador + mensagem1_2; break;
|
|
|
|
+ mensagem = mensagem1_1 + contador + mensagem1_2; // Paranbens! (falta comparar com numero minimo!)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ desenhaTudo();
|
|
}
|
|
}
|
|
- console.log("movaHaste(hi): final");
|
|
|
|
- return 1;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
|
|
+ console.log("movaHaste(hi): final");
|
|
|
|
+ return 1;
|
|
|
|
+ } // movaHaste(hi)
|
|
|
|
|
|
// Dispara eventos
|
|
// Dispara eventos
|
|
-function clickCanvas (mouseEvent)
|
|
|
|
-{
|
|
|
|
- var posx = mouseEvent.offsetX, posy = mouseEvent.offsetY; // Posicao do mouse, valores para parametros de .drawImage()
|
|
|
|
-
|
|
|
|
- if (posx > 25 && posx < 350 && posy > 30 && posy < 440) // Clicou na haste 1
|
|
|
|
- {
|
|
|
|
- resp = movaHaste(0);
|
|
|
|
|
|
+function clickCanvas (mouseEvent) {
|
|
|
|
+ var posx = mouseEvent.offsetX, posy = mouseEvent.offsetY; // Posicao do "mouse", valores para parametros de '.drawImage(...)'
|
|
|
|
+ if (posx>25 && posx<350 && posy>30 && posy<440) { // > clicou na haste 1
|
|
|
|
+ resp = movaHaste(0);
|
|
}
|
|
}
|
|
- else
|
|
|
|
- if (posx > 350 && posx < 690 && posy > 30 && posy < 440) // Clicou na haste 2
|
|
|
|
- {
|
|
|
|
- resp = movaHaste(1);
|
|
|
|
|
|
+ else
|
|
|
|
+ if (posx>350 && posx<690 && posy>30 && posy<440) { // > clicou na haste 2
|
|
|
|
+ resp = movaHaste(1);
|
|
}
|
|
}
|
|
- else
|
|
|
|
- if (posx > 690 && posx < 1030 && posy > 30 && posy < 440) // Clicou na haste 3
|
|
|
|
- {
|
|
|
|
- resp = movaHaste(2);
|
|
|
|
|
|
+ else
|
|
|
|
+ if (posx>690 && posx<1030 && posy>30 && posy<440) { // > clicou na haste 3
|
|
|
|
+ resp = movaHaste(2);
|
|
}
|
|
}
|
|
- if (revendo) // estava revendo movimento mas clicou em haste, entao cancele revisao!
|
|
|
|
- {
|
|
|
|
- mensagem = msgReverPare; // "stava revendo movimentação, mas ao mover manualmente, a revisão foi finalizada!
|
|
|
|
- limparRevisao();
|
|
|
|
- desenhaMensagem(); //sem efeito, 'sleep(.)' nao permite aparecer a mensagem
|
|
|
|
|
|
+ if (revendo) { // estava revendo movimento mas clicou em haste, entao cancele revisao!
|
|
|
|
+ mensagem = msgReverPare; // "Estava revendo movimentação, mas ao mover manualmente, a revisão foi finalizada!"
|
|
|
|
+ limparRevisao();
|
|
|
|
+ desenhaMensagem(); //D sem efeito, nao 'sleep(.)' nao permite aparecer a mensagem
|
|
|
|
+ //sleep(1600); // em 'integration-functions.js'
|
|
}
|
|
}
|
|
-}
|
|
|
|
-
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
// Desenha um retangulo - modelo de http://jsfiddle.net/vu7dZ/1/
|
|
// Desenha um retangulo - modelo de http://jsfiddle.net/vu7dZ/1/
|
|
@@ -548,7 +492,6 @@ function desenhaDiscos () { // 'context' e' global
|
|
ind_disco = matHastes[0][0];
|
|
ind_disco = matHastes[0][0];
|
|
i = 0;
|
|
i = 0;
|
|
while (ind_disco!=-1) { // enquanto ainda tem disco, nao e' o ultimo
|
|
while (ind_disco!=-1) { // enquanto ainda tem disco, nao e' o ultimo
|
|
-
|
|
|
|
posx = 33 + (6 - ind_disco-1)*14; // para nDiscos=6 : usar 34 + ...
|
|
posx = 33 + (6 - ind_disco-1)*14; // para nDiscos=6 : usar 34 + ...
|
|
//TODO: precisa resolver um erro/advertencia que aparece
|
|
//TODO: precisa resolver um erro/advertencia que aparece
|
|
// TypeError: Argument 1 of CanvasRenderingContext2D.drawImage could not be converted to any of: HTMLImageElement, SVGImageElement, HTMLCanvasElement, HTMLVideoElement, ImageBitmap.
|
|
// TypeError: Argument 1 of CanvasRenderingContext2D.drawImage could not be converted to any of: HTMLImageElement, SVGImageElement, HTMLCanvasElement, HTMLVideoElement, ImageBitmap.
|
|
@@ -621,7 +564,7 @@ function desenhaTudo () {
|
|
context.fillText(" " + mensagemNM + contador, txtNMX, txtNMY); // numero de movimentos
|
|
context.fillText(" " + mensagemNM + contador, txtNMX, txtNMY); // numero de movimentos
|
|
desenhaDiscos();
|
|
desenhaDiscos();
|
|
console.log("desenhaTudo(): final");
|
|
console.log("desenhaTudo(): final");
|
|
-} // desenhaTudo()
|
|
|
|
|
|
+ } // desenhaTudo()
|
|
|
|
|
|
|
|
|
|
// Versao distinta para inicia - removida em favor do 'onload' no 'body'
|
|
// Versao distinta para inicia - removida em favor do 'onload' no 'body'
|
|
@@ -630,5 +573,28 @@ function desenhaTudo () {
|
|
// desenhaTudo();
|
|
// desenhaTudo();
|
|
// });
|
|
// });
|
|
|
|
|
|
|
|
+// -------------------- ATUALIZACAO --------------------
|
|
|
|
+/* Botao automatico e velocidade -> Resolve a torre de hanoi usando recursão
|
|
|
|
+ * TODO: corrigir sleep() nao atrasa o algoritmo adequadamente, tela nao atualiza
|
|
|
|
+ */
|
|
|
|
+function resolveAutomatico(n, origem, destino, aux) {
|
|
|
|
+ if (n == 1) { // O menor disco (1) se move livremente em qualquer haste
|
|
|
|
+ movaHaste(origem);
|
|
|
|
+ movaHaste(destino);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ resolveAutomatico(n - 1, origem, aux, destino); // Retirar discos menores do caminho
|
|
|
|
+ movaHaste(origem);
|
|
|
|
+ movaHaste(destino); // Mover maior disco para o destino
|
|
|
|
+ resolveAutomatico(n - 1, aux, destino, origem); //Mover os discos menores para cima do maior novamente
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+// Verifica posicao dos discos e chama a funcao recursiva
|
|
|
|
+function preparaAutomatico()
|
|
|
|
+{
|
|
|
|
+ reiniciar(nDiscos); //formula nao funciona caso os discos estejam desorganizados
|
|
|
|
+ resolveAutomatico(nDiscos, 0, 2 ,1);
|
|
|
|
+ }
|
|
|
|
+// -------------------- FIM DA ATUALIZACAO --------------------
|
|
|
|
|
|
console.log("iHanoi: final do JavaScript principal"); //D
|
|
console.log("iHanoi: final do JavaScript principal"); //D
|