Pathfinding fait maison sauce C#

4 réflexions au sujet de “Pathfinding fait maison sauce C#”

  1. Coucou Syllius,

    Je ne connaît pas trop bien le concept de recursivité , je ne penses pas en utiliser. J’emploie un système d’aller retour entre deux fonctions :

    par exemple une première fonction va sonder les cases adjacentes
    ensuite une deuxième fonction va immédiatement mémoriser et traiter l’information (par exemple comparer la nouvelle valeur avec l’ancienne mémorisée et décider si oui ou non on la conserve ou on l’oublie)

    En gros à chaque cellule sondées, je traite l’information immédiatement jusqu’à la fin.
    voici le bout de code de mon PathFindeEngine

    ` public void PathfinderEngine(int i_value, int j_value)
    // i_value et j_value correspondent aux coordonnées de la cellule mère à traiter
    // nous devons traiter toute ses cellules filles adjacentes
    {
    if (begin_pathfinding ) // autorise le calcul du Pathfinding
    {
    int memorized_value = open_map[i_value, j_value, 0]; // c’est la valeur H+G de la cellule mère
    int best_minimum_value = memorized_value; // on initialise un première mémoire tampon
    int current_value_scanning = memorized_value; // on initialise une deuxième mémoire tampon

    // prélever les coordonnées
    int i_memorized = i_value; // j’enregistre l’abcsisse de la cellule mère
    int j_memorized = j_value; // j’enregistre l’ordonnées de la cellule mère

    // je prépare mes valeurs tampon pour le traitement des cases adjacentes
    int _i_moins = i_value – 1; // à gauche
    int _i_plus = i_value + 1; // à droite
    int _j_moins = j_value – 1; // en haut
    int _j_plus = j_value + 1; // en bas

    // je place mes mouchards (lisible dans SORTIE) : voir menu Affichage
    Console.WriteLine(« current i,j dans le moteur de pathfinding :  » + i_value.ToString() +  » /  » + j_value.ToString());
    Console.WriteLine(« au début old_values i,j » + old_path_node_i_value.ToString() +  » /  » + old_path_node_j_value.ToString());

    // je vérifie que la cible n’est pas égal au point de départ
    // point de départ : (old_path_node_i_value , old_path_node_j_value)
    if (i_value == old_path_node_i_value && j_value == old_path_node_j_value)
    {
    // si OUI : je créé une alerte et je lance mon compteur debug_path
    // son rôle : éjecter du programme et tout remettre par défaut pour éviter les boucles infinies
    Console.WriteLine(« alerte debug!!! « );

    debug_path += 1;
    }

    // je vérifie que la cible n’est pas égal au point de départ
    // point de départ : (old_path_node_i_value , old_path_node_j_value)
    if (old_path_node_i_value != i_value || old_path_node_j_value != j_value)
    {
    // si NON : la cible n’est pas le point de départ

    // en haut
    if (_j_moins >= 0 // vérifier que je reste dans l’index de ma tilemap
    && map[i_value, _j_moins] > 0
    && open_map[i_value, _j_moins, 0] >= 0)
    {
    // je prélève la valeur enregistrée dans mon tableau
    current_value_scanning = open_map[i_value, _j_moins, 0];

    // je teste la valeur et si elle est plus petite que l’ancienne,
    // j’efface l’ancienne par la nouvelle
    if (current_value_scanning < best_minimum_value)
    {
    best_minimum_value = current_value_scanning;

    // je prélève les coordonnées et les range dans une mémoire tampon

    i_memorized = i_value;
    j_memorized = _j_moins;
    }
    }

    // en bas + ** vérifier si c'est un mur
    if (_j_plus 0
    && open_map[i_value, _j_plus, 0] >= 0)
    {
    current_value_scanning = open_map[i_value, _j_plus, 0];

    // je teste la valeur et si elle est plus petite que l’ancienne,
    // j’efface l’ancienne par la nouvelle
    if (current_value_scanning = 0// vérifier que je reste dans l’index de ma tilemap
    && _j_moins >= 0
    && map[_i_moins, _j_moins] > 0
    && open_map[_i_moins, _j_moins, 0] >= 0)
    {
    current_value_scanning = open_map[_i_moins, _j_moins, 0];

    // je teste la valeur et si elle est plus petite que l’ancienne,
    // j’efface l’ancienne par la nouvelle
    if (current_value_scanning = 0// vérifier que je reste dans l’index de ma tilemap
    && map[_i_moins, j_value] > 0
    && open_map[_i_moins, j_value, 0] >= 0)
    {
    current_value_scanning = open_map[_i_moins, j_value, 0];

    // je teste la valeur et si elle est plus petite que l’ancienne,
    // j’efface l’ancienne par la nouvelle
    if (current_value_scanning = 0 /// à gauche // vérifier que je reste dans l’index de ma tilemap
    && _j_plus 0 /// ne contient pas de mur
    && open_map[_i_moins, _j_plus, 0] >= 0) /// contient une valeur traitée dans open_map()
    {
    current_value_scanning = open_map[_i_moins, _j_plus, 0];

    // je teste la valeur et si elle est plus petite que l’ancienne,
    // j’efface l’ancienne par la nouvelle
    if (current_value_scanning < best_minimum_value)
    {
    best_minimum_value = current_value_scanning;

    // je prélève les coordonnées et les range dans une mémoire tampon

    i_memorized = _i_moins;
    j_memorized = _j_plus;
    }
    }

    //en haut à droite + ** vérifier si c'est un mur
    if (_i_plus = 0 // vérifier que je reste dans l’index de ma tilemap
    && map[_i_plus, _j_moins] > 0
    && open_map[_i_plus, _j_moins, 0] >= 0)
    {
    current_value_scanning = open_map[_i_plus, _j_moins, 0];

    // je teste la valeur et si elle est plus petite que l’ancienne,
    // j’efface l’ancienne par la nouvelle
    if (current_value_scanning < best_minimum_value)
    {
    best_minimum_value = current_value_scanning;

    // je prélève les coordonnées et les range dans une mémoire tampon

    i_memorized = _i_plus;
    j_memorized = _j_moins;
    }

    }

    //à droite + ** vérifier si c'est un mur
    if (_i_plus 0 // vérifier que je reste dans l’index de ma tilemap
    && open_map[_i_plus, j_value, 0] >= 0)
    {
    current_value_scanning = open_map[_i_plus, j_value, 0];

    // je teste la valeur et si elle est plus petite que l’ancienne,
    // j’efface l’ancienne par la nouvelle
    if (current_value_scanning < best_minimum_value)
    {
    best_minimum_value = current_value_scanning;

    // je prélève les coordonnées et les range dans une mémoire tampon

    i_memorized = _i_plus;
    j_memorized = j_value;
    }
    }

    //en bas à droite + ** vérifier si c'est un mur
    if (_i_plus < limit_i_value // vérifier que je reste dans l'index de ma tilemap
    && _j_plus 0
    && open_map[_i_plus, _j_plus, 0] >= 0)
    {
    current_value_scanning = open_map[_i_plus, _j_plus, 0];

    // je teste la valeur et si elle est plus petite que l’ancienne,
    // j’efface l’ancienne par la nouvelle
    if (current_value_scanning 80)
    {
    begin_pathfinding = false; // je cloture le programme
    stop_pathfinding = true;
    move_the_sprite = false;
    force_eject = true;
    Console.WriteLine(« le moteur de pathfinding a rencontré une erreur, nous l’avons forcé à s’arrêter »);

    item.IsHidden = true; // je cache l’icone de recherche

    // mon programme est bouclé

    }

    // je met à jour les valeurs à controler
    i_path_value = i_memorized;
    j_path_value = j_memorized;

    // je sécurise la méthode pour pouvoir y mettre fin en cas de PB
    old_path_node_i_value = i_value; // l’abscisse de la cellule mère est enregistrée et sera comparée ultrieurement
    old_path_node_j_value = j_value; // l’ordonées de la cellule mère est enregistrée et sera comparés ultrieurement
    // old_path_node_i_value et old_path_node_j_value sont des variables déclarées au début de la classe
    }
    }’

  2. tu peux le poster sur https://pastebin.com/ et linker le lien obtenu.

    Une fonction récursive est une fonction qui s’appelle d’elle-même, c’est ce que j’ai utilisé dans l’atelier sur IA où j’ai programmé un monstre qui pourchasse le héro dans un labyrinthe (.

    Ca permet de condenser considérablement le code également. Je te link le lien de la fonction récursive utilisée : .

    Il est important d’avoir une condition d’arrêt sinon on pourrait se retrouver avec des appels de fonctions à l’infini. Dans mon cas la profondeur de recherche était limité à 5 cases.

Laisser un commentaire

Dialoguez avec les autres membres de la gamecodeur school.

Accédez maintenant à notre serveur Discord privé : Entraide, Game Jams, Partage de projets, etc.

Vous devez être membre de la Gamecodeur School Premium pour être autorisé à accéder au serveur.