Temps de trajet entre deux villes (Formule & code)

  • Auteur de la discussion DeletedUser57123
  • Date de début
Statut
N'est pas ouverte pour d'autres réponses.

DeletedUser57123

Guest
Comment calculer le temps de trajet entre deux villes (Formule)
Voici un tuto expliquant la formule afin de calculer la distance entre deux villes et ainsi connaître le temps de trajet avec une unité. Ce code utilise les données du monde de Grepolis et ainsi rend cette tâche automatique.

Pré-requis :
- Quelques connaissance de code (en général, pas de langage particulier)

- Les fichiers du monde disponible ici : https://wiki.fr.grepolis.com/wiki/Données_mondes
- Du fichier Xoffset.txt présent dans ce Spoiler
$island_type, $offset_x, $offset_y, $position_on_island (ne pas recopier cette ligne dans le fichier)
1,451,130,0
1,351,168,1
1,261,230,2
1,193,268,3
1,201,317,4
1,220,396,5
1,290,393,6
1,364,401,7
1,453,459,8
1,519,498,9
1,601,463,10
1,682,462,11
1,752,441,12
1,827,410,13
1,886,347,14
1,857,289,15
1,812,202,16
1,728,226,17
1,780,283,18
1,751,319,19
2,321,183,0
2,326,103,1
2,407,98,2
2,510,68,3
2,619,75,4
2,687,100,5
2,750,130,6
2,794,165,7
2,774,229,8
2,740,297,9
2,734,366,10
2,681,387,11
2,550,410,12
2,480,408,13
2,314,393,14
2,216,387,15
2,195,323,16
2,122,300,17
2,115,216,18
2,190,178,19
3,485,79,0
3,400,63,1
3,340,88,2
3,283,108,3
3,238,144,4
3,152,208,5
3,141,310,6
3,214,353,7
3,298,391,8
3,359,408,9
3,403,432,10
3,481,454,11
3,568,435,12
3,607,377,13
3,737,385,14
3,709,342,15
3,858,247,16
3,847,185,17
3,776,145,18
3,693,96,19
4,527,114,0
4,584,131,1
4,690,150,2
4,738,185,3
4,780,207,4
4,682,244,5
4,623,273,6
4,525,282,7
4,488,240,8
4,406,202,9
4,324,203,10
4,238,230,11
4,262,277,12
4,273,318,13
4,204,351,14
4,111,336,15
4,100,262,16
4,140,200,17
4,244,163,18
4,332,130,19
5,214,204,0
5,235,127,1
5,325,79,2
5,404,54,3
5,518,70,4
5,536,122,5
5,638,125,6
5,731,125,7
5,746,176,8
5,838,200,9
5,848,252,10
5,789,326,11
5,739,363,12
5,650,393,13
5,559,418,14
5,434,465,15
5,320,417,16
5,275,373,17
5,625,308,18
5,620,240,19
6,467,373,0
6,551,424,1
6,676,457,2
6,770,463,3
6,826,434,4
6,826,354,5
6,770,320,6
6,708,299,7
6,640,208,8
6,589,181,9
6,504,143,10
6,416,145,11
6,343,163,12
6,271,175,13
6,174,231,14
6,95,293,15
6,149,327,16
6,188,365,17
6,167,417,18
6,267,442,19
7,153,237,0
7,128,214,1
7,112,160,2
7,119,114,3
7,173,93,4
7,226,115,5
7,323,148,6
7,380,171,7
7,508,187,8
7,447,213,9
7,475,265,10
7,507,310,11
7,502,359,12
7,438,389,13
7,433,456,14
7,370,446,15
7,291,427,16
7,220,450,17
7,174,419,18
7,124,394,19
8,578,245,0
8,638,270,1
8,700,290,2
8,735,335,3
8,693,363,4
8,648,390,5
8,584,412,6
8,469,440,7
8,402,440,8
8,284,417,9
8,224,389,10
8,176,332,11
8,134,306,12
8,134,261,13
8,100,213,14
8,127,166,15
8,176,143,16
8,234,124,17
8,303,123,18
8,338,159,19
9,178,321,0
9,106,282,1
9,131,220,2
9,182,163,3
9,358,72,4
9,416,46,5
9,513,59,6
9,587,116,7
9,820,189,8
9,857,230,9
9,833,319,10
9,713,390,11
9,652,425,12
9,613,362,13
9,527,397,14
9,524,449,15
9,423,447,16
9,362,442,17
9,348,395,18
9,327,366,19
10,553,137,0
10,606,103,1
10,700,110,2
10,748,153,3
10,814,221,4
10,799,319,5
10,747,357,6
10,676,391,7
10,492,421,8
10,411,440,9
10,314,415,10
10,249,378,11
10,194,355,12
10,128,288,13
10,155,179,14
10,233,118,15
10,332,106,16
10,369,145,17
10,348,192,18
10,259,200,19
11,119,119,0
11,190,76,1
11,273,79,2
11,395,145,3
11,425,233,4
11,312,172,5
11,259,126,6
12,185,67,0
12,274,89,1
12,321,192,2
12,263,207,3
12,192,226,4
12,119,205,5
12,153,146,6
13,383,0,0
13,374,146,1
13,550,289,2
13,466,299,3
13,420,277,4
13,336,300,5
13,231,264,6
13,184,235,7
13,206,138,8
13,206,46,9
13,292,31,10
14,210,69,0
14,301,81,1
14,303,138,2
14,259,159,3
14,248,240,4
14,146,238,5
14,75,203,6
15,119,87,0
15,244,95,1
15,265,129,2
15,377,132,3
15,431,163,4
15,490,206,5
15,397,260,6
15,325,273,7
16,123,111,0
16,209,106,1
16,301,118,2
16,348,171,3
16,446,203,4
16,552,218,5
16,606,244,6
16,593,306,7
16,503,321,8
16,343,297,9
16,227,270,10
16,175,212,11
16,119,184,12
37,485,120,0
37,400,130,1
37,432,190,2
37,585,292,3
37,550,350,4
37,370,220,5
37,288,193,6
37,192,240,7
37,141,300,8
37,175,353,9
37,243,411,10
37,375,445,11
37,530,490,12
37,640,500,13
37,690,470,14
37,775,450,15
37,858,367,16
37,847,245,17
37,776,200,18
37,693,159,19
38,350,75,0
38,250,50,1
38,170,84,2
38,108,142,3
38,81,189,4
38,89,238,5
38,105,288,6
38,217,313,7
38,301,365,8
38,375,378,9
38,445,380,10
38,525,376,11
38,588,375,12
38,663,344,13
38,757,305,14
38,679,218,15
38,798,195,16
38,740,105,17
38,636,65,18
38,530,45,19
39,517,53,0
39,430,80,1
39,266,115,2
39,187,185,3
39,111,248,4
39,107,310,5
39,189,363,6
39,253,405,7
39,344,419,8
39,424,387,9
39,502,387,10
39,650,411,11
39,711,380,12
39,816,343,13
39,874,256,14
39,691,240,15
39,636,211,16
39,701,194,17
39,652,102,18
39,585,62,19
40,389,94,0
40,344,151,1
40,339,210,2
40,163,235,3
40,94,284,4
40,133,339,5
40,191,364,6
40,264,395,7
40,325,428,8
40,430,406,9
40,648,433,10
40,727,394,11
40,792,350,12
40,863,303,13
40,866,263,14
40,741,244,15
40,681,222,16
40,656,142,17
40,544,127,18
40,484,84,19
41,444,95,0
41,357,110,1
41,248,150,2
41,166,199,3
41,148,233,4
41,143,276,5
41,158,327,6
41,194,375,7
41,264,413,8
41,315,433,9
41,448,462,10
41,584,453,11
41,738,380,12
41,798,348,13
41,867,323,14
41,881,260,15
41,772,244,16
41,657,309,17
41,623,128,18
41,525,95,19
42,457,85,0
42,391,95,1
42,321,130,2
42,244,154,3
42,172,210,4
42,117,302,5
42,105,338,6
42,167,367,7
42,210,471,8
42,313,486,9
42,319,375,10
42,489,407,11
42,491,453,12
42,608,446,13
42,661,413,14
42,769,367,15
42,849,265,16
42,700,156,17
42,637,123,18
42,552,96,19
43,305,1,0
43,250,20,1
43,191,75,2
43,85,104,3
43,91,163,4
43,121,217,5
43,101,259,6
43,180,156,7
43,656,197,8
43,303,305,9
43,361,331,10
43,442,316,11
43,551,317,12
43,646,298,13
43,706,267,14
43,768,233,15
43,741,91,16
43,689,39,17
43,528,46,18
43,448,46,19
44,536,11,0
44,508,53,1
44,419,42,2
44,310,36,3
44,342,101,4
44,172,129,5
44,181,204,6
44,238,277,7
44,352,301,8
44,408,354,9
44,467,257,10
44,551,249,11
44,600,364,12
44,695,331,13
44,780,299,14
44,789,218,15
44,865,175,16
44,811,116,17
44,678,85,18
44,696,29,19
45,352,132,0
45,301,186,1
45,169,199,2
45,191,243,3
45,270,314,4
45,188,327,5
45,115,355,6
45,101,393,7
45,163,428,8
45,276,428,9
45,421,388,10
45,458,443,11
45,603,441,12
45,675,390,13
45,736,341,14
45,750,246,15
45,650,135,16
45,583,139,17
45,499,150,18
45,431,113,19
46,496,78,0
46,339,109,1
46,287,158,2
46,215,173,3
46,161,201,4
46,95,252,5
46,41,307,6
46,96,329,7
46,151,424,8
46,264,414,9
46,305,468,10
46,529,462,11
46,585,431,12
46,674,413,13
46,733,379,14
46,733,303,15
46,732,236,16
46,708,202,17
46,650,166,18
46,568,90,19
47,155,135,0
47,248,106,1
47,341,148,2
47,438,150,3
47,516,280,4
47,488,309,5
47,260,214,6
47,82,188,7
47,480,227,8
48,145,205,0
48,200,232,1
48,266,215,2
48,325,185,3
48,396,133,4
48,445,95,5
48,395,78,6
48,365,1,7
49,98,100,0
49,234,106,1
49,331,95,2
49,484,115,3
49,705,78,4
49,665,128,5
49,463,253,6
49,290,270,7
49,220,246,8
50,153,111,0
50,213,95,1
50,285,118,2
50,348,133,3
50,415,170,4
50,472,358,5
50,412,400,6
50,332,425,7
50,255,445,8
50,170,435,9
51,155,91,0
51,229,85,1
51,331,106,2
51,398,228,3
51,375,253,4
51,220,251,5
51,240,180,6
51,170,148,7
52,123,111,0
52,209,68,1
52,690,193,2
52,610,232,3
52,510,253,4
52,430,248,5
52,310,222,6
52,322,188,7
52,252,170,8
52,150,170,9
53,33,6,0
53,98,3,1
53,232,39,2
53,572,169,3
53,400,182,4
53,310,212,5
53,210,216,6
53,140,180,7
53,60,160,8
53,78,110,9
53,59,56,10
54,387,69,0
54,322,66,1
54,275,104,2
54,123,152,3
54,114,223,4
54,121,260,5
54,199,304,6
54,296,306,7
54,370,272,8
54,215,233,9
55,177,60,0
55,115,109,1
55,50,109,2
55,200,197,3
55,221,230,4
55,346,254,5
55,399,273,6
55,461,252,7
55,453,124,8
56,476,75,0
56,422,103,1
56,329,149,2
56,240,173,3
56,169,195,4
56,124,233,5
56,178,279,6
56,169,330,7
56,183,370,8
56,575,294,9
57,206,58,0
57,234,93,1
57,140,165,2
57,112,212,3
57,209,248,4
57,218,309,5
57,293,322,6
57,347,285,7
58,147,279,0
58,170,334,1
58,231,365,2
58,402,364,3
58,431,322,4
58,557,320,5
59,187,62,0
59,274,78,1
59,353,123,2
59,312,176,3
59,426,203,4
59,432,264,5
59,314,304,6
59,218,383,7
60,91,312,0
60,295,247,1
60,407,355,2
60,429,289,3
60,523,285,4
60,560,228,5
60,586,154,6
60,561,98,7
60,510,67,8


