/* Jeu des dix pièces alignées
               pions
               grenouilles ...
	deux.js (C) 2009 Jean-Paul Davalan
	le programme javascript deux.js est utilisé sur la page
        http://jeux-et-mathematiques.davalan.org/jeux/solitaires/dix/index.html
	(ou sur les pages équivalentes des sites miroirs)
*/
var MAXCASES=20

function jeu(nc, h, l) {
	this.txt=""
	this.ncases=nc
	this.cases=new Array()
	this.ncoups=0
	this.njoues=0
	this.ngains=0
	this.etat = "attente"
	this.hmax=h
	this.lsaut=l;
	this.hfin=0
	this.nfin=0
	this.ntas=Math.floor(nc/h)
	this.histor=new Array()
	this.chist=""
	//this.pref="c"
	//this.suff="png"
	this.alerte = function() {
	}
	this.rem = function(s) {
		/*
		this.txt = s+"<br>"+this.txt
		document.getElementById("logs").innerHTML=this.txt
		*/
		
	}
	this.initpartie = function() {
		this.etat="partie"
		document.getElementById("resultat").innerHTML=""
		document.getElementById("logs").innerHTML=""
		document.getElementById("sols").innerHTML=""
		this.ncoups=0
		for(i=0; i< MAXCASES; i++) this.cases[i] = 0;
		for(i=0; i< this.ncases; i++) this.cases[i] = 1;
		this.affiche()
		this.chist=this.ncases+" : "
		this.txt=""
		this.rem("init partie")
	}

	this.init = function() {
		this.njoues=this.ngains=0
		this.initpartie()
	}
	this.clic = function(k, sens) {
		//alert(this.etat+" "+k+" "+sens)
		this.rem("clic sur la case "+k+" à "+(sens==-1)?"gauche":"droite")
		if(this.etat != "partie") {
			//this.alerte()
			this.rem("Partie finie")
			return;
		}
		//alert(this.cases[k])
		if(this.cases[k]==0) {
			this.rem("clic sur une case vide")
			return;
		}
		
		var p = this.teste(k, sens)
		//alert("teste "+p)
		if(0<=p && p<this.ncases) {
			this.effect(k, p)
		} else {
			//this.alerte() 
			//this.alert(this.possible2())
			if( ! this.possible()) {
				this.rem("Aucune possibilité de jeu")
				this.finpartie(false) 
			}
		}
	}
	this.teste= function(k, sens) {
		if(this.cases[k]==0) return -1
		var u=0
		var t = (sens==-1) ? -1 : 1
		for(var i=k+t; i>=0 && i< this.ncases && u<=this.hmax; i+=t) {
			if(this.cases[i]>=1) { // && this.cases[i]+this.cases[k]<=this.hmax) {
					u++
					if(u==this.lsaut) {
						if(this.cases[i]+this.cases[k]<=this.hmax) {
							this.rem("la case "+i+" convient")
							return i
						} else {
							this.rem("Teste : "+k+" "+sens+" "+i+" "+this.cases[i]+"+"+this.cases[k]+"="+(this.cases[i]+this.cases[k]))
							//alert(k+" "+sens+" "+i+" "+this.cases[i]+"+"+this.cases[k]+"="+(this.cases[i]+this.cases[k]))
							return -1
						}
					}
			}		
		 } 
		this.rem("Teste (fin) : "+k+" "+sens+" "+i+" "+this.cases[k])
		return -1
	}

	this.possible2 = function() {
		for(var s = -1; s<=1; s+=2) {
			for(var i=0; i<this.ncases; i++) {
				if( this.cases[i]>=1 && this.teste(i, s) >=0) {
					this.rem("Possible2 : "+i+" "+s)
					return i+" "+s
				}
			}
		}
		this.rem("Possible2 : non")
		return "false"
	}
        this.possible = function() {
                for(var s = -1; s<=1; s+=2) {
                        for(var i=0; i<this.ncases; i++) {
                                if( this.teste(i, s) >=0) {
					this.rem("Possible : "+i+" "+s)
					return true
				}
                        }
                }
		this.rem("Possible : non")
                return false
        }

	this.effect = function(k, p) {
		this.ncoups++
		this.chist += (k+1)+"->"+(p+1)+",&nbsp;"
		this.cases[p] += this.cases[k]
		this.cases[k]=0;
		if(this.testefin()) {
			
			this.ngains++
			this.affiche()
			this.rem("fin partie, gains : "+this.ngains);
			//this.njoues++
			this.finpartie(true)
		}
		this.affiche()
	}
	this.testefin = function() {
		this.hfin=0
		for(var i=0; i<this.ncases; i++) {
			if(this.hfin==0 && this.cases[i]!=0) this.hfin = this.cases[i]
			if(this.cases[i] !=this.hfin && this.cases[i]!=0) return false
		}
		this.nfin = this.ncases/this.hfin
		return true;
	}
 	
	this.affiche = function() {
		for(var i=0; i<20; i++) {
			var ima = document.images["im"+i]
			ima.src = imge[this.cases[i]].src
			if(this.cases[i]==0) {
				
				ima.width=0
			} else { 
				ima.width=40
			}
		}			
	}
	this.affsols = function() {
		var lh = this.histor.length
		var s = lh+" solution"+((lh>1)?"s":"")+" :<br>"
		for(var i=0; i< this.histor.length; i++) {
			s += (1+i)+")  "+this.histor[i]+"<br>"
		}
		document.getElementById("sols").innerHTML=s
	}

	this.addsol = function() {
		for(var i=0; i< this.histor.length; i++) {
			if(this.histor[i]==this.chist) {
				this.rem("La solution n'est pas nouvelle")
				return false
			}
		}
		this.histor.push(this.chist);
		return true
	}
	this.finpartie = function(b) {
		var s 
		this.etat="fin"
		this.njoues++
		this.rem("Partie "+((b)?"gagnée":"perdue")+"  Nb jeux : "+this.njoues+"  Gagnées : "+this.ngains)
		if(b==true) {
			var v = this.addsol()
			s = "<span style='color:green;font-weight:bolder'>BRAVO.</span> Vous avez réussi à obtenir "+this.nfin+" tas de "+this.hfin+" pièces."
			if(v==true) s += "Cette solution est nouvelle."
			else s += "Cette solution n'est pas nouvelle pour vous."
		} else {
			s = "<span style='color:red'>Le jeu est bloqué,</span> vous ne pourrez pas obtenir des tas d'un même nombre de pièces dans cette partie."
		}
		if(this.ngains==0) {
			s += "<br>Vous n'avez gagné aucune partie "
		} else if(this.ngains==1) {
			s += "<br>Vous avez gagné une partie "
		} else {
			s += "<br>Vous avez gagné "+ this.ngains+" parties "
		}
		if(this.njoues==1) {
			s += "sur une partie jouée. <br>"
		} else if(this.njoues>1) {
			s += " sur "+this.njoues+" parties jouées.<br>"
		}
		var nh=this.histor.length
		if(nh>0) {
			s += "Le nombre de solutions différentes trouvées est "+nh+"<br>"
		}
		s += "<br />Vous pouvez jouer une nouvelle partie en cliquant sur le bouton [Nouvelle partie]"
		document.getElementById("resultat").innerHTML=s
		this.affsols()
	}

}


var imge = new Array(20);

for(var i=0; i<=20; i++) {
	imge[i] = new Image()
	imge[i].src = "d"+i+".png"
}

// jeu(nc, h, l)
var x = new jeu(20,20,3)


function clk(k, s) {
	//alert(k+" "+s)
	x.clic(k, s)
	
}

function partie() {
	//alert("partie")
	x.initpartie()
}
		
function reinit() {
	if(x!=null) delete(x)
	var tas = parseInt(document.frm.tas.value)
	var hmax = parseInt(document.frm.hmax.value)
	var saut = parseInt(document.frm.saut.value)
	x = new jeu(tas, hmax, saut)
	x.init()
}

function exple(s) {
	var t = s.split(/[\s\,\;\:]+/g);
	document.frm.tas.value=t[0]
	document.frm.hmax.value=t[1]
	document.frm.saut.value=t[2]
	reinit()
}



