JeuWeb - Crée ton jeu par navigateur

Version complète : Créer une frise chronologique
Vous consultez actuellement la version basse qualité d’un document. Voir la version complète avec le bon formatage.
Bonjour !

j'ai une idée qui me trotte dans la tête mais j'ai pas du prendre les chose par le bon bout.

J'aimerais créer un système de frise chronologique a partir d'informations extraites dans BDD :

Imaginons que je commence en l'an 0, j'aimerais pouvoir naviguer en -100 et en +100.

Ensuite juste en dessous j’aimerais avoir le nom de la période qui correspond aux dates.

j'ai essayé dans le cadre d'un petit projet sans trop de prétention et donc avec des périodes réelles et je n'obtiens pas les résultats escomptés.

je vous remercie par avance pour votre aide XD
Quel est ton problème ?
Je suppose au vu de ta signature que tu cherches une solution PHP. Tu pourrais par exemple utiliser un array avec le début de chaque période :
Code :
$periodes = array(
    -5000000000 => "Ere pré-républicaine",
    -25000 => "Ancienne République",
    -19 => "Empire Galactique",
    4 => "Nouvelle République",
    28 => "Alliance Galactique",
    130 => "Nouvel Empire Sith",
    138 => "..."
);
$annee = 0;
foreach($periodes as $an => $nom)
{
    if($an > $annee)
    {
         break;
    }
    $periode = $nom;
}
echo $periode; // Affiche Empire Galactique
Attention au dépassement d'entier PHP: -5.000.000.000 dépassera la limite (env. -2^31 soit env -2.300.000.000 de mémoire). Le nombre entier sera alors transformé en flottant, avec un risque de perdre le coté "entier" (-5.000.000.000 peut devenir -5.000.000.001,584516924 par exemple)
Je trouve le "foreach" inélégant, mais je n'ai pas de meilleure idée...
Non, c'est plus : pow(2, 8*4) = 4 294 967 296, et puis c'est la borne la plus basse et la date de création de la galaxie n'est pas fixée à l'année prêt ^^

Je pense pas que sa chronologie sera aussi étalée que celle de Star Wars ^^ Sinon, après, il y a GMP, mais ça n'en vaut sûrement pas le coup pour une perte de précision de quelques années.

Il n'y a rien de plus adapté que foreach pour parcourir un array. Si on utiliser des fonctions de comparaison, tri d'array etc. ce serait également un foreach appelé implicitement puisqu'il faut mettre sur chaque année de début le nom de la période suivante.

Ensuite, il serait plus "élégant" d'utiliser une fonction, surtout que ça peut resservir ailleurs. Du coup, on fait un return plutôt qu'un break. Sinon, on peut décaler les éléments, ainsi lorsque $an > $annee, $nom correspond à $annee et donc on peut faire le return et on économise les assignations à chaque tour de boucle, la RAM est contente, mais du coup, il faut faire la gymnastique mentale pour décaler tout l'array puisque
PHP utilise des entiers non signés partout? j'ai un sérieux doute... La limite en entier signé est 2x moindre, donc 2.1G environ
Nope, ca dépend des cas: array_map sera par exemple bien plus efficace et élégant qu'un foreach, sous condition d'avoir besoin du tableau d'entrée et du tableau de sortie (autrement dit, une copie, et non une modification du tableau original).
Après, tu utilises un tableau, avec année_limite=>nom_ère: y'a peut-être mieux (mais j'ai rien en tête pour l'instant)

En fait, ce qui m'embête (OSEF dans le cas d'un si petit tableau, mais c'est toujours bien de savoir faire mieux), c'est que trouver le nom d'une période donnée est en O(n) (on doit parcourir tout le tableau), alors que l'accès à un élément d'un tableau est en O(1), donc, je me demande s'il n'y aurait pas un peu plus performant et élégant qu'un "bête" parcours du tableau des années de fin des ères (ou de début des ères).
Autre truc qui me chiffonne justement: si la frise chronologique est infinie des deux cotés (pas de temps 0, pas de temps final butoir), alors on sauve quoi? L'année de début? l'année de fin de l'ère? Dans les deux cas, il faudra avoir un cas particulier pour la première ou la dernière ère (et les cas particuliers, c'est pas beau :p)

Dernier élément: foreach appelé "implicitement" en utilisant les fonctions spécifiques aux tableaux sera plus rapide qu'un foreach appelé explicitement pour parcourir le tableau. En d'autres mots, si tu refais le même algorithme que, par exemple, sort() mais encodé en PHP (via foreach), alors tu auras des performances moindres (ou au mieux, égales, et encore, ca m'épaterait franchement!)
L'élégance, je laisse ça aux designers, pour un code je préfère les perfs et l'évolutivité. Ça m'intéresse pas trop de faire du code pour montrer aux autres comme il est beau. XD Y a peu de chance de pouvoir faire mieux qu'une fonction qui parcourt juste l'array et fait 0 assignation. Mais comme je me suis trompé d'une puissance de deux, je veux bien croire qu'il y a une solution à laquelle je n'ai pas pensé mais je vais pas m'amuser à la chercher car la poignée de lignes proposée me semble largement assez optimisée pour ce qu'elle a à faire.

Petit test effectué :
Code :
for($i=-5000000000;$i>-5000001000;$i--)
{
    echo "$i <br />";
};

0, 1, 2, 3, 4, etc. s'affichent correctement. Le type est bien un double mais la précision est suffisante pour obtenir un résultat juste à 1 près. Donc le calcul de l'entier maximal avant la perte de précision est au delà même de 2^32.

Grâce à une petite expérience, j'ai une valeur approximative de cet entier limite :
Code :
for($i=-5000000000;$i>-250000000000000000;$i-=10000000000)
{
    $j=$i-1;
    if($i - $j != 1)
    {
                "Perte de précision à ".$i;
        break;
    }
}
Résultat : -9.007205E+15
Donc la frise chronologique peut remonter jusqu'à - 9 000 000 000 000 000 sans aucune inprécision.
Pfiou, balèze PHP ^^
merci pour vos idées j'avais oublié que j'avais posté ici a ce sujet je test et je vous dit de quoi il en retourne.
Cet article pourrait t'intéresser.