JeuWeb - Crée ton jeu par navigateur
Sélection sous contrainte dans un array - 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 : Sélection sous contrainte dans un array (/showthread.php?tid=7206)



Sélection sous contrainte dans un array - Racktor - 20-06-2014

Bonjour !

Bon je reviens pour retravailler quelque chose que j'avais déjà exposer.

On m'avait aidé pour construite un array pour y stocker pas mal de variable fixe, très pratique au demeurant !
<?php
$BUILDINGS = array (
'place_du_marche' =>
array (
'id' => '9',
'nom' => 'place du marché',
'nom_pluriel' => '',
'nom_variable' => 'place_du_marche',
'type' => 'distribution',
),
'masure' =>
array (
'id' => '7',
'nom' => 'masure',
'nom_pluriel' => '',
'nom_variable' => 'masure',
'type' => 'habitation',
),
'batisse' =>
array (
'id' => '8',
'nom' => 'bâtisse',
'nom_pluriel' => '',
'nom_variable' => 'batisse',
'type' => 'habitation',
),
'domaine' =>
array (
'id' => '21',
'nom' => 'domaine',
'nom_pluriel' => '',
'nom_variable' => 'domaine',
'type' => 'habitation',
),
'appartement' =>
array (
'id' => '22',
'nom' => 'appartement',
'nom_pluriel' => '',
'nom_variable' => 'appartement',
'type' => 'habitation',
),
'residence' =>
array (
'id' => '23',
'nom' => 'résidence',
'nom_pluriel' => '',
'nom_variable' => 'residence',
'type' => 'habitation',
),
'hopital' =>
array (
'id' => '1',
'nom' => 'hôpital',
'nom_pluriel' => '',
'nom_variable' => 'hopital',
'type' => 'hygiene',
),
'fontaine' =>
array (
'id' => '2',
'nom' => 'fontaine',
'nom_pluriel' => '',
'nom_variable' => 'fontaine',
'type' => 'hygiene',
),
'morgue' =>
array (
'id' => '5',
'nom' => 'morgue',
'nom_pluriel' => '',
'nom_variable' => 'morgue',
'type' => 'hygiene',
),
'dentiste' =>
array (
'id' => '6',
'nom' => 'dentiste',
'nom_pluriel' => '',
'nom_variable' => 'dentiste',
'type' => 'hygiene',
),
'fonderie' =>
array (
'id' => '12',
'nom' => 'fonderie',
'nom_pluriel' => '',
'nom_variable' => 'fonderie',
'type' => 'industrie',
),
'scierie' =>
array (
'id' => '13',
'nom' => 'scierie',
'nom_pluriel' => '',
'nom_variable' => 'scierie',
'type' => 'industrie',
),
'pressoir' =>
array (
'id' => '17',
'nom' => 'pressoir',
'nom_pluriel' => '',
'nom_variable' => 'pressoir',
'type' => 'industrie',
),
'armurerie' =>
array (
'id' => '18',
'nom' => 'armurerie',
'nom_pluriel' => '',
'nom_variable' => 'armurerie',
'type' => 'industrie',
),
'moulin' =>
array (
'id' => '19',
'nom' => 'moulin',
'nom_pluriel' => '',
'nom_variable' => 'moulin',
'type' => 'industrie',
),
'boulangerie' =>
array (
'id' => '20',
'nom' => 'boulangerie',
'nom_pluriel' => '',
'nom_variable' => 'boulangerie',
'type' => 'industrie',
),
'brasserie' =>
array (
'id' => '24',
'nom' => 'brasserie',
'nom_pluriel' => '',
'nom_variable' => 'brasserie',
'type' => 'industrie',
),
'mine_de_fer' =>
array (
'id' => '14',
'nom' => 'mine de fer',
'nom_pluriel' => '',
'nom_variable' => 'mine_de_fer',
'type' => 'ressources',
),
'verger' =>
array (
'id' => '15',
'nom' => 'verger',
'nom_pluriel' => '',
'nom_variable' => 'verger',
'type' => 'ressources',
),
'mine_d_or' =>
array (
'id' => '16',
'nom' => 'mine d\'or',
'nom_pluriel' => '',
'nom_variable' => 'mine_d_or',
'type' => 'ressources',
),
'exploitation_forestiere' =>
array (
'id' => '25',
'nom' => 'exploitation forestière',
'nom_pluriel' => '',
'nom_variable' => 'exploitation_forestiere',
'type' => 'ressources',
),
'poste_de_garde' =>
array (
'id' => '26',
'nom' => 'palais de justice',
'nom_pluriel' => '',
'nom_variable' => 'poste_de_garde',
'type' => 'securite',
),
'grenier' =>
array (
'id' => '3',
'nom' => 'grenier',
'nom_pluriel' => '',
'nom_variable' => 'grenier',
'type' => 'stockage',
),
'entrepot' =>
array (
'id' => '4',
'nom' => 'entrepôt',
'nom_pluriel' => '',
'nom_variable' => 'entrepot',
'type' => 'stockage',
),
);
?>
je me dis quelque chose : pour soulager la BDD j'aimerais directement faire ma sélection a partir de ce tableau.