Préparation
Pour commencer téléchargez les fichiers

- http://frX.grepolis.com/data/towns.txt
- http://frX.grepolis.com/data/islands.txt
en remplaçant le X par le numéro de votre monde (Alpha : 1, Bêta : 2... Amisos : 101, disponible ici )
Créez un fichier "Xoffset.txt" contenant les données du spoiler dans les pré-requis. Ce fichier n'est pas disponible en ligne, mais contient des informations essentiels.
Vous avez donc trois fichiers en local : towns.txt, islands.txt et Xoffset.txt, ces trois fichiers vont nous permettre de récupérer les informations du monde, et ainsi en déduire les distances entre les villes.


1- La carte
Il existe deux échelles, deux mesures dans la carte de Grepolis.

La première c'est celle qu'on connaît, chaque mer fait 100 unité, unité que l'on nommera Grepolis Map ou gm, une mer fait donc 100 x 100 gm, un monde fait 1000 * 1000 gm.
La deuxième est celle en background, elle est en pixel, chaque mer fait 12800 pixel, comprenez que pour placer les villes, îles et tout autre objet sur la map l'unité gm ne signifie rien, cela se compte en pixel.

Ainsi nous aurons besoin de passer de l'unité gm en pixel lors des calculs, mais rien de bien méchant.

