JeuWeb - Crée ton jeu par navigateur
[Réglé]Valeurs aléatoires pour un remplissage de carte - 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 : [Réglé]Valeurs aléatoires pour un remplissage de carte (/showthread.php?tid=606)



[Réglé]Valeurs aléatoires pour un remplissage de carte - Shidame - 04-01-2007

Bonjour à tous et meilleurs voeux,

Il est vrai que j'ai été longuement absent au niveau des post mais je passe toujours de temps en temps sur le forum, la fac me prend du temps.

Bref passons directement au vif du sujet.

Je souhaite remplir aléatoirement une carte de systemes stellaires ayant comme attributs :

- coordonnée absysse : x (entre 1 et 200)
- coordonnée ordonnée : y (entre 1 et 200)
- une image associé sur la carte (un simple INT) : skin (entre 1 et 6)

Le coin haut-gauche représente le zéro.

J'ai donc créé un script pour remplir aléatoirement cette carte de 40000 cases a 10% soit environ 4000 systèmes.

(tout les scripts ci-dessous sont au stade de broullion voir code panzani Smile )

Voici mon script :
creer_systemes.php
Code PHP :
<?php
mysql_connect
('localhost','root','') ;
mysql_select_db('elvetika') ;

for (
$i=0; $i<25; $i++) {
$sql = 'insert into systeme (px, py, skin)
select A,B,C
from (
select
truncate(rand()*200+1,0) A,
truncate(rand()*200+1,0) B,
truncate(rand()*6+1,0) C
) as rand
where not exists (select skin from systeme where px=rand.A and py=rand.B)'
;
mysql_unbuffered_query ($sql);
}

$req = mysql_query("SELECT count(*) FROM systeme");
$total = array_pop(mysql_fetch_row($req));

mysql_close();

if (
$total<4000) header ("Refresh: 1;URL=creer_systemes.php");
echo
$total;
?>

Ensuite j'utilise la librairie GD pour visualiser ma création :p , car bon pas évident pour un humain (même demi-dieu) d'interpréter une suite de coordonnée.

build_map.php
Code PHP :
<?php
header
("Content-type: image/png");

$image_carte = imagecreate(800,700) or die ('Librairie GD non fonctionnelle');
$fond_carte=Imagecolorallocate($image_carte, 0, 0, 0);

$decx=22; //decalage pour faire jolie ;p
$decy=22;

$bleu = Imagecolorallocate($image_carte, 255, 0, 0);
$vert = Imagecolorallocate($image_carte, 255, 0, 255);
$jaune = Imagecolorallocate($image_carte, 0, 255, 255);
$rose = Imagecolorallocate($image_carte, 255, 255, 0);
$blanc = Imagecolorallocate($image_carte, 255, 255, 255);
$noir = Imagecolorallocate($image_carte, 120, 30, 255);

$x1=0+$decx;
$x2=0+$decx;

for (
$i=1;$i<=5;$i++) {
ImageLine ($image_carte, $x1, $decy, $x2, 600+$decy, $blanc);
$x1= $x1+150;
$x2 =$x2+150;
}

$y1=0+$decy;
$y2=0+$decy;

for (
$i=1;$i<=5;$i++) {
ImageLine ($image_carte, $decx, $y1, 600+$decx, $y2, $blanc);
$y1= $y1+150;
$y2 =$y2+150;
}

include(
'config.php'); // constantes HOST USER PWD BDD
include ('inc/class.mydb.php');// class mysql (si qqun veu je peu la poster mais je l'ai pas finie)

$sql = new myDB(HOST, USER, PWD , BDD);

$query = 'SELECT px,py,skin FROM systeme';


$nbbleu = 0;
$nbvert = 0;
$nbjaune = 0;
$nbrose = 0;
$nbblanc = 0;
$nbnoir = 0;