j'explique autrement : j'aimerais faire une boucle qui me donne [nom_variable] quand le type est égal à 'habitation'.
Bhon j'ai compris que pour extraire en entier les données il faut deux foreach ...
Et en conditionnant dans ma tête je me dis ca :
Code :
    foreach ($BUILDINGS as $v1)
    {
        foreach ($v1 as $v2)
        {
            if($BUILDINGS[$v2]['type'] == 'habitation')
            {
                echo "$v2\n";
            }
        }
    }
j'obtiens :
Citation :masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence masure masure batisse domaine domaine appartement appartement residence

Bhon a la rigeur je pourrais enlever les doublons et puis hop mais je pense j'ai merdé quelque part ...


RE: Sélection sous contrainte dans un array - niahoo - 20-06-2014

essaie ça. je comprends pas pourquoi tu as deux foreach.

<?php
foreach ($BUILDINGS as $key => $infos)
{
if($infos['type'] == 'habitation')
{
echo "$key\n";
}
}

tes champs 'nom_variable' sont redondants avec les clés associées à chaque tableau. (Enfin dans l'exemple elles sont toujours identiques). Tu peux donc directement accéder à la clé dans ton foreach.

Ton second foreach traversait chaque liste de champs et à mon avis ça faisait une comparaison entre une variable inexistante et un string, les deux étant converties en entier zéro. On dirait bien que tu n'a pas les erreurs qui s'affichent et c'est un gros handicap.

error_reporting(E_ALL); ou error_reporting(-1) si tu veux les strict.


RE: Sélection sous contrainte dans un array - Xenos - 20-06-2014

On OO, tu auras bien plus de facilité pour gérer tout cela...

[exemple en rédaction...]


<?php

/**
* Un batiment stocké dans PHP au lieu de la BDD
*/
interface building_interface
{
}

/**
* Interfaces définissant le type d'un batiment.
*/
interface building_types
{
const Habitation = 'habitation';
const Distribution = 'distribution';
const Hygiene = 'hygiene';
const Securite = 'securite';
const Stockage = 'stockage';
const Ressources = 'ressources';
const Industrie = 'industrie';
}
interface building_type_distribution
{
const type = building_types:Big Grinistribution;
}
interface building_type_habitation
{
const type = building_types::Habitation;
}
interface building_type_hygiene
{
const type = building_types::Hygiene;
}
interface building_type_industrie
{
const type = building_types::Industrie;
}
interface building_type_ressources
{
const type = building_types::Ressources;
}
interface building_type_securite
{
const type = building_types::Securite;
}
interface building_type_stockage
{
const type = building_types::Stockage;
}

/**
* Les buildings
*/

class place_du_marche implements building_interface, building_type_distribution
{
const id = 9;
const nom = 'place du marché';
const nom_pluriel = '';
const nom_variable = 'place_du_marche';

}
class masure implements building_interface, building_type_habitation
{
const id = 7;
const nom = 'masure';
const nom_pluriel = '';
const nom_variable = 'masure';
}
class batisse implements building_interface, building_type_habitation
{
const id = 8;
const nom = 'bâtisse';
const nom_pluriel = '';
const nom_variable = 'batisse';
}
class domaine implements building_interface, building_type_habitation
{
const id = 21;
const nom = 'domaine';
const nom_pluriel = '';
const nom_variable = 'domaine';
}
class appartement implements building_interface, building_type_habitation
{
const id = 22;
const nom = 'appartement';
const nom_pluriel = '';
const nom_variable = 'appartement';
}
class residence implements building_interface, building_type_habitation
{
const id = 23;
const nom = 'résidence';
const nom_pluriel = '';
const nom_variable = 'residence';
}
class hopital implements building_interface, building_type_hygiene
{
const id = 1;
const nom = 'hôpital';
const nom_pluriel = '';
const nom_variable = 'hopital';
}
class fontaine implements building_interface, building_type_hygiene
{
const id = 2;
const nom = 'fontaine';
const nom_pluriel = '';
const nom_variable = 'fontaine';
}
class morgue implements building_interface, building_type_hygiene
{
const id = 5;
const nom = 'morgue';
const nom_pluriel = '';
const nom_variable = 'morgue';
}
class dentiste implements building_interface, building_type_hygiene
{
const id = 6;
const nom = 'dentiste';
const nom_pluriel = '';
const nom_variable = 'dentiste';
}
class fonderie implements building_interface, building_type_industrie
{
const id = 12;
const nom = 'fonderie';
const nom_pluriel = '';
const nom_variable = 'fonderie';
}
class scierie implements building_interface, building_type_industrie
{
const id = 13;
const nom = 'scierie';
const nom_pluriel = '';
const nom_variable = 'scierie';
}
class pressoir implements building_interface, building_type_industrie
{
const id = 17;
const nom = 'pressoir';
const nom_pluriel = '';
const nom_variable = 'pressoir';
}
class armurerie implements building_interface, building_type_industrie
{
const id = 18;
const nom = 'armurerie';
const nom_pluriel = '';
const nom_variable = 'armurerie';
}
class moulin implements building_interface, building_type_industrie
{
const id = 19;
const nom = 'moulin';
const nom_pluriel = '';
const nom_variable = 'moulin';
}
class boulangerie implements building_interface, building_type_industrie
{
const id = 20;
const nom = 'boulangerie';
const nom_pluriel = '';
const nom_variable = 'boulangerie';
}
class brasserie implements building_interface, building_type_industrie
{
const id = 24;
const nom = 'brasserie';
const nom_pluriel = '';
const nom_variable = 'brasserie';
}
class mine_de_fer implements building_interface, building_type_ressources
{
const id = 14;
const nom = 'mine de fer';
const nom_pluriel = '';
const nom_variable = 'mine_de_fer';
}
class verger implements building_interface, building_type_ressources
{
const id = 15;
const nom = 'verger';
const nom_pluriel = '';
const nom_variable = 'verger';
}
class mine_d_or implements building_interface, building_type_ressources
{
const id = 16;
const nom = "mine d'or"; // l'apostrophe panique la coloration syntaxique de JeuWeb...
const nom_pluriel = '';
const nom_variable = 'mine_d_or';
}
class exploitation_forestiere implements building_interface, building_type_ressources
{
const id = 25;
const nom = 'exploitation forestière';
const nom_pluriel = '';
const nom_variable = 'exploitation_forestiere';
}
class poste_de_garde implements building_interface, building_type_securite
{
const id = 26;
const nom = 'palais de justice';
const nom_pluriel = '';
const nom_variable = 'poste_de_garde';
}
class grenier implements building_interface, building_type_stockage
{
const id = 3;
const nom = 'grenier';
const nom_pluriel = '';
const nom_variable = 'grenier';
}
class entrepot implements building_interface, building_type_stockage
{
const id = 4;
const nom = 'entrepôt';
const nom_pluriel = '';
const nom_variable = 'entrepot';
}

$BUILDINGS = array (
new place_du_marche(),
new masure(),
new batisse(),
new domaine(),
new appartement(),
new residence(),
new hopital(),
new fontaine(),
new morgue(),
new dentiste(),
new fonderie(),
new scierie(),
new pressoir(),
new armurerie(),
new moulin(),
new boulangerie(),
new brasserie(),
new mine_de_fer(),
new verger(),
new mine_d_or(),
new exploitation_forestiere(),
new poste_de_garde(),
new grenier(),
new entrepot()
);

foreach ($BUILDINGS as $building)
if ($building::type == building_types::Habitation)
var_dump(array($building::nom_variable => $building));
?>

building_interface est l'interface commune à tous les batiments, et indique qu'un objet est un batiment
building_types centralise les types possibles des batiments. L'intérêt évident est de ne plus répéter la chaine de caractères (ex: 'habitation'), et tout répétition est une invitation à la fuate de farppe Smile
building_type_* est l'interface indiquant qu'un bâtiment est un type donné.
class * sont les batiments. On pourra leur trouver des noms de classe plus ciblés, ou bien (et c'est ce que je ferait), les mettre dans un namespace bien à eux.

Je trouve un tel code bien plus lisible, séparant clairement la création du tableau de données (avec les "new") de la définition de chaque building (aka chaque classe).
De plus, le traitement de $BUILDINGS sera facilité: on pourra ajouter des méthodes aux classes si on veut faire faire quelque chose à ces bâtiments.
Par exemple, on pourra passer par une classe abstraite "abstract class building_abstract" qui centraliserait les méthodes communes aux classes déclarées ici. Ensuite, on leur fait hériter de cette classe abstraite via class * extends building_abstract implements building_interface, building_type_*.


Notes: le var_dump() affiche un "tableau" de un élément, qui au nom_variable du batiment associe l'objet correspondant à ce batiment, j'ai trouvé cela assez joli comme rendu Smile
En pratique, je ferai de $BUILDINGS un objet (un conteneur de building_interface), mais bon, je n'ai pas envie d'écrire tout le code ^^


RE: Sélection sous contrainte dans un array - Ter Rowan - 21-06-2014

chuis pas d'accord avec toi Xenos

les tableaux ca existe aussi en OO et ici y a rien qui justifie de créer des structures complexes, on est juste sur une liste de paramètres (enfin, une table quoi)


RE: Sélection sous contrainte dans un array - Xenos - 21-06-2014

Pour mon $BUILDINGS lui-même, d'accord, en tant que "liste de new", il peut rester comme étant un tableau.

En revanche, pour le $BUILDINGS original, il me semble plus adapté (mais pas obligatoire bien sûr) d'en faire une liste d'objets. Si cela avait été une table de BDD, chaque ligne aurait représenté un objet. On peut d'ailleurs mettre chaque classe dans un fichier séparé, mettre le tout dans un dossier, et parcourir le contenu de ce dossier pour construire "$BUILDINGS". Ainsi, quand on voudra ajouter un type de bâtiment, il suffira de faire une nouvelle classe et de l'ajouter au dossier (0 modification de code = moins de risque de bousiller un truc Smile ).

Ok pour laisser les tableaux en "pas objet" quand ils sont à 1D, mais quand ils sont à 2D avec chaque ligne qui représente un "truc", cela me semble plus approprié de faire de "truc" une classe (surtout quand, comme ici, on a un paramètre "type" qui apparait: cela fait vachement 'class' à mon gout ^^).
Sinon, je suis d'accord pour stocker sous forme de tableaux les matrices (en encapsulant le tableau dans une classe si on veut) et les tableaux de paramètres où chaque élément est indépendant (par exemple, le tableau de combat des pokémons).

D'ailleurs, cela serait peut-être encode plus pertinent d'en faire des interfaces plutôt que des classes: ainsi, il suffirait d'implémenter l'interface à la classe correspondant à ce batiment, plutôt que d'avoir un $BUILDINGS centralisant le tout...

On peut toujours faire les deux: remplacer les "class" de l'exemple par des interfaces (avec des constantes), créer une classe par batiment qui se contente d'implémenter la bonne interface, et instancier ces classes spécifiques dans $BUILDINGS. Dans le reste du code, dans la classe "réelle" du batiment, on pourra alors implémenter la bonne interface.


RE: Sélection sous contrainte dans un array - Racktor - 21-06-2014

Merci niahoo c'est parfait !

De toute façon la POO c'est pas dans mon univers même si je conçois que ca pourrait être sympas de l'utiliser ...

je viens de comprendre ma bêtise ... j'avais pas vu la clef ...