2- Les constantes
La formule contient quelques constantes à expliquer avant de l'introduire.

Il faut savoir qu'un temps initiale est pris en compte durant chaque attaque, cette durée est de 900s, 15 minutes, dans un monde avec une vitesse monde x1, pour un monde avec une vitesse monde x2 vous aurez 900/2 = 450s soit 7 minutes initiale, dans un monde x3 900/3 = 300s etc.

De plus, une unité à une vitesse de déplacement, celle-ci correspond au nombre de pixel qu'elle parcourt durant 50 secondes. Vous devinerez donc la nécessitez de faire les calculs en pixel et non en gm.

3- Le principe
Abordons le principe de la formule.

Dans un premier temps il faut calculer la position exacte des deux villes en pixel, puis avec l'application du théorème de Pythagore nous pourrons savoir la distance en pixel qui les séparent, à partir de là nous pourrons calculer, avec la vitesse de l'unité et la vitesse des unités du monde, le temps nécessaire pour parcourir la distance.

4- La formule
Voici les étapes de la formule :


1) Position de la ville
Prenons la ville H, votre ville (H comme Home), vous pourrez la rechercher dans le fichier "towns.txt", grâce au site où vous avez téléchargé les fichiers vous pourrez savoir ce que représente les variables et leur position dans le fichier.
Récupérez les variables suivantes :
$island_x : la position x de l'île de la ville en unité gm
$island_y : la position y de l'île de la ville en unité gm
$number_on_island : la position de la ville sur l'île (en bas à gauche, près de la plage, au nord, etc)
Faites de même pour la ville T, la ville cible (T comme Target)

