Problème de simplification de code php - lopji - 13-12-2011
Bonjour, depuis quelques jours je travail sur la map de mon jeu pour générer un décor aléatoire. J'ai réussis à faire un code fonctionnel, mais ce code prend énormément de ressource au serveur et le fait même planter ! :'( J'ai essayé de le réduire mais je n'ai pas trouvé comment, quelqu'un pourrait-il m'aider à ce sujet ?
Le code:
<?php
for ($x = 1; $x <= 23; $x++)
{
$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
$bdd = new PDO('mysql:host=sql.olympe-network.com;dbname=*****', '*****', '*****', $pdo_options);
$reponse = $bdd->query('SELECT Nombrecarre FROM map ORDER by Id desc Limit 0,1');
while ($donnees = $reponse->fetch())
{
$Nombrecarre = $donnees['Nombrecarre'];
}
$reponse = $bdd->query('SELECT Id FROM map ORDER by Id desc Limit 0,1');
while ($donnees = $reponse->fetch())
{
$Id = $donnees['Id'];
}
$reponse = $bdd->query('SELECT * FROM map WHERE Nombrecarre = '.$Nombrecarre.' ORDER by Id Limit 1');
$Nouvellecase = $Nombrecarre - 1;
$Nombrecarre = $Nombrecarre + 2;
$Id++;
while ($donnees = $reponse->fetch())
{
if ($donnees['Pos_x'] == $donnees['Pos_y'] && $donnees['Pos_y'] <= 0){
// définis la position du prochain carré
$positionX = $donnees['Pos_x'] - 1;
$positionY = $donnees['Pos_y'] - 1;
echo '<br />' . $positionY .'<br />';
for ($i = 0; $i <= $Nouvellecase; $i++)
{
$positionnouvelleX = $positionX + $i;
$positionancienX = $positionnouvelleX - 1;
//$positionancienY = $positionY - 1;
$req = $bdd->prepare('SELECT Nom FROM map WHERE Pos_x = ? AND Pos_y = ? ');
$req->execute(array($positionancienX, $positionY));
while ($donnees = $req->fetch())
{
$Nom = $donnees['Nom'];
}
$nombre = mt_rand(1,100);
if ($Nom == 'plaine2')
{
echo 'plaine2';
if ($nombre < 60)
{
$terrains = "plaine1";
}
else
{
$terrains = 'plaine3';
}
}
else if ($Nom == 'plaine3')
{
echo 'plaine3';
if ($nombre < 60)
{
$terrains = "plaine2";
}
else
{
$terrains = 'foret1';
}
}
else if ($Nom == 'foret1')
{
echo 'foret1';
if ($nombre < 35)
{
$terrains = "plaine3";
}
else
{
$terrains = 'foret1';
}
}
else if ($Nom == 'eau')
{
echo 'eau';
if ($nombre < 35)
{
$terrains = "plaine1";
}
else
{
$terrains = 'eau';
}
}
else
{
echo 'plaine1';
if ($nombre < 40)
{
$terrains = "plaine1";
}
else
{
if ($nombre < 75 )
{
$terrains = 'plaine2';
}
else
{
$terrains = 'eau';
}
}
}
$req = $bdd->prepare('INSERT INTO map(Nombrecarre, Id, Nom, Pos_x, Pos_y) VALUES(:Nombrecarre, :Id, :terrains, :positionnouvelleX, :positionY)');
$req->execute(array(
'Nombrecarre' => $Nombrecarre,
'Id' => $Id,
'terrains' => $terrains,
'positionnouvelleX' => $positionnouvelleX,
'positionY' => $positionY
));
$Id++;
}
$positionX = $positionnouvelleX;
for ($i = 1; $i <= $Nouvellecase; $i++)
{
echo '<br />' . $positionY .'<br />';
$positionnouvelleY = $positionY + $i;
$positionancienY = $positionnouvelleY - 1;
echo '<br /> '. $i .'<br />';
echo '<br />' . $positionnouvelleY .'<br />';
$req = $bdd->prepare('SELECT Nom FROM map WHERE Pos_x = ? AND Pos_y = ? ');
$req->execute(array($positionX, $positionancienY));
while ($donnees = $req->fetch())
{
$Nom = $donnees['Nom'];
}
$nombre = mt_rand(1,100);
if ($Nom == 'plaine2')
{
echo 'plaine2';
if ($nombre < 60)
{
$terrains = "plaine1";
}
else
{
$terrains = 'plaine3';
}
}
else if ($Nom == 'plaine3')
{
echo 'plaine3';
if ($nombre < 60)
{
$terrains = "plaine2";
}
else
{
$terrains = 'foret1';
}
}
else if ($Nom == 'foret1')
{
echo 'foret1';
if ($nombre < 35)
{
$terrains = "plaine3";
}
else
{
$terrains = 'foret1';
}
}
else if ($Nom == 'eau')
{
echo 'eau';
if ($nombre < 35)
{
$terrains = "plaine1";
}
else
{
$terrains = 'eau';
}
}
else
{
echo 'plaine1';
if ($nombre < 40)
{
$terrains = "plaine1";
}
else
{
if ($nombre < 75 )
{
$terrains = 'plaine2';
}
else
{
$terrains = 'eau';
}
}
}
$req = $bdd->prepare('INSERT INTO map(Nombrecarre, Id, Nom, Pos_x, Pos_y) VALUES(:Nombrecarre, :Id, :terrains, :positionnouvelleX, :positionY)');
$req->execute(array(
'Nombrecarre' => $Nombrecarre,
'Id' => $Id,
'terrains' => $terrains,
'positionnouvelleX' => $positionX,
'positionY' => $positionnouvelleY
));
$Id++;
}
$positionX = $positionnouvelleX;
$positionY = $positionnouvelleY;
for ($i = 1; $i <= $Nouvellecase; $i++)
{
$positionnouvelleX = $positionX - $i;
$positionancienX = $positionnouvelleX + 1;
$req = $bdd->prepare('SELECT Nom FROM map WHERE Pos_x = ? AND Pos_y = ? ');
$req->execute(array($positionancienX, $positionY));
while ($donnees = $req->fetch())
{
$Nom = $donnees['Nom'];
}
$nombre = mt_rand(1,100);
if ($Nom == 'plaine2')
{
echo 'plaine2';
if ($nombre < 60)
{
$terrains = "plaine1";
}
else
{
$terrains = 'plaine3';
}
}
else if ($Nom == 'plaine3')
{
echo 'plaine3';
if ($nombre < 60)
{
$terrains = "plaine2";
}
else
{
$terrains = 'foret1';
}
}
else if ($Nom == 'foret1')
{
echo 'foret1';
if ($nombre < 35)
{
$terrains = "plaine3";
}
else
{
$terrains = 'foret1';
}
}
else if ($Nom == 'eau')
{
echo 'eau';
if ($nombre < 35)
{
$terrains = "plaine1";
}
else
{
$terrains = 'eau';
}
}
else
{
echo 'plaine1';
if ($nombre < 40)
{
$terrains = "plaine1";
}
else
{
if ($nombre < 75 )
{
$terrains = 'plaine2';
}
else
{
$terrains = 'eau';
}
}
}
$req = $bdd->prepare('INSERT INTO map(Nombrecarre, Id, Nom, Pos_x, Pos_y) VALUES(:Nombrecarre, :Id, :terrains, :positionnouvelleX, :positionY)');
$req->execute(array(
'Nombrecarre' => $Nombrecarre,
'Id' => $Id,
'terrains' => $terrains,
'positionnouvelleX' => $positionnouvelleX,
'positionY' => $positionY
));
$Id++;
}
$positionX = $positionnouvelleX;
$positionY = $positionnouvelleY;
for ($i = 1; $i <= ($Nouvellecase - 1); $i++)
{
$positionnouvelleY = $positionY - $i;
$positionancienY = $positionnouvelleY + 1;
$req = $bdd->prepare('SELECT Nom FROM map WHERE Pos_x = ? AND Pos_y = ? ');
$req->execute(array($positionX, $positionancienY));
while ($donnees = $req->fetch())
{
$Nom = $donnees['Nom'];
}
$nombre = mt_rand(1,100);
if ($Nom == 'plaine2')
{
echo 'plaine2';
if ($nombre < 60)
{
$terrains = "plaine1";
}
else
{
$terrains = 'plaine3';
}
}
else if ($Nom == 'plaine3')
{
echo 'plaine3';
if ($nombre < 60)
{
$terrains = "plaine2";
}
else
{
$terrains = 'foret1';
}
}
else if ($Nom == 'foret1')
{
echo 'foret1';
if ($nombre < 35)
{
$terrains = "plaine3";
}
else
{
$terrains = 'foret1';
}
}
else if ($Nom == 'eau')
{
echo 'eau';
if ($nombre < 35)
{
$terrains = "plaine1";
}
else
{
$terrains = 'eau';
}
}
else
{
echo 'plaine1';
if ($nombre < 40)
{
$terrains = "plaine1";
}
else
{
if ($nombre < 75 )
{
$terrains = 'plaine2';
}
else
{
$terrains = 'eau';
}
}
}
$req = $bdd->prepare('INSERT INTO map(Nombrecarre, Id, Nom, Pos_x, Pos_y) VALUES(:Nombrecarre, :Id, :terrains, :positionnouvelleX, :positionY)');
$req->execute(array(
'Nombrecarre' => $Nombrecarre,
'Id' => $Id,
'terrains' => $terrains,
'positionnouvelleX' => $positionX,
'positionY' => $positionnouvelleY
));
$Id++;
}
}
else
{
echo 'erreur <br />';
}
}
}
?>
Merci d'avance .
RE: Problème de simplification de code php - php_addict - 13-12-2011
oh la vache...
tu n'y va pas de main morte pour ton premier message sur le forum...tu te rend compte qu'il n'y a que toi qui peut comprendre ton code? imagines que je fasse la même chose, je te file du code et que je te demande pourquoi ca cloche, sans explications ni rien...
RE: Problème de simplification de code php - Ter Rowan - 13-12-2011
je ne suis pas rentré plus que ca dans le code pour identifier d'éventuelles boucles infinies ou autre mais déj ce qui me choque c'est le nombre de requêtes que tu fais dans les boucles
le mieux à mon sens est déjà de découper le code :
1) construire une requête qui ramène tous les enregistrements dont tu as besoin de la table map (avec un where, histoire de n'amener que les enregistrements dont tu as besoin)
là tu fais des requêtes unitaires donc au moins 23 fois trop
de plus tu fais une requete pour ramener un "nombrecarré" et après tu fais une requete sur la même table pour ramener les infos du nombre carrés, ça fait au moins 2 fois trop
donc déjà 46 fois trop de requete select
2) boucler pour construire les données que tu souhaites (pas essayer de comprendre ta boucle avec $x mais c'est le résultat de cette boucle)
3) construire ta phase d'insertion avec les prepare qui vont bien
1 requete prepare
boucle pour tous les insert (via execute),
1 autre requete prepare
boucle pour tous les insert (via execute),
etc...
l'intérêt de la préparation c'est de faire plusieurs fois la même requete de suite (avec des valeurs différentes) là tu changes à chaque fois
RE: Problème de simplification de code php - lopji - 13-12-2011
Ok merci Ter Rowan, donc si j'ai bien compris je dois préparer mes requêtes avant la boucle, puis les exécuter dans la boucle en passant les différents paramètres nécessaire ? Sinon une autre question, à l'exécution du code, le switch est il plus rapide ou égal au if ?
Sinon désolé pour le code, j'ai oublié de le commenter.
RE: Problème de simplification de code php - niahoo - 13-12-2011
Salut,
Ton code n'est pas assez bien organisé. Essaie de le découper en plein de fonction qui ont chacune un rôle précis et unique (chaque tache est remplie par une seule fonction, chaque fonction ne remplit qu'une tache).
Tu y verras plus clair (nous aussi).
Au lieu de faire $nombre = mt_rand() et une série de if/elseif/elseif/elseif dans une boucle, ce qui est long, essaie plutot de mettre tes terrains dans un array et d'utiliser array_rand.Si tu veux donner plus de chances à un type de terrain de sortir, tu peux trouver une solution simple sur ce post : http://www.jeuweb.org/showthread.php?tid=7797&pid=99386#pid99386
Ensuite, les remarques concernant les requêtes sur un post précédent s'ajoutent à ce que je propose, ce n'est pas au choix
Pour finir, si c'est toujours long, ou non mais que tu veux pouvoir optimiser, tu pourrais lancer la génération de 200 cartes et les stocker en fichier ou bese de données de façon légère et ensuite tu n'auras qu'à les ressortir au besoin sans devoir les regénérer. Tu peux en regénérer de temps en temps, en gardant ou pas les anciennes.
RE: Problème de simplification de code php - Gropéper - 14-12-2011
(13-12-2011, 09:07 PM)lopji a écrit : Ok merci Ter Rowan, donc si j'ai bien compris je dois préparer mes requêtes avant la boucle, puis les exécuter dans la boucle en passant les différents paramètres nécessaire ? Sinon une autre question, à l'exécution du code, le switch est il plus rapide ou égal au if ?
Sinon désolé pour le code, j'ai oublié de le commenter.
Non il faut que tu comprimes tes requêtes pour en faire une seule en dehors de la boucle pour éviter d’en faire 250000. Tu stockes le résultat dans un tableau auquel tu accèdes dans la boucle.
RE: Problème de simplification de code php - atra27 - 14-12-2011
c'est hallucinant! tu fait ta connection dans une boucle!
ta besoin de 24 connections ou quoi?
j'ai pas cherché plus loin
si tout est comme sa je propose de recommencer à zéro
si on dit de pas faire de requête dans une boucle c'est Pas pour faire les requêtes ET la connection
RE: Problème de simplification de code php - Hideaki - 14-12-2011
Étonnant que personne, n'aille faîtes cette remarque :
Avant de demander de l'aide, il est important de se présenter !
Pense à faire ou à refaire les tutoriaux du site du zéro, développez.com etc
RE: Problème de simplification de code php - pascal - 14-12-2011
Et explique ce que doit faire le script avec des mots.
Ensuite tu utilise toujours des mots pour montrer la logique, le déroulement du script et seulement après tu passes au code.
RE: Problème de simplification de code php - lopji - 17-12-2011
Ok merci de vos réponses, j'ai réussis à réduire mon code en préparant mes requêtes il est maintenant 4 fois plus rapide^^.
|