if (!
$sql->select($query)) {}
else {
foreach (
$sql->select($query) as $value) {

//je cree un tableau pour les trier par clan
$px = $value['px'];
$py = $value['py'];


switch (
$value['skin']) {
case
1 :
$color = $bleu;
$nbbleu++;
break;
case
2 :
$color = $vert;
$nbvert++;
break;
case
3 :
$color = $jaune;
$nbjaune++;
break;
case
4 :
$color = $rose;
$nbrose++;
break;
case
5 :
$color = $blanc;
$nbblanc++;
break;
case
6 :
$color = $noir;
$nbnoir++;
break;
}

$px = $px*3;
$py = $py*3;
imagefilledrectangle ($image_carte, $px+$decx-1, $py+$decy-1, $px+$decx+1, $py+$decy+1, $color);
}
}

imagestring($image_carte, 4, 722, 250, $nbbleu, $bleu);
imagestring($image_carte, 4, 722, 300, $nbvert, $vert);
imagestring($image_carte, 4, 722, 350, $nbblanc, $blanc);
imagestring($image_carte, 4, 722, 400, $nbrose, $rose);
imagestring($image_carte, 4, 722, 450, $nbjaune, $jaune);
imagestring($image_carte, 4, 722, 500, $nbnoir, $noir);
$somme = $nbbleu+$nbvert+$nbblanc+$nbrose+$nbjaune+$nbnoir;
imagestring($image_carte, 3, 666, 550, 'TOTAL : '.$somme, $blanc);

$sql->close();
// on affiche l'image
imagepng($image_carte);
ImageDestroy ($image_carte);
?>
Voici le rendu :

[Image: galaxie_couleur.png]

On vois clairement un motif apparaitre, je sais que la fonction rand() est pseudo aléatoire mais bon la je bloque....

J'ai également oté les couleurs cela donne ceci :
[Image: galaxie_noir-blanc.png]
On vois que rand() a du mal sur les petits ecarts ( 1 à 6).

Ai-je commis une erreur?

Voyez vous un moyen de remédier à ce problème?


Merci d'avance,


RE: Valeurs aléatoires pour un remplissage de carte - Loetheri - 04-01-2007

Utilise mt_rand de PHP. Il est nettement plus performant pour l'avoir essayé de nombreuses fois.


RE: Valeurs aléatoires pour un remplissage de carte - Shidame - 04-01-2007

Merci je viens d'essayer c'est bien mieux mais nécessite du coup d'effectuer un calcul par PHP.
Voici la partie que j'ai modifié:
dans 'creer_systme.php'
Code PHP :
<?php 
for ($i=0; $i<25; $i++) {
$rand1 = mt_rand(1,200);
$rand2 = mt_rand(1,200);
$rand3 = mt_rand(1,6);

$sql = 'insert into systeme (px, py, skin)
select A,B,C
from (
select
'
.$rand1.' A,
'
.$rand2.' B,
'
.$rand3.' C
) as rand
where not exists (select skin from systeme where px=rand.A and py=rand.B)'
;
mysql_unbuffered_query ($sql);
}
Voici le résultat :
[Image: galaxie_couleur_mt_rand.png]

Merci Loetheri,


RE: Valeurs aléatoires pour un remplissage de carte - Loetheri - 04-01-2007

Que cela soit PHP ou MySQL, c'est toujours un serveur derrière.
Ce qui change, c'est l'implémentation de la fonction. Plus ta fonction est performante pour trouver des valeurs aléatoires, plus il y a de chances que cela utilise de la puissance de ton serveur.


RE: Valeurs aléatoires pour un remplissage de carte - Shidame - 04-01-2007

Je ne parlai pas de ca exactement, avant tout etait interprétai directement par mysql, mais ca n'est pas grave ca marche c'est l'essentiel, et puis le script ne sert que pour remplir la BDD.

En cherchant dans le manuel php : mt_rand consome moins que rand() :p


RE: [Réglé]Valeurs aléatoires pour un remplissage de carte - joshua - 05-01-2007

gloups. Effectivement, je pensais aps que le rand() était AUSSI pourri....


RE: [Réglé]Valeurs aléatoires pour un remplissage de carte - Loetheri - 05-01-2007

On parle de rand de MySQL pour la première image.
rand de PHP ne doit guère fonctionner mieux que cela.
Il vaut mieux utiliser mt_rand de PHP.