2) Type de l'île
Pour chacune des îles des villes vous devez récupérer leur type, vous remarquerez qu'il existe différent forme d'île, leur forme influe sur la position des villes. Pour ce faire, grâce à $island_x et $island_y récupérés auparavant vous allez rechercher l'île en question dans le fichier "islands.txt"
Contentez vous de récupérer la variable $island_type : le type de l'île.


3) Récupération des offset

Offset en anglais signifie "décalage", ces valeurs sont exprimés en pixel et signifie le décalage en pixel à partir de l'origine de l'île, ainsi c'est les offset qui permettent de positionner les villes sur l'île. L'origine de l'île correspond a $island_x et $island_y en pixel, exprimés de base en gm.
Pour récupérer les offset x et y de la ville vous devez récupérer les variables :
$offset_x : décalage en x
$offset_y : décalage en y
dans le fichier "Xoffset.txt", retrouvez ces valeurs grâce aux variables $island_type et $position_on_island récupérés plutôt. Une fois ces valeurs récupérées nous pouvons passer aux calculs.

4) Position exacte des villes
Calculons la position exacte des villes en pixel à partir de $island_x, $island_y, $offset_x et $offset_y.
$island_x et $island_y sont en unité gm, donc nous devons les passer en unité pixel, pour ce faire nous devons multiplier les valeurs par 128, puis ajouter les offset. Si $island_x est impair nous devons ajouter 64 au calcul de la position y. Application :

