Requet sql chevauchement interval de données [Résolu]

Signaler
-
Messages postés
1
Date d'inscription
mardi 14 avril 2020
Statut
Membre
Dernière intervention
14 avril 2020
-
Bonjour,
voici un petit problème que je croise dans un projet étudiant.
j'ai une base de donnée sur phpmyadmin PLATEAU_1 contenant ligne colonne valeur, ligne et colonne étant mes clé primaire valeur contenant 0,1ou 2.
je peux ainsi représenté un tableau bidimensionnel contenant ces 3 valeur pour chaque case.
je souéte compté les alignement de 4 horizontal vertical et diagonal pour une même valeur.
pour limité le sujet concentrons nous que su les diagonal.
j’obtiens en sql qui me liste les alignement de 4 en diagonal
SELECT DISTINCT T1.LIGNE AS L1,T1.COLUMNE AS C1, T4.LIGNE AS L4,T4.COLUMNE AS C4 
FROM PLATEAU_1 AS T1, PLATEAU_1 AS T2, PLATEAU_1 AS T3, PLATEAU_1 AS T4 
WHERE T1.VALUE=1 
AND ( T2.VALUE=T1.VALUE AND T2.COLUMNE=T1.COLUMNE+1 AND T2.LIGNE=T1.LIGNE+1 AND T3.VALUE=T2.VALUE AND T3.COLUMNE=T1.COLUMNE+2 AND T3.LIGNE=T1.LIGNE+2 AND T4.VALUE=T3.VALUE AND T4.COLUMNE=T1.COLUMNE+3 AND T4.LIGNE=T1.LIGNE+3 )

ce qui est tout à fait fonctionnel néanmoins je souéte ajouté des condition afin d'exclure les alignement qui se chevauche.et cela en optimisant les résultat un alignement de 8 correspond à 2 alignement de 4 et non Un seul alignement en plein milieux de l'intervalle.
en théorie il suffit d'isolé les alignement étant précédé en diagonal par un case ayant une autre valeur ou étant précédé de n case étant multiple de 4, j'ai bien du mal à réaliser cela en sql


Configuration: Linux / Chrome 80.0.3987.87

3 réponses

Messages postés
3604
Date d'inscription
jeudi 16 juin 2005
Statut
Membre
Dernière intervention
3 juillet 2020
957
Bonjour,

Honnêtement je ne pense pas que ton problème se traite en SQL de façon simple en une seule requête. Est-ce réellement nécessaire ? Ces résultats ne peuvent-ils pas être traités a posteriori dans un autre langage pour exclure de façon procédurale les résultats non souhaités ?

Si non, je te suggère de considérer ta requête actuelle comme une sous-requête d'une requête plus complexe qui exclura les résultats non voulus (il faudra rajouter Value aux champs retournés par ta requête courante, et peut-être un champ calculé 'direction' qui facilitera les comparaisons, et la joindre à elle-même...). Mais ça va vraiment la rendre immaintenable je pense, car trop complexe.

Xavier
Messages postés
3604
Date d'inscription
jeudi 16 juin 2005
Statut
Membre
Dernière intervention
3 juillet 2020
957
Une petite astuce pour t'aider à identifier si un alignement en diagonal est sur la même diagonale qu'un autre :
- pour les diagonales descendantes, ligne-colonne est une constante unique ;
- pour les diagonales montantes, ligne+colonne est une constante unique.
Déjà ça facilitera les requêtes.
Messages postés
11509
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
10 juillet 2020
659
bonjour, quel est le soucis qui t’empêche "d'isolé les alignement étant précédé en diagonal par un case ayant une autre valeur ou étant précédé de n case étant multiple de 4"?
qu'as-tu essayé, et quel résultat as-tu obtenu?

je pense que la première chose à faire est d'obtenir les informations nécessaires.
donc de modifier la requête, ou (souvent plus clair) de faire des requêtes supplémentaires, avec l'information "précédé par une case différente" et l'information "précédé de n*4 cases".

réfléchi au problème, utilise des exemples, afin de bien maîtriser la méthode à utiliser, ne commence pas trop vite à faire des requêtes.
Messages postés
11509
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
10 juillet 2020
659
il est peut-être plus simple de faire une requête pour obtenir tous ceux que tu veux éliminer, as-tu envisagé de faire cela?
Messages postés
11509
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
10 juillet 2020
659
connais-tu la dimension du plateau?
tu pourrais commencer par obtenir tous les segments précédés par une case différente.
puis obtenir tous ceux qui sont précédés par un segment obtenu dans la requête précédente.
puis obtenir tous ceux qui sont précédés par un segment obtenu dans la requête précédente.
...
et puis rassembler le tout.
Messages postés
1
Date d'inscription
mardi 14 avril 2020
Statut
Membre
Dernière intervention
14 avril 2020

