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
Voici ma solution actuelle (elle fonctionne):
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
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 :-)