$town_x = ($island_x * 128) + $offset_x;
$town_y = ($island_y * 128) + $offset_y;
Si $island_x est impair alors $town_y = $town_y + 64;

Les valeurs $town_x et $town_y correspondent aux valeurs de la position exacte de la ville en pixel.
Faites de même pour la ville cible.


5) Calcul de la distance

Une fois les positons des deux villes calculées nous pouvons, grâce au théorème de Pythagore, calculer la distance qui les séparent. Voici un pseudo-code pour comprendre :
$calcX = $town_x_target - $town_x_home;
$calcY = $town_y_target - $town_y_home;

$distance = pow($calcX,2) + pow($calcY,2); // pow(&,@) = met & à la puissance @
$distance = sqrt($distance); // Racine carré


Ainsi la valeur $distance et le nombre de pixel qui sépare nos deux viles.

6) Final : le temps de trajet
Enfin pour finir voici comment calculer le temps de trajet entre les deux villes.
Tout d'abord définissons $speed la variable de la vitesse de l'unité en question et $units_speed la vitesse des unité dans le monde. Soit $speed = $speed * $units_speed;
Définissons aussi une variable $bonus = 1.0; correspondant aux bonus pouvant modifier le temps de trajet comme le phare ($bonus += 0.15; les 15% du phare, ou la cartographie à 10% soit $bonus += 0.10)
Ainsi :
$returnSeconds = floor(($distance * 50) / ($speed * $bonus)); // floor(@) : arrondit @
$returnSeconds += (900 / $worldSpeed); // Ajoute le temps de base (divisé, réduit, par la vitesse du monde)


$returnSeconds correspond à la vitesse en seconde du temps de trajet ! À vous de le transformez en heure:minute:seconde avec le langage de votre choix, ou via un site internet.

Le code (PHP)

Voici le code complet en PHP permettant de calculer le temps de trajet.
Ci-dessous un premier code avec des fonctions primaires au seconde code, veuillez à changer l'emplacement des fichiers aux début des fonctions sur les lignes "$datafile = fopen(filename)" afin de correspondre avec l'emplacement de vos fichiers.

Appelez la fonction "timeAttack" de cette manière, cette fonction vous retournera le temps de trajet en seconde :
PHP:
timeAttack(false,false,13,1,1,"Nom de la ville T","Nom de la ville H");
PHP:
function getDataIslandXYPositionByTownName($town_name){[/SIZE][/SIZE]
[SIZE=5][SIZE=4]
    $town_name = urlencode($town_name);
    $datafile = fopen($_SERVER['DOCUMENT_ROOT'].'/datafile/101datatowns.txt', 'r');//Ouvre le fichier en readonly
    while($line = fgets($datafile)) {//Pour chaque ligne
        $line = str_replace(',,', ',0,', $line);
        $pieces = explode(",",$line);
        $name = $pieces[2];
        $x = $pieces[3];
        $y = $pieces[4];
        $position = $pieces[5];
        if($town_name == $name){
            return $x . '/' . $y . '/' . $position;
        }
    }
    return -1;
}

function getDataXByData($data){
    $pieces = explode("/",$data);
    return $pieces[0];
}
function getDataYByData($data){
    $pieces = explode("/",$data);
    return $pieces[1];
}
function getDataIslandPositionByData($data){
    $pieces = explode("/",$data);
    return $pieces[2];
}

function getDataIslandTypeByXY($island_x,$island_y){
    $datafile = fopen($_SERVER['DOCUMENT_ROOT'].'/datafile/101dataislands.txt', 'r');//Ouvre le fichier en readonly
    while($line = fgets($datafile)) {//Pour chaque ligne
        $line = str_replace(',,', ',0,', $line);
        $pieces = explode(",",$line);
        $x = $pieces[1];
        $y = $pieces[2];
        $type = $pieces[3];
        if($island_x == $x AND $island_y == $y){
            return $type;
        }
    }
    return -1;
}

