Algorithmus gesucht.

Asteria

Mitglied
Guten Morgen zusammen !

Ich schon wieder ! :)
Ich bin leider mal wieder etwas planlos.. :-/
...und brauche daher eure ausgezeichnete Hilfe ! :)
Es geht um Folgendes:

Browsergame. Spieler hat anderen Spieler angegriffen und gewonnen.
Als "Belohnung" stiehlt er einige Rohstoffe vom Betreffenden.
Es gibt insgesamt 8 Rohstoffe. Die Anzahl der erbeuteten Rohstoffe
bzw die Anzahl die er mitnehmen kann, richtet sich nach der
Anzahl Karren, ist demnach auch variabel.
Nun sollen die Rohstoffe möglichst gleichmässig aufgeteilt werden.
Also wenn er 8000 Rohstoffe insgesamt stehlen kann,
soll er von jedem halt 1000 Rohstoffe mitnehmen..

Hab mir den ganzen gestrigen Abend den Kopf darüber zerbrochen.
Scheitere aber halt daran, dass von einigen Rohstoffen vielleicht
gerade gar nichts oder zu wenig da ist. Das würde die Aufteilung verändern..
Die einzige Idee, die ich hatte war eine 1-Rohstoff-Schleife.
Sozusagen, dass immer gleichmässig 1 Rohstoff pro Rohstofftyp "abgebucht" wird,
aber wenn man überlegt, dass der Spieler vllt auch 100000 Rohstoffe klauen kann,
würde diese Schleife eeeeeeeewig rechnen..
Also hoffe ich einfach mal, dass die klugen Köpfe hier,
eine deutlich bessere Idee für die Lösung haben ! :)

Beste Grüße
 
Hi

zuerst gehst du vom Besiegten alle 8 Typen durch und suchst von denen, wo nicht (!) 0 da ist, das wenigste (Anzahl in A speichern) und zählst die Nicht-0-Typen auch (B).
Wenn überall 0 ist (B==0), gibts nichts mehr zum stehlen, Schluss..

Sonst gibts noch die Anzahl, die du Stehlen kannst/darfst: C.
Wenn C==0: Schluss

Als nächstes:
Wenn (C/B) kleiner A: A=C/B

Bei allen Typen, bei denen der Besiegte mehr als 0 hat, A abziehen und dem Gewinner A geben
Dann C -= A*B
Und wieder alles von vorne, Schleife.

Vllt.hab ich jetzt auch komplett falsch gedacht...sollte aber so funktionieren.
 
Rechne doch aus:
gesammtlfrachtraum der schiffe / anzahl der ressourcen also in deinem fall:

8000 / 8 = 1000 von jedem rohstoff oder.
16000/8 = 2000 von jedem rohstoff usw.

kann auch sein das ihn denkfehler habe ^^
 
etwa so. Die Erklärung ist im code
PHP:
$ware = array('a' => 4000, 'b' => 3000, 'c' => 700, 'd' => 7000);
$menge = 4000;
$geklaut = array();

//Klauen bis die Karen voll sind oder es nix mehr zu klauen gibt
while($menge = klaue($menge, $ware, $geklaut));
var_dump($ware, $geklaut);

/**
 * Klaut eine Menge Ressourcen glaichmässig über die vorhandenen Ressourcen verteilt
 * @param Array<Integer>    $menge      Menge zu klauenden Ressourcen
 * @param Array<Integer>    $ware       Array mit den vorhandenen Ressourcen (Referenziert)
 * @param Intger            $geklaut    Array mit den geklauten Ressourcen (Referenziert)
 * @return Integer          RestMenge oder False
 */
function klaue($menge, &$ware, &$geklaut){
    //Wenn keine Waren mehr da sind, abbrechen
    if(array_sum($ware)<=0){
        return false;
    }
    //Nur die Waren nehmen, die noch bestand haben
    $wareVorhanden = array_filter($ware);
    //Ausrechnen wieviel pro Ware ich nehmen soll
    $proWare = (Integer)$menge/count($wareVorhanden);
    //Restmenge die noch nicht geklaut werden konnte definieren
    $restMenge = false;
    
    //Alle Waren mit Bestand durchgehen
    //Gerechnet wird aber nachher mit dem gesamten Warenbestand $waren, damit die Referenz nicht kaput geht
    foreach(array_keys($wareVorhanden) as $name){
        //Es sind genügend Waren da
        if($ware[$name] >= $proWare){
            //Waren bei der Diebesmenge dazuzählen
            $geklaut[$name] = $geklaut[$name] + $proWare;
            //Waren beim Warensand abziehen 
            $ware[$name] = $ware[$name] - $proWare;
        //Es sind ungenügend Waren da
        }else{
            //Berechnen wievie Ware nicht geklaut werden konnte
            $restMenge += $proWare - $ware[$name];
            //Waren bei der Diebesmenge dazuzählen
            $geklaut[$name] = $geklaut[$name] + $ware[$name];
            //Warenbestand leeren
            $ware[$name] = 0;
        }
    }
    //Restmenge zurückgeben
    return (Integer) $restMenge;
}
 
Danke auch dir vielmals Yaslaw !
Ich kann den Script sehr gut nachvollziehen,
wirklich schön auskommentiert! Danke.

Verrätst du mir allerdings vllt noch wozu diese & Zeichen
vor $ware und $geklaut beim Funktionsbeginn sind ?!
Ich kenne diese Verwendung leider nciht :(



Edit: Das Schlüsselzeichen wird benutzt, weil ein Array übergeben wird.
Verstanden. Danke nochmals an euch alle ! :))
 
Zuletzt bearbeitet:
Edit: Das Schlüsselzeichen wird benutzt, weil ein Array übergeben wird.
Verstanden. Danke nochmals an euch alle ! :))

Falsch. Das & bedeutet, dass eine Referenz übergeben wird. Wenn ich innerhalb einer Funktion die Variable die mit & übergeben wird verändere, dann verändert sie sich ausserhalb ebenfalls. Ohne das & wird innerhalb der Funktion eine Kopie des Wertes von Ausserhalb verwendet.
Hier ein Beispiel
PHP:
$a = 1;
func($a);
var_dump($a);    // gibt 1 zurück
funcWithRef($a);
var_dump($a);    // gibt 2 zurück

//Funktion ohne Referenz des Paramaters
function func($item){
    $item = $item +1;
}
//Funktion mit Referenz des Paramaters
function funcWithRef(&$item){
    $item = $item +1;
}
 
Zurück