JeuWeb - Crée ton jeu par navigateur
calcule de ressources - 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 : calcule de ressources (/showthread.php?tid=5149)



calcule de ressources - zeppelin - 04-09-2010

Bonjour tout le monde!

J'ai une requête un peu spéciale... J'ai pas mal hésité à le mettre ici ou dans la section Algorithme & Solutions, mais comme ça comporte du code je suis venu ici.

Alors pour mon problème:

J'ai dans mon jeu pas mal de ressources différentes (12! Oo). Sur un pillage par exemple, je dois retirer un nombre de ressource d'un certain joueur.

Je veux que ça se passe de telle manière que les ressources où le stoque est le plus élevé soient les plus pillés, jusqu'à se stabiliser.

Exemple:

Le joueur pillé a 83 bois et 25 pierres.

- Il est pillé pour un total de 40. Le pilleur repart donc avec 40 bois et il reste 33 bois ainsi que 25 pierres dans le stoque.
- Il est pillé pour un total de 80. Le pilleur repart donc avec 69 bois et 11 pierres et il reste 14 bois ainsi que 14 pierres dans le stoque.

J'ai beau chercher une bonne solution, je n'arrive pas à trouver quelque chose de simple... Problème d'analyse du problème je pense, je n'ai pas la bonne conception... Et je suis pratiquement sûr qu'il y a plus simple Undecided

Voici ma solution actuelle (elle fonctionne):
Code PHP :
<?php 
public function getRemovedRessources($ressources, $toRemove)
{
// exemple de signature, décommenter pour tester
// $ressources = array('wood' => 23, 'gold' => 87, 'stones' => 23, 'wheat' => 23, 'beer' => 54);
// $toRemove = 121;

// if remove everything
if(array_sum($ressources) <= $toRemove)
{
return
$ressources;
}

// **********************************************
// search from which ressources we have to remove
// **********************************************

// hightest values top
arsort($ressources);

// numeric keys of the array, needed to find position of pointer
$keys = array_keys($ressources);

// if we need to remove from all ressources don\'t even enter the loop
if(array_sum($ressources) - (count($ressources) * end($ressources)) < $toRemove)
{
$tempArray = $ressources;
goto
removeRessources;
}

foreach(
$ressources as $ressource => $value)
{
// position in $keys
$position = array_search($ressource, $keys);

// get an array whit only the x first entries
$tempArray = array_slice($ressources, 0, ($position + 1));

// how much can be removed in this temp array?
$possibleToRemove = array_sum($tempArray) - (count($tempArray) * $ressources[$keys[($position + 1)]]);

// if we found the limit
if($possibleToRemove >= $toRemove)
{
break;
}
}

// **********************************************
// remove ressources
// **********************************************
removeRessources:
// how much has to be left from each ressource
$left = floor((array_sum($tempArray) - $toRemove) / count($tempArray));

// get a copy of $tempArray filled whit $left value
$endTempArray = array_fill_keys(array_keys($tempArray), $left);

// how much got removed
$removed = array_sum($tempArray) - count($tempArray) * $left;

// is there any difference whit our goal (cauz of floor)? foreach diff -> fix a value
$diff = $removed - $toRemove;

foreach(
$endTempArray as $ressource => $value)
{
if(
$diff == 0) break;

$endTempArray[$ressource] += 1;
$diff--;
}

// now we have what should be left, but we want to return what got removed
foreach($endTempArray as $ressource => $left)
{
$removedRessources[$ressource] = $ressources[$ressource] - $left;
}

return
$removedRessources;
}

Si vous avez une piste c'est avec grand plaisir! Merci :-)


RE: calcule de ressources - srm - 04-09-2010

Tu fais la somme de tout le stock, tu calcules donc le pourcentage de chaque unité par rapport au stock total.
Si il pile 40 tu répartis 40 par rapport au pourcentage de chaque unité par rapport au stock total.


RE: calcule de ressources - php_addict - 04-09-2010

j'avais créé un post similaire si tu veut y jeter un coup d'oeil...

--> http://www.jeuweb.org/showthread.php?tid=6549


RE: calcule de ressources - niahoo - 04-09-2010

sinon y a toujours le mode bourrin hein

Code PHP :
<?php 
# FONCTION

<?php
function loot ($startResources, $lootPoints) {
$looted = 0;
while(
$looted < $lootPoints && array_sum($startResources) > 0) {
$startResources[array_search(max($startResources), $startResources)]--;
$looted++;
}
return array(
$looted,$startResources);
}

# SCRIPT DE TEST

$r = array(); // ressources de départ

$r['pierre'] = 50;
$r['bois'] = 12;
$r['or'] = 43;
$r['biere'] = 86;
$r['soupe'] = 37;
$r['chanvre'] = 23;
$r['sable'] = 4;

$lootAmount = 32; // la quantité d'unités à piller
print_r($r);
list(
$looted, $r) = loot($r, $lootAmount); // ressources d'arrivée
echo "$looted units looted\n"; // donne ce qu'on a pu prendre avant que les réserves soient vides
print_r($r);



RE: calcule de ressources - Myrina - 06-09-2010

Voici comment j'ai géré le vol de ressources de manière proportionnelle:

Code PHP :
<?php 
/**
* Effectue le vol des ressources (remplissage du fret)
*
* @param Array $ressBase Ressources à prendre sur la base
* @param Integer $placeFret Place restante en fret
* @return Array
*/
function volRessources($ressBase,$placeFret) {
$totalRessBase=array_sum($ressBase);
if (
$totalRessBase<=$placeFret) {
//Il y a de la place pour tout prendre donc on prend tout
return $ressBase;
} else {
//Remplissage du fret proportionnellement aux ressources détenus sur la base
$ressVol=array_fill(0,count($ressBase),0);
$pourcentageRess=1.0*$placeFret/$totalRessBase;
for (
$i=0;$i<count($ressBase);$i++) {
$delta=intval($ressBase[$i]*$pourcentageRess);
if (
$delta<0) {
$delta=0;
}
if (
$delta>$ressBase[$i]) {
$delta=$ressBase[$i];
}
$ressVol[$i]+=$delta;
$ressBase[$i]-=$delta;
$placeFret-=$delta;
}
return
$ressVol;
}
}



RE: calcule de ressources - niahoo - 07-09-2010

Alors, ça fonctionne ?


RE: calcule de ressources - atra27 - 07-09-2010

haaaaannnnn je vais te piquer ton script!
Trop bon sa! :p