358 lines
10 KiB
JavaScript
358 lines
10 KiB
JavaScript
/* [0] Constructeur -> définit le conteneur et le bouton d'ajout
|
|
=========================================================*/
|
|
function inputPhoneMatrice(container){
|
|
this.container = container;
|
|
}
|
|
|
|
/* [1] Attributs
|
|
=========================================================*/
|
|
inputPhoneMatrice.prototype = {
|
|
container: this.container // Conteneur de la matrice
|
|
};
|
|
|
|
|
|
/* [2] Gestion de l'enregistrement de la matrice
|
|
=========================================================*/
|
|
inputPhoneMatrice.prototype.fieldsToStorage = function(){
|
|
console.log('MATRICE: FIELDS TO STORAGE');
|
|
|
|
|
|
// {1} On initialise notre deflater pour récupérer les valeurs //
|
|
var deflater = new FormDeflater(this.container, ['input'], ['data-name']);
|
|
|
|
// {2} On extrait les données //
|
|
var deflated = deflater.deflate();
|
|
// On crée le hash
|
|
var deflatedHash = crc32(JSON.stringify(deflated));
|
|
|
|
|
|
// console.log(deflated);
|
|
|
|
/* (3) On crée l'objet et on le remplit avec les relations */
|
|
var obj = {};
|
|
|
|
for( var i in deflated )
|
|
|
|
// {1} Si c'est un tableau de sujets //
|
|
if( deflated[i] instanceof Array ){
|
|
|
|
// Pour chacune des différentes relations, on ajoute si TRUE
|
|
for( var a in deflated[i] ){
|
|
if( obj[i] == null )
|
|
obj[i] = [];
|
|
|
|
obj[i].push( parseInt(deflated[i][a]) );
|
|
}
|
|
|
|
// {2} Si il n'y a qu'un sujet //
|
|
}else if( deflated[i] !== null ){
|
|
if( obj[i] == null )
|
|
obj[i] = [];
|
|
|
|
obj[i].push( parseInt(deflated[i]) );
|
|
}
|
|
|
|
lsi.set( 'p_matrice', 0, obj );
|
|
// Objet de la forme
|
|
//
|
|
// idA: [idV, idW], # A connait V et W (et réciproquement)
|
|
// idB: [idX, idY], # B connait X et Y (et réciproquement)
|
|
// ...
|
|
//
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* [4] Gestion de l'affichage depuis le 'localStorage'
|
|
=========================================================*/
|
|
inputPhoneMatrice.prototype.storageToFields = function(){
|
|
console.log('MATRICE: STORAGE TO FIELDS');
|
|
|
|
/* (1) On récupère la liste des contacts à mettre dans la matrice */
|
|
// On récupère les fiches
|
|
var ficheData = lsi.export('p_fiches');
|
|
|
|
// On récupère les données de la matrice
|
|
var matriceData = lsi.get('p_matrice', 0);
|
|
|
|
// On récupère les contacts pour afficher les noms/prénoms
|
|
var contactData = lsi.export('p_contacts');
|
|
|
|
// Contiendra les UID des contacts à mettre dans la matrice
|
|
var contacts = [];
|
|
|
|
// Pour chaque fiche, on ajoute l'uid du contact s'il n'est pas déja ajouté
|
|
for( var f in ficheData )
|
|
if( contacts.indexOf( ficheData[f].contact ) == -1 )
|
|
contacts.push( ficheData[f].contact );
|
|
|
|
|
|
/* (2) On construit le HTML de la matrice */
|
|
// Contiendra le HTML
|
|
var matrice_html = "<table class='line'>";
|
|
|
|
// {1} Pour chaque ligne //
|
|
for( var A = 0 ; A < contacts.length ; A++ ){
|
|
var conA = contactData[A];
|
|
|
|
|
|
matrice_html += '<tr>';
|
|
|
|
if( A > 0 ){ // Noms sur la première ligne (abscisses)
|
|
matrice_html += '<td style="text-align: right;">';
|
|
matrice_html += conA.username;
|
|
matrice_html += '</td>';
|
|
}else // Sinon,
|
|
matrice_html += '<td></td>';
|
|
|
|
// {2} Pour chaque case //
|
|
for( var B = 0 ; B < contacts.length ; B++ ){ if( B < contacts.length-1 ){
|
|
var conB = contactData[B];
|
|
|
|
// {3} Première colonne -> Intitulé des ordonnées //
|
|
if( A == 0 ){
|
|
matrice_html += '<td>';
|
|
matrice_html += '<span style="writing-mode: vertical-lr; text-align: right;">';
|
|
matrice_html += conB.username;
|
|
matrice_html += '</span>';
|
|
|
|
// {4} Valeurs des relations (boutons) //
|
|
}else if( B < A ){
|
|
matrice_html += "<td>";
|
|
matrice_html += "<input type='checkbox' name='matrice_"+conA.uid+"_"+conB.uid+"' data-name='"+conA.uid+"' value='"+conB.uid+"' id='p_matrice_"+conA.uid+"_"+conB.uid+"'";
|
|
// Si la relation existe, on active le bouton
|
|
if( matriceData[A] != null && matriceData[A].indexOf(B) > -1 )
|
|
matrice_html += " checked";
|
|
matrice_html += " >";
|
|
matrice_html += "<label for='p_matrice_"+conA.uid+"_"+conB.uid+"'></label>";
|
|
|
|
// {5} Cases vides (moitié supérieure droite) //
|
|
}else
|
|
matrice_html += "<td class='hidden'>";
|
|
|
|
matrice_html += '</td>';
|
|
}}
|
|
|
|
matrice_html += '</tr>';
|
|
}
|
|
matrice_html += '</table>';
|
|
|
|
|
|
/* (3) On affiche la matrice */
|
|
this.container.innerHTML = matrice_html;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* [9] Point d'amorçage de la gestion des contacts
|
|
=========================================================*/
|
|
inputPhoneMatrice.prototype.attach = function(){
|
|
console.log('MATRICE: ATTACH');
|
|
|
|
/* (1) On initialise le jeu de données */
|
|
lsi.createDataset('p_matrice');
|
|
|
|
/* (2) On charge les mini fiches depuis la mémoire ('localStorage') */
|
|
this.storageToFields();
|
|
|
|
/* (3) On enregistre la matrice à chaque modification */
|
|
var ptr = this;
|
|
this.container.addEventListener('click', function(e){
|
|
ptr.fieldsToStorage();
|
|
ptr.storageToFields();
|
|
}, false);
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inputPhoneMatrice.prototype.parseGrid = function(){
|
|
/* (1) On récupère la matrice des éléments de la grille */
|
|
var gridElements = $$('.matrice-panel input[data-name][value]');
|
|
for( var i in gridElements ){
|
|
if( !(gridElements[i] instanceof Element) )
|
|
continue;
|
|
|
|
var col = gridElements[i].getData('name');
|
|
var row = gridElements[i].value;
|
|
|
|
if( !(this.sGrid[col] instanceof Array) )
|
|
this.sGrid[col] = [];
|
|
|
|
this.sGrid[col][row] = gridElements[i];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
inputPhoneMatrice.prototype.snake = function(){
|
|
|
|
/* [0] On écrit les fonctions principales
|
|
=========================================================*/
|
|
/* (1) ATTRIBUTS */
|
|
this.sVelocity = [0, 0];
|
|
this.sLength = 2;
|
|
this.sStack = [];
|
|
this.sKeys = [];
|
|
this.sGrid = [];
|
|
this.sTarget = null;
|
|
this.sRoutine = null;
|
|
var ptr = this;
|
|
|
|
/* (2) ON RECUPERE LA MATRICE D'ELEMENTS */
|
|
this.parseGrid();
|
|
|
|
/* (2) On positionne le joueur au milieu */
|
|
var midcol = parseInt( this.sGrid.length / 2 );
|
|
var midrow = parseInt( this.sGrid[midcol].length / 2 );
|
|
this.sStack.push( this.sGrid[midcol][midrow] );
|
|
|
|
/* (3) On positionne la cible */
|
|
var tool = { correct: false }
|
|
while( !tool.correct ){
|
|
tool.col = Math.floor( Math.random()*this.sGrid.length );
|
|
tool.row = Math.floor( Math.random()*this.sGrid[tool.col].length );
|
|
tool.correct = this.sGrid[tool.col] != null && this.sGrid[tool.col][tool.row] != null;
|
|
tool.correct = tool.correct && this.sStack.indexOf(this.sGrid[tool.col][tool.row]) == -1;
|
|
}
|
|
this.sTarget = this.sGrid[tool.col][tool.row];
|
|
|
|
/* [1] Gestion des handlers
|
|
=========================================================*/
|
|
/* (1) Pression sur touche */
|
|
document.body.addEventListener('keydown', function(e){
|
|
// Si une fleche, on l'enregistre si elle ne l'est pas déja
|
|
if( [37, 38, 39, 40].indexOf(e.keyCode) > -1 && ptr.sKeys.indexOf(e.keyCode) == -1 )
|
|
ptr.sKeys.push(e.keyCode);
|
|
}, false);
|
|
|
|
/* (2) Relachement touche */
|
|
document.body.addEventListener('keyup', function(e){
|
|
var index = ptr.sKeys.indexOf(e.keyCode);
|
|
// Si une fleche, on la retire si elle ne l'est pas déja
|
|
if( [37, 38, 39, 40].indexOf(e.keyCode) > -1 && index > -1 )
|
|
ptr.sKeys.splice(index);
|
|
}, false);
|
|
|
|
/* [2] Lancement de la boucle de jeu
|
|
=========================================================*/
|
|
this.sRoutine = setInterval(function(){
|
|
/* (1) Gestion de la vélocité en fonction des touches */
|
|
if( ptr.sKeys.indexOf(37) > -1 ) // Vers la gauche
|
|
ptr.sVelocity[0] = -1;
|
|
else if( ptr.sKeys.indexOf(39) > -1 ) // Vers la droite
|
|
ptr.sVelocity[0] = 1;
|
|
|
|
if( ptr.sKeys.indexOf(38) > -1 ) // Vers le haut
|
|
ptr.sVelocity[1] = -1;
|
|
else if( ptr.sKeys.indexOf(40) > -1 ) // Vers le bas
|
|
ptr.sVelocity[1] = 1;
|
|
else if( ptr.sVelocity[0] != 0 )
|
|
ptr.sVelocity[1] = 0;
|
|
|
|
if( ptr.sKeys.indexOf(37)+ptr.sKeys.indexOf(39) == -2 && ptr.sVelocity[1] != 0 )
|
|
ptr.sVelocity[0] = 0;
|
|
|
|
// Dernier element de la pile
|
|
var lastStack = ptr.sStack[ ptr.sStack.length-1 ];
|
|
var lastcol = parseInt( lastStack.getData('name') );
|
|
var lastrow = parseInt( lastStack.value );
|
|
|
|
/* (2) Gestion du mouvement */
|
|
lastrow = (lastrow + ptr.sVelocity[0]) % ptr.sGrid[lastcol].length;
|
|
if( lastrow < 0 ) lastrow = ptr.sGrid[lastcol].length - 1;
|
|
|
|
lastcol = (lastcol + ptr.sVelocity[1]) % ptr.sGrid.length;
|
|
if( lastcol <= 0 ) lastcol = lastrow+1;
|
|
if( ptr.sGrid[lastcol] == null || ptr.sGrid[lastcol][lastrow] == null )
|
|
lastcol = ptr.sGrid.length-1;
|
|
|
|
|
|
|
|
if( ptr.sGrid[lastcol] != null && ptr.sGrid[lastcol][lastrow] != null ){
|
|
|
|
/* (1) Si la case est déja prisse */
|
|
if( ptr.sGrid[lastcol][lastrow].checked ){
|
|
/* (2) Si on c'est la cible */
|
|
if( ptr.sGrid[lastcol][lastrow].id == ptr.sTarget.id ){
|
|
ptr.sLength++;
|
|
|
|
// On repositionne la cible
|
|
var tool = { correct: false }
|
|
while( !tool.correct ){
|
|
tool.col = Math.floor( Math.random()*ptr.sGrid.length );
|
|
tool.row = Math.floor( Math.random()*ptr.sGrid[tool.col].length );
|
|
tool.correct = ptr.sGrid[tool.col] != null && ptr.sGrid[tool.col][tool.row] != null;
|
|
tool.correct = tool.correct && ptr.sStack.indexOf(ptr.sGrid[tool.col][tool.row]) == -1;
|
|
}
|
|
ptr.sTarget = ptr.sGrid[tool.col][tool.row];
|
|
}
|
|
|
|
/* (3) Si on se mord la queue (mais pas la tete)*/
|
|
else if( ptr.sStack[ptr.sStack.length-1].id != ptr.sGrid[lastcol][lastrow].id ){
|
|
console.log(ptr.sStack[ptr.sStack.length-1].id, ptr.sGrid[lastcol][lastrow].id );
|
|
alert('vous avez perdu! Score: '+(ptr.sLength-2) );
|
|
clearInterval(ptr.sRoutine);
|
|
}
|
|
}
|
|
ptr.sStack.push( ptr.sGrid[lastcol][lastrow] );
|
|
}
|
|
|
|
|
|
|
|
/* (3) On affiche que les cases de la pile */
|
|
var matrix = [];
|
|
for( var i in ptr.sStack ){
|
|
var col = ptr.sStack[i].getData('name');
|
|
var row = ptr.sStack[i].value;
|
|
|
|
if( matrix[col] == null )
|
|
matrix[col] = [];
|
|
|
|
matrix[col].push( parseInt(row) );
|
|
}
|
|
|
|
/* (4) On ajoute la cible */
|
|
if( ptr.sTarget != null ){
|
|
var col = ptr.sTarget.getData('name');
|
|
var row = ptr.sTarget.value;
|
|
|
|
if( matrix[col] == null )
|
|
matrix[col] = [];
|
|
|
|
matrix[col].push( parseInt(row) );
|
|
}
|
|
|
|
|
|
/* (5) Enregistrement du modèle */
|
|
lsi.set('p_matrice', 0, matrix);
|
|
ptr.storageToFields();
|
|
ptr.parseGrid();
|
|
|
|
|
|
/* (6) On vide les cases dépassant sLength */
|
|
var len = ptr.sStack.length;
|
|
|
|
if( len >= ptr.sLength )
|
|
ptr.sStack = ptr.sStack.slice( 1+len-ptr.sLength );
|
|
|
|
document.location ='#snake';
|
|
|
|
}, 200);
|
|
|
|
};
|