Speicherreservierung ja/nein?
-
könntest du nicht einfach eine schleife und ein int-vector für die HP nehmen ?
[EDIT] ich beziehen mich hierbei noch immer auf die klasse/template Flotte die von der jeweiligen schiffsart ableitet (ein template würde sich hier wirklich hervorragend eignen)
for (vector<int>::iterator ITR = ShipArray.begin(); ITR != ShipArray.end();) { if (ZUFALLSSCHADEN > ITR->leftHP) { ITR = ShipArray.delete(ITR); } else { ITR->leftHP -= ZUFALLSSCHADEN; ITR++; } // Heißt soviel wie wenn zufällig erteilter schaden größer der verbleibenden HP // dann schiff zerstört ansonsten HP abziehen und iterator inkrementieren }so sparst du dir den unsinnig vergeudeten speicher der für jedes einzelne objekt nötig wäre und benutzt nur das bisschen speicher das pro schiffs eigenschaft nötig ist.
ZUFALLSSCHADEN berechnest du dir nach deinem verteilungschema oder wie auch immer ^^
-
Benutze einfach std::vector und lasse deine grauen Zellen an wichtigerem arbeiten.
Btw, musst du unbedingt die Schiffe aus dem Vector löschen? Reicht es nicht, alle Schiffe die Hp <= 0 haben, als tote Schiffe zu betrachten?
-
viande schrieb:
Edit: Speicher sollte in dieser Größenordnung kein Problem sein. Außer jedes Schiff sollte sein eigenes, persönliches Video erhalten . Ansonsten wirst du kaum mehrere Millionen Schiffe in deinem Spiel haben
Nene, Videos sind nicht enthalten. Es ist eine reine Simulation, wo nur Texte enthalten sind. Allerdings können durchaus 100000 Schiffe vorhanden sein.
@ Ceos: Ich kenne nicht alle Funktionen die vector liefert. ShipArray.delete();
löscht dies einfach das Elemt aus dem vector?@ DEvent: Klar, darüber könnte man vorher eine Abfrage machen. Bloß wenn ich schon extra dafür Speicher reservieren sollte, dann würde es ja auch Sinn machen, wenn ich diesen direkt wieder freigebe und das Schiff aus der Liste entferne. Oder sollte man den Speicher einfach komplett am Ende der Simulation freigeben.
-
ich hab mir da mal was ausgetüftelt und wollt mal deine meinung dazu wissen btw. die meinung der anderen zur effizienz (syntax und vollständigkeit sollen bitte vernachlässigt werden, da ich das nur einfach mal so geschrieben habe)
Ship.h
typedef struct { int HP; int Dmg; } TShipSpecs; class Ship { public: Ship(); ~Ship(); private: TShipSpecs ShipSpecifications; virtual void initSpecs(); };Ship.cpp
Ship::Ship() { initSpecs(); }Kreuzer.h
class Kreuzer : public Ship { public: Kreuzer(); ~Kreuzer(); void dealDmg(int Dmg); private: void initSpecs(); };Kreuzer.cpp
Kreuzer::Kreuzer() { super(); } void Kreuzer::initSpecs() { ShipSpecifications.HP = 100; ShipSpecifications.Dmg = 0; } void Kreuzer::DealDmg(int Dmg) { ShipSpecifications.Dmg += Dmg; }KreuzerVerband.h
class KreuzerVerband :: public Kreuzer { public: KreuzerVerband(int number); ~KreuzerVerband(); int Number; void dealGaussDmg(int Dmg); private: vector<TShipSpecs> ShipHPList; };KreuzerVerband.cpp
KreuzerVerband::KreuzerVerband(int number) { super(); Number = number; for (int i=0; i < Number; i++) { ShipHPList.push_back(Kreuzer::ShipSpecifications); } } void KreuzerVerband::dealGaussDmg(int Dmg) { for (vector<TShipSpecs>::iterator ITR = ShipHPList.begin();ITR != ShipHPList.end; ) { int dmgtodeal = Dmg - GAUSSFORMEL-ZUFALLSSCHADEN; Dmg -= dmgtodeal; ShipSpecifications = *ITR; dealDmg(dmgtodeal); if (ShipSpecifications.Dmg > ShipSpecifications.HP) { ITR = dmgtodeal.erase(ITR); Number--; } else { ITR++; } } }
-
es war nicht delete(iterator where) es war erase(iterator where)
[EDIT] sorry for doppelpost hab den falschen button gedrückt
-
Guten Morgen!
@ Ceos: Erst mal vielen Dank für die Mühe, die du dir gemacht hast!
Wie ich ja schon sagte, habe ich nur die Schiffsklasse (c_ship). Da jeder Schiffstyp die selben Fähigkeiten und Eigenschaften hat (halt nur andere Werte), ist es nicht nötig, dass ich für jeden Schiffstyp eine eigene abgeleitete Klasse schreiben muss. Vor allem würde dies, zumindest für mich, sehr unübersichtlich werden, da ich insgesamt über 15 Schiffstypen habe, wo nochmals über 20 Verteidigungsanlagen hinzu kommen. Das würde ja bedeuten, dass ich zusätzlich ca. 60 Dateien in meinem Projekt zu verwalten hätte.
Das mag sicherlich für große Projekte nicht viel sein, doch denke ich dass dies hier nicht nötig ist.
Ich war am überlegen, um einen Verband von mehreren Schiffen eines Typs zu erstellen, eine zusätzliche Klasse (c_fleet) zu erstellen.
In dieser Klasse werden einfach vectoren des jeweiligen Schiffstyps zur Verfügung gestellt.// c_fleet.hpp #inlcude "c_ship" #include <vector> class c_fleet { private: std::vector<c_ship> Kreuzer; std::vector<c_ship> Schlachtschiff; // usw. public: c_fleet(); ~c_fleet(); };// c_fleet.cpp c_fleet::c_fleet(int Kreuzer, int Schlachts, // usw...) { c_ship cKreuzer("Kreuzer") for(int i = 1; i < Kreuzer; i++) { Kreuzer.push_back(cKreuzer); } // für jeden Typ erneut }Wäre das eine annehmbare Möglichkeit?
Gruß Spartaner
-
Wenn die Schiffe alle technisch identisch sind, reicht eigentlich ein vector aus, um alle unterzubringen. Das dürfte es dann auch leichter machen, Flächeneffekte darzustellen, die die gesamte Flotte betreffen. Aber da stellt sich dann letztendlich die Design-Frage: Wie soll das Schießen gesteuert werden?
(schießt du "irgendwo in die gegnerische Flotte rein", "auf ein beliebiges Typ-X Schiff", "auf GENAU DIESES Schiff",...? oder hast du eventuell Waffen, die mehrere Schiffe gleichzeitig treffen können?)
-
Zum Entfernen aus Vectoren nach bestimmten Kriterien empfiehlt sich remove_if in Verbindung mit erase
-
@ THX 1138: Das werde ich mir direkt mal ansehen, Danke!
CStoll schrieb:
Wenn die Schiffe alle technisch identisch sind, reicht eigentlich ein vector aus, um alle unterzubringen
Diesen Gedanken hatte ich auch schon gehabt. Bloß stelle ich es mir etwas unübersichtlich vor, wenn in meinem vector die Elemente 1 bis 50 Kreuzer sind, die Elemente 50 bis 67 sind Schlachtschiffe usw.
Aber da stellt sich dann letztendlich die Design-Frage: Wie soll das Schießen gesteuert werden?Die Funktion zur Berechnung des Schadens werde ich noch in die Klasse der Waffen einfügen.
Das Schießen an sich läuft wie folgend ab. Jede Waffe hat ihr Lieblingsziel (Prioritätenliste). Jetzt geht die Waffe meines Schiffes diese Liste durch und vergleicht sie mit den Schiffen der gegnerischen Flotte. Der Schiffstyp der als erstes in der Liste vor kommt, wird unter beschuß genommen.
Dazu wird zunächst der Schaden ermittelt, den die Waffe anrichtet und dann wird dieser auf alle Schiffe der gegnerischen Flotte (des angegebenen Schiffstyps) verteilt (nach der Normalverteilung). So werden dann alle Waffen aller Schiffe durchgegangen. Ist die Berechnung des Schadens und der Treffer dann bei allen Schiffen geschehen, werden die zerstörten Schiffe aus der Flotte "gestrichen", so dass dann in der nächsten Runde die entsprechend geringere Anzahl an Schiffen vorhanden ist.
-
naja son ungleich sind deine und meine idee gar nicht, nur das ich dabei des speichers wegen nicht ganze instanzen sondern eher nur die statuswerte die verändert werden könnten in vektoren packen wollte, des speichers wegen
... bis 100000 Schiffe ...
[EDIT] Mühe warr das kein :p war ja nur n gedankenspiel .... soll das eventuell nen OGamesimulator oder was verwandtes werden ? wenn ich deine schiffsklassen und die anzahl der arten so anseh erinnert mich das stark daran ;p
-
Ceos schrieb:
soll das eventuell nen OGamesimulator oder was verwandtes werden ? wenn ich deine schiffsklassen und die anzahl der arten so anseh erinnert mich das stark daran ;p
Es wird ein Kampfsimulator für Horizon (ein anderes Browsergame). Ich hab ja früher nie was von Browsergames gehalten. Aber wie dann immer mehr von meinen Arbeitskollegen damit angefangen haben, hab ich mir das auch mal angesehen und bin jetzt seit knapp 7 Monaten dabei.
-
Spartaner schrieb:
CStoll schrieb:
Wenn die Schiffe alle technisch identisch sind, reicht eigentlich ein vector aus, um alle unterzubringen
Diesen Gedanken hatte ich auch schon gehabt. Bloß stelle ich es mir etwas unübersichtlich vor, wenn in meinem vector die Elemente 1 bis 50 Kreuzer sind, die Elemente 50 bis 67 sind Schlachtschiffe usw.
Ach, so schwer ist das auch wieder nicht. Dazu mußt du die Schiffstypen nur geordnet (z.B. nach Maximal-Hitpoints oder nach Schiffstyp) in den Vektor reinpacken und kannst dir dann per equal_range() einen bestimmten Flottenteil raussuchen lassen (z.B.
equal_range(ships.begin(),ships.end(),"Kreuzer")liefert alle Kreuzer deiner Flotte.Die Funktion zur Berechnung des Schadens werde ich noch in die Klasse der Waffen einfügen.
Das Schießen an sich läuft wie folgend ab. Jede Waffe hat ihr Lieblingsziel (Prioritätenliste). Jetzt geht die Waffe meines Schiffes diese Liste durch und vergleicht sie mit den Schiffen der gegnerischen Flotte. Der Schiffstyp der als erstes in der Liste vor kommt, wird unter beschuß genommen.
Dazu wird zunächst der Schaden ermittelt, den die Waffe anrichtet und dann wird dieser auf alle Schiffe der gegnerischen Flotte (des angegebenen Schiffstyps) verteilt (nach der Normalverteilung). So werden dann alle Waffen aller Schiffe durchgegangen. Ist die Berechnung des Schadens und der Treffer dann bei allen Schiffen geschehen, werden die zerstörten Schiffe aus der Flotte "gestrichen", so dass dann in der nächsten Runde die entsprechend geringere Anzahl an Schiffen vorhanden ist.Auch eine Möglichkeit - und mit einem vector recht gut umsetzbar:
vector<string> m_prio;//Namen der "Lieblingsgegner" in fallender Reihenfolge pair<vector<c_ship>::iterator,vector<c_ship>::iterator> ship_range; for(vector<string>::iterator pos=m_prio.begin();pos!=m_prio.end();++pos) { ship_range = equal_range(ships.begin(),ships.end();*pos); if(ship_range.first!=ship_range.second()) break; } for(vector<c_ship>::iterator tgt=ship_range.first;tgt!=ship_range.second;++tgt) attack(*tgt);
-
CStoll schrieb:
Ach, so schwer ist das auch wieder nicht. Dazu mußt du die Schiffstypen nur geordnet (z.B. nach Maximal-Hitpoints oder nach Schiffstyp) in den Vektor reinpacken und kannst dir dann per equal_range() einen bestimmten Flottenteil raussuchen lassen (z.B. equal_range(ships.begin(),ships.end(),"Kreuzer") liefert alle Kreuzer deiner Flotte.
Das klingt interessant. Liege ich da richtig, dass diese Funktion einfach den letzten Eintrag im vector zurückliefert? Wenn z.b. bis zum Element 50 Kreuzer enthalten sind, so soll die Funktion eine 50 zurückliefern?
pair<vector<c_ship>::iterator,vector<c_ship>::iterator> ship_range;Das verstehe ich nicht richtig. Ist dass so eine Art "Doppel-vector"? Könntest du mir deinen Codeschnipsel vielleicht etwas genauer erklären?
-
Schau dir mal equal_range an
equal_range liefert ein pair Iteratoren zurück, die den Bereich der Schiffe abdecken, die dem gewünschten Namen entsprechen. Also vom ersten bis eine nach dem letzten
Dieser Range wird in der zweiten Schlaufe durchiteriert.PS: Nein ich habe keine Aktien von SGI...
-
Spartaner schrieb:
CStoll schrieb:
Ach, so schwer ist das auch wieder nicht. Dazu mußt du die Schiffstypen nur geordnet (z.B. nach Maximal-Hitpoints oder nach Schiffstyp) in den Vektor reinpacken und kannst dir dann per equal_range() einen bestimmten Flottenteil raussuchen lassen (z.B. equal_range(ships.begin(),ships.end(),"Kreuzer") liefert alle Kreuzer deiner Flotte.
Das klingt interessant. Liege ich da richtig, dass diese Funktion einfach den letzten Eintrag im vector zurückliefert? Wenn z.b. bis zum Element 50 Kreuzer enthalten sind, so soll die Funktion eine 50 zurückliefern?
Nein, equal_range liefert nicht die Anzahl der gefundenen Elemente, sondern ein Paar von Iteratoren - d.h. ship_range.first zeigt auf den ersten Kreuzer deiner Flotte, ship_range.second auf den ersten Nicht-Kreuzer.
Edit@THX: Das heißt übrigens immer noch "Schleife"

-
CStoll schrieb:
Edit@THX: Das heißt übrigens immer noch "Schleife"

Uups, sch**ss Helvetismen.
-
@ DEvent: Klar, darüber könnte man vorher eine Abfrage machen. Bloß wenn ich schon extra dafür Speicher reservieren sollte, dann würde es ja auch Sinn machen, wenn ich diesen direkt wieder freigebe und das Schiff aus der Liste entferne. Oder sollte man den Speicher einfach komplett am Ende der Simulation freigeben.
Wenn du den Speicher in der Simulation freigibst, bringt das nur: a) extra Verwaltungsaufwand und b) Geschwindigkeitsnachteile.
Aus a) folgt, das der Algorithmus unnötig verkompliziert wird und dadurch nochmal fehleranfälliger und langsamer wird.
Was anderes wäre, wenn du in der Simulation Speicher anforderst, dann würde der Speicher unnötigerweise immer weiter zunehmen.
Aber auch dann könnte man die "Leichen" drinnerlassen, bis zu einem Maximalwert, und dann einen Algorithmus starten, der die "Leichen" aus dem Speicher entfernt.
Würde den Vorteil bringen, das es 2 Algorithmen sind, einen für die Simulation, einer für die Speicherverwaltung.
-
Danke noch mal für die Hilfe!
Mit den Informationen werde ich jetzt erst mal weiter machen.
Gruß Spartaner
-
pair<vector<c_ship>::iterator, vector<c_ship>::iterator> ship_range; ship_range = equal_range(ships.begin(),ships.end(),"Kreuzer")Ich habe hiermit noch ein kleines Problem. Wenn ich dies so nutzen möchte, bekomme ich den Fehler, dass er string nicht nach c_ship (meine Klasse) konvertieren kann. Das ist ja auch irgendwie verständlich und logisch. Die deklaration des Schiffstyps ist zwar in der Klasse vorhanden, aber mit ships.begin() .end() überprüfe ich ja ein ganzes Objekt der Klasse c_ship und nicht nur eine einzelne Membervariable.
Kann ich den Vergleich so nicht machen oder habe ich mir die definition von equal_range nicht richtig angesehen und mache da einen großen Fehler?pair<vector<c_ship>::iterator, vector<c_ship>::iterator> ship_range; c_ship Kreuzer("Kreuzer"); ship_range = equal_range(ships.begin(),ships.end(), Kreuzer)Übergebe ich der Funktion jetzt einfach ein Schiff, nach welchem er in dem vector suchen soll, so bekomme ich folgenden Fehler (wenn ich es noch richtig wiedergeben kann):
_function_base.h(73) operator '<' ist im Typ c_ship für Argumente desselben Typs nicht implementiert.
Ich verstehe einfach nicht wie dieser Fehler zustande kommt. Könnt ihr mir dabei noch mal helfen?
Gruß Spartaner
-
Ich hoffe es ist in Ordnung *push*