bonjours
je précisé mon projet , c'est une sorte de jeux multijoueur de morpion géant modulable
ou bute est d'aligné un maximum de fois "TAILLE POINT" case dans un plateau de taille variable "TAILLE X", "TAILLE Y" en sachant que sur un même alignement on ne comptabilise que les alignement n'ayant en commun pas plus de "$cumule" élément.

Pour illustré l'exemple typique :aligné sur un plateau de 20*20 un maximum d'alignement de 4 sachant que pour deux alignement sur la même ligne il ne peuvent avoir que 1 élément commun.

En effet Reivax962 je ne me contente pas du SQL , le PHP vas de mise pour récupéré les donné et rendre dynamique mes requête en fonction de tout les paramétré évoqué .
j'aurais du le précisé , j'espérais ciblé le problème.

je pense avoir résolut mon problème

j'ai tout d'abord isolé parmi tout les alignement (allant uniquement de gauche à droite ou haut en bas ) ceux qui sont en tête d'une suite d'alignement et ceux en bordure de tableau

j'ai ensuite été cherché récursivement les alignement qui se suivent directement et cela tant qu'il y en à , les comptabilisant au fur et a mesure
cela me permet d'exclure les alignement se juxtaposant et optimisant au maximum le calcule du score.

il me suffit alors de comptabilisé ces alignement au fur et a mesure pour obtenir mon score .

voila se que j'ai pour le moment:
function Score($VALUE,$TAILLEPOINT,$IDPARTY,$cumule)//on compte les alignement d'une longeur (taillepoint) pour un joueur doné ayant une (value) représentative durant une party doné (IDPARTY), on accepte les alignement n valeur cumulé (cumule)
{
 
 $sqlFROM="SELECT DISTINCT T1.LIGNE AS L1,T1.COLUMNE AS C1, T$TAILLEPOINT.LIGNE AS  L$TAILLEPOINT,T$TAILLEPOINT.COLUMNE AS C$TAILLEPOINT FROM";//liste debut et fin  des alignement 
 for($i=1;$i<=$TAILLEPOINT+1;$i++)//on créer autant de tableau que la longueur de l'alignemenT +1 pour recupérer la valeur precedant dans l'alignement.
 {
  $sqlFROM .=" PLATEAU_$IDPARTY AS T$i";
  if($i!=$TAILLEPOINT+1)$sqlFROM.=",";
  else $sqlFROM.=" WHERE";
 }

 $sqlFROM.=" T1.VALUE=$VALUE ";//on compte les alignement pour une valeur doné d'un seul joueur
 $nbaligne=0;//initialise le comteur d'alignement
 $[/sql/sqlintro.php3 sql]=$sqlFROM;

 for($PANTE=-1;$PANTE<=1;$PANTE++)
 {
  echo "un:$nbaligne";
  for($i=1;$i<$TAILLEPOINT;$i++)//on isole les alignement 
  {  
   if($i==1)$sql.="AND ( ";
   else$[/sql/sqlintro.php3 sql].=" AND ";
   $j=$i+1;
   $sql.="T$j.VALUE=T$i.VALUE AND T$j.COLUMNE=T1.COLUMNE+$i AND T$j.LIGNE=T1.LIGNE+$i";
  }
  $sql.=" ) ";//liste des alignement cumulé compléte
  $sql0= "$sql AND ( T1.LIGNE=1 OR T1.COLUMNE=1 OR T5.LIGNE=T1.LIGNE-1 AND T5.COLUMNE=T1.COLUMNE-1 AND T5.VALUE!=$VALUE)";//liste des alignement soit contre la bordure du tableau soit ettant en tete d'alignement.
  $nbaligne+=SQLgetchamp("SELECT COUNT(T0.L1) FROM ($sql0) AS T0"); 
  echo "deux:$nbaligne";
  $sql.=" AND NOT ( T1.LIGNE=1 OR T1.COLUMNE=1 OR T5.LIGNE=T1.LIGNE-1 AND T5.COLUMNE=T1.COLUMNE-1 AND T5.VALUE!=$VALUE)";
  $sqllist[1]=$sql0;
  $i=2;
  
  do{
  $sqllist[$i]="SELECT TT.L1,TT.C1,TT.L$TAILLEPOINT,TT.C$TAILLEPOINT FROM ($sql) AS TT,(".$sqllist[$i-1].") AS TT2 WHERE ( TT.L1=TT2.L$TAILLEPOINT+1-$cumule AND TT.C1=TT2.C$TAILLEPOINT+1-$cumule )";
  $aux=SQLgetchamp("SELECT COUNT(T0.L1) FROM (".$sqllist[$i].") AS T0");
  $nbaligne+=$aux;
  $i++;
  }while($aux!=0);
  echo ",trois:$nbaligne";
 }
}

pour le moment la fonction ne récupère que le score en diagonal à l’intérieur $nbaligne
la boucle for utilisant $pante est censé dans le future dans son parcoure altéré les requête pour passé de horizontal a diagonal puis à vertical et cumulant les résultat . le programme incomplet pour le moment et donne cumulé 3 fois le score en diagonal .
merci de votre aide
bien a vous