function getDataOffsetByTypePosition($island_type,$position_on_island){

    $datafile = fopen($_SERVER['DOCUMENT_ROOT'].'/datafile/Xoffset.txt', 'r');//Ouvre le fichier en readonly
    while($line = fgets($datafile)) {//Pour chaque ligne
        $line = str_replace(',,', ',0,', $line);
        $pieces = explode(",",$line);
        $type = $pieces[0];
        $offsetX = $pieces[1];
        $offsetY = $pieces[2];
        $position = $pieces[3];
        //Enlève le chariot retour à la ligne
        $position = trim(preg_replace('/\s\s+/', ' ', $position));
        if($island_type == $type AND $position_on_island == $position){
            return $offsetX . '/' . $offsetY ;
        }
    }
    return -1;
}
PHP:
function timeAttack($lightHouse,$cartography,$speed,$worldSpeed,$unitSpeed,$townTarget,$townHome){
        $speed = $speed * $unitSpeed;

        $bonus = 1.0;

        if($lightHouse){
            $bonus += 0.15;
        }
        if($cartography){
            $bonus += 0.10;
        }

        $islandDataTarget = getDataIslandXYPositionByTownName($townTarget);
        $islandXTarget = getDataXByData($islandDataTarget);
        $islandYTarget = getDataYByData($islandDataTarget);
        $islandPositionTarget = getDataIslandPositionByData($islandDataTarget);
        $islandTypeTarget = getDataIslandTypeByXY($islandXTarget,$islandYTarget);
        $islandOffsetDataTarget = getDataOffsetByTypePosition($islandTypeTarget,$islandPositionTarget);
        $islandOffsetXTarget = getDataXByData($islandOffsetDataTarget);
        $islandOffsetYTarget = getDataYByData($islandOffsetDataTarget);
        $xPositionTownTarget = ($islandXTarget * 128) + $islandOffsetXTarget;
        $yPositionTownTarget = $islandYTarget * 128 + $islandOffsetYTarget;
        if($islandXTarget % 2 != 0){
            $yPositionTownTarget += 64;
        }

        $islandDataHome = getDataIslandXYPositionByTownName($townHome);
        $islandXHome = getDataXByData($islandDataHome);
        $islandYHome = getDataYByData($islandDataHome);
        $islandPositionHome = getDataIslandPositionByData($islandDataHome);
        $islandTypeHome = getDataIslandTypeByXY($islandXHome,$islandYHome);
        $islandOffsetDataHome = getDataOffsetByTypePosition($islandTypeHome,$islandPositionHome);
        $islandOffsetXHome = getDataXByData($islandOffsetDataHome);
        $islandOffsetYHome = getDataYByData($islandOffsetDataHome);

        $xPositionTownHome = ($islandXHome * 128) + $islandOffsetXHome;
        $yPositionTownHome = $islandYHome * 128 + $islandOffsetYHome;
        if($islandXHome % 2 != 0){
            $yPositionTownHome += 64;
        }

        $calcX = $xPositionTownTarget - $xPositionTownHome;
        $calcY = $yPositionTownTarget - $yPositionTownHome;

        $distance = pow($calcX,2) + pow($calcY,2);
        $distance = sqrt($distance);
        $distance = $distance * 10;
        $distance = round($distance);
        $distance = $distance / 10;
        $distance = floor($distance);

        $returnSeconds = floor(($distance * 50) / ($speed * $bonus));
        $returnSeconds += (900 / $worldSpeed);

        return $returnSeconds;

    }

En espérant avoir aidé certains.
JackPots
 

Tiguerrier

Héros de l'Antiquité
Tuto magnifique !
Merci beaucoup.

Par contre dans quel cas calcules tu le temps de trajet entre 2 villes ?
 

DeletedUser57123

Guest
Lorsque que tu fais des outils, ou que tu souhaites automatiser certaines choses pour Grepolis, comme je le fais, le calcul pour savoir le temps entre deux villes permet tout un tas de chose. J'ai étudié la question personnellement afin de répondre à un problème, j'ai vu que le sujet faisait parler sur les forums (plutôt américain) mais jamais la solution, j'ai voulu la partager, si un jour quelqu'un se retrouve dans le même cas que moi il sera content de voir la réponse bien rédigé :)
 

DeletedUser58442

Guest
j'ai cependant posé quelques questions sur le sujet et ce matin le fichier ne fonctionne plus => dommage car très utile et facile d'utilisation ..Tutuapp 9apps Showbox
 
Dernière édition par un modérateur:
Statut
N'est pas ouverte pour d'autres réponses.