JeuWeb - Crée ton jeu par navigateur
Problème de simplification de code php - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Problème de simplification de code php (/showthread.php?tid=5849)

Pages : 1 2


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 Smile.


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 Smile

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^^.