Bonjour,

Je viens vers vous car je suis une grose buse en math et que je galère un peu sur la création d'une fonction sans doute évidente.

Ce que je fais

J'ai deux tables dans ma base de donnée : users et articles.
Chacune d'elles contient les champs ci-dessous :

  • Gold (int)
  • Silver (int)
  • Copper (int)

Ces trois champs sont indépendants les uns des autres.

Ce que je veux

Sur mon projet, il est possible que les utilisateurs achètent un article contre cet or, argent et cuivre.
Par exemple, une pomme à 25 cuivre, si l'utilisateur a 30 cuivre, il ne lui en restera plus que 5 cuivre et il obtient la pomme. Jusque-là, je n'ai aucune soucis.

Mon soucis vient de la conversion si l'utilisateur n'a pas assez de monnaie. Par exemple, si la pomme coûte 25 cuivre et que l'utilisateur a 1 argent et 0 cuivre, pouvoir transformer la pièce d'argent en 100 pièces de cuivre et faire la soustraction des 25 cuivres de la pomme de manière dynamique. Et pareil s'il a de l'or mais pas assez d'argent et de cuivre.

Auriez-vous une astuce pour optimiser cela ou une fonction php que je ne pense pas connaître qui pourrait m'aider dans la conversion de ces nombres ? J'ai essayé de manière un peu "barbare" et me suis retrouvé avec une quinzaine de conditions un peu bancale dont je doute de la fiabilité.
Merci d'avance. :)

4 réponses


Markus51
Réponse acceptée

Bonsoir,

Si toutes tes monnaies (or,argent,cuivre) ont des équivalences (par exemple (j'invente car tu n'as pas donné les valeurs) : 1 argent = 100 cuivre et 1 or = 100 argent) pourquoi tu stock le tout dans des colonnes différentes ? Pour moi tu devrais avoir une seule valeur admetons "coin" et que celle ci soit distribué comme une pile. On dépile les "coins" lors de l'affichage et dès qu'on a assez pour remplir la pile "gold" alors on incrémente puis avec le reste on incrémente "silver" autant qu'on le peux et dès qu'il ne reste plus assez on incrémente "copper" avec le reste. De ce fait tu as x gold y silver et z copper simplement avec des divisions et des modulos .

Comme ca pour le prix des articles ca se fait en "coin" et l'affichage rendu à l'utilisateur est effectué avec les trois valeurs pour faire plus propre.

J'imagine un truc du genre :

<?php

function getProductValue(int $coinValue) {

    $gold_value = 1000;
    $silver_value = 100;
    $copper_value = 1;

    $gold = floor($coinValue / $gold_value);
    $coinValue = $coinValue % $gold_value;
    $silver = floor($coinValue / $silver_value);
    $coinValue = $coinValue % $silver_value;
    $copper = $coinValue / $copper_value;

    return [
        'gold'      => $gold,
        'silver'    => $silver,
        'copper'    => $copper
    ];
}
var_dump(getProductValue(16));
/*
    array(3) {
      ["gold"]=>
      float(0)
      ["silver"]=>
      float(0)
      ["copper"]=>
      float(16)
    }
*/
var_dump(getProductValue(5230));
/*
    array(3) {
      ["gold"]=>
      float(5)
      ["silver"]=>
      float(2)
      ["copper"]=>
      float(30)
    }
*/

Si jamais tu veux garder ta strucure de table et bien tu fait la transformation lors de la création de ton object user et article en récupèrant les valeurs de la table en valeur "coin".

En tout cas c'est comme ca que je le verrai. Comme toutes tes monnaies sont convertissables et ont des equivalences simple je ferais un systeme de calcul simple comme celui-ci.

Bonne soirée !

Bonjoiur,

Je dirais que tu n'as pas réellement besoin de faire des calculs compliqué, si tu sais que ton "unité" (je vais continuer à utiliser ce terme dans le reste de mon explication ça me semble le plus logique) de base c'est le cuivre (l'unité la plus basse j'entend) te suffit juste par exemple de checker dans ton code si la pièce en question est une pièce de cuivre, d'argent etc.. et dans le cas où c'est autre chose qu'une pièce de cuivre il te suffit d'attribuer une valeur de base pour calculer (genre 1 argent = 100 cuivres) donc si la pomme coûte 5 argent (en imaginant) et que l'utilisateur donnes 6 d'argents tu pourras lui rendre soit 1 d'argent soit 100 de cuivre etc..

Je ne sais pas si mon explication est clair mais bon.

@laznet
Désolé, je n'ai pas vraiment compris, haha.

@Markus51
Ton idée me plait. Lorsque j'ai créé mes champs, je n'avais pas pensé à une simple conversion. Par contre, je crois que tu as une coquille à $copper_value. C'est 1 et non 2, il me semble ?
Quoiqu'il en soit, je viens de tester ta fonction. Elle marche ! Je dois juste l'adapter car j'utilise Twig et je n'arrive pas à la faire fonctionner en retournant un tableau. Merci pour votre aide !

Pas de soucis.
Tu peux afficher un tableau dans twig avec {{dump(array)}}

Pour les valeurs j'ai mis des valeurs au pif 1 et 2 seraient des valeurs acceptables.
En revanche pour plus de flexibilité il serait mieux de faire :

$copper_value = 1;
$silver_value = $copper_value * 100;
$gold_value = $copper_value * 1000;

Ou tout autre mise en relation des valeurs en fonction du resultat escompté.

Bonne continuation.