20-08-2011, 08:14 PM
(Modification du message : 30-09-2011, 02:21 PM par Sephi-Chan.)
Bonjour, je suis toujours dans mon algorithme A* sur cases hexagonale:cogne:.
J'ai commencer par développer le script pour des cases carrée, puis j'ai reprogrammer la fonction "casesAdjacentes" qui renvoi les cases adjacentes à celle analysé.
Le script fonctionne (ou presque) puisqu'il arrives à trouver la case final, mais au moment de retracé le chemin, celui-ci est sacadé, voici un petit aperçu du dis problème:
Case verte: départ.
Case rouge: case cherché
Case noir: franchissable
Case bleu foncé: non-franchissable
Case bleu clair: le chemin final
Je penses que le problème est dût à l'update du parent si le score est plus faible, mais je n'arrives pas à trouver le problème...
Voici le code de ma fonction:
J'ai commencer par développer le script pour des cases carrée, puis j'ai reprogrammer la fonction "casesAdjacentes" qui renvoi les cases adjacentes à celle analysé.
Le script fonctionne (ou presque) puisqu'il arrives à trouver la case final, mais au moment de retracé le chemin, celui-ci est sacadé, voici un petit aperçu du dis problème:
Case verte: départ.
Case rouge: case cherché
Case noir: franchissable
Case bleu foncé: non-franchissable
Case bleu clair: le chemin final
Je penses que le problème est dût à l'update du parent si le score est plus faible, mais je n'arrives pas à trouver le problème...
Voici le code de ma fonction:
function chemin(&$tableau, $xDepart, $yDepart, $xFinal, $yFinal, $mode = 1) {
// Note : pour simplifier les traitements et pouvoir utiliser des cases comme index de tableau,
// on utilisera une représentation sous forme de chaine dans le déroulement de l'algo
$open = array(); // liste ouverte (cases à traiter)
$closed = array(); // liste fermée (cases traitées)
$f = array(); // coût f
$parent = array(); // case parente d'une autre ($parent[$enfant] = $parent)
// Valeurs initiales
$caseDepart = "$xDepart,$yDepart"; // case de départ
$caseFinale = "$xFinal,$yFinal"; // case d'arrivée
$open[] = $caseDepart; // la case de départ est déjà traitée d'office
$coutCaseDepart = coutCase($xDepart, $yDepart, $xFinal, $yFinal, $mode);
$f[$caseDepart] = $coutCaseDepart["f"];
$caseCourrante = $caseDepart; // case courrante
$coutCourrant = $coutCaseDepart;
$iCourrant = 0; // Identifiant de la case courrante, permettras de localiser $caseCourrante dans $open et $closed
$while = 0;
while ($caseCourrante != $caseFinale) {
if (count($open) == 0) // si la liste ouverte est vide, alors échec dans la recherche du chemin
return false;
list($xCourrante, $yCourrante) = explode(",", $caseCourrante);
$casesAdjacentes = casesAdjacentes($tableau, $xCourrante, $yCourrante, $mode); // On récupère la liste des cases adjacentes
$fMin = NULL;
$iFMin = NULL;
$xFMin = NULL;
$yFMin = NULL;
foreach ($casesAdjacentes as $iCaseAnalyse => $caseAnalyse) { // On les analyse une par une
list($xAnalyse,$yAnalyse) = $caseAnalyse;
$coordAnalyse = "$xAnalyse,$yAnalyse";
if(in_array($coordAnalyse, $closed)) // Si la case a déjà été traité
continue; // On saute une itération
$open[] = $coordAnalyse;
if($fMin === NULL) { // Si c'est la première itération
$iOpen = array_search($caseCourrante, $open); // On recherche dans la liste ouverte la case analysé
$closed[] = $open[$iOpen]; // On met la case courrante dans la liste fermé
array_splice($open, $iOpen, 1); // Et on l'enlève de la liste ouverte
$firstIteration = false;
}
$coutAnalyse = coutCase($xAnalyse, $yAnalyse, $xFinal, $yFinal, $mode, $coutCourrant, $xCourrante, $yCourrante);
if($fMin === NULL OR $fMin > $coutAnalyse["f"]) { // Si c'est la première itération ou que la case analyse a un plus faible coût que les précédentes
$fMin = $coutAnalyse["f"];
$iFMin = $iCaseAnalyse;
$xFMin = $xAnalyse;
$yFMin = $yAnalyse;
$coutCourrant = $coutAnalyse;
}
if(!array_key_exists($coordAnalyse, $parent) OR $f[$coordAnalyse] > $coutAnalyse["f"]) ///////////////// ICI SERAIT LE PROBLEME...
$parent[$coordAnalyse] = $caseCourrante;
$f[$coordAnalyse] = $coutAnalyse["f"];
if($caseAnalyse == $caseFinale)
break;
}
$caseCourrante = "$xFMin,$yFMin";
}
$caseParcouru = $caseFinale;
$cheminFinal = array();
while($caseParcouru != $caseDepart) {
list($xParcouru,$yParcouru) = explode(",",$caseParcouru);
if($caseParcouru == $caseFinale)
$tableau[$xParcouru][$yParcouru] = "arrivee";
else
$tableau[$xParcouru][$yParcouru] = "parcouru";
$cheminFinal[] = $caseParcouru;
$caseParcouru = $parent[$caseParcouru];
if($caseParcouru == $caseDepart) {
list($xParcouru,$yParcouru) = explode(",",$caseParcouru);
$tableau[$xParcouru][$yParcouru] = "depart";
}
}
return $parent;
}
Si vous voyez quelque chose de louche que je rates, même si je sais qu'un code brut comme ça est pas facile à corriger lorsqu'il n'est pas de soit-même.