Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!
Werbeanzeige
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
for(int Frame = 0; Frame < FutureFrames; Frame++) { if(cGS != MaxGS && Frame%5 == 0)//Nur jeden 5. Frame Tasten ändern, sonst sind die Routen zu ähnlich for(int i = cGS-1; i >= 0; i--) { if(!GS[i].Players[Me].Alive) continue; for(int j = 0; j < 6; j++) { if(GS[i].Players[Me].LastKeys == j) continue; GS[cGS] = GS[i]; GS[cGS].Players[Me].LastKeys = j; if(Frame == 0) GS[cGS].StartKeys = j; if(++cGS == MaxGS) goto Next; } } Next: for(int i = 0; i < cGS; i++) { if(!GS[i].Players[Me].Alive) continue; if(GS[i].CanPlayerShoot(You)) GS[i].Shoot(You)->PlayerOwner = -1;//damit der Gegner in unserer Vision ganz viel schießt (kein Schusslimit) GS[i].Move(Me, GS[i].Players[Me].LastKeys | K_Shoot, GS_.Players[You].LastKeys /*& ~K_Shoot*/); if(!GS[i].Players[Me].Alive && GS[i].FrameNo < GS[i].MinDieTime) GS[i].MinDieTime = GS[i].FrameNo; if(!GS[i].Players[You].Alive && GS[i].Players[You].RespawnTimer == 99) { if(GS[i].FrameNo > GS[i].MaxKillTime) GS[i].MaxKillTime = GS[i].FrameNo; } } } |
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
std::vector<Expression*> Ops(...); for(size_t i = 0; i < Ops.size();) { assert(Ops[i]->IsBoolean()); if(*Ops[i] == *Number(0)) return Number(0); if(*Ops[i] == *Number(1)) goto Erase; if(Ops[i]->Is<OpLogicalAnd>()) { Ops.insert(Ops.begin()+i+1, ((OpLogicalAnd*)Ops[i])->Ops.begin(), ((OpLogicalAnd*)Ops[i])->Ops.end()); goto Erase; } if(Ops[i]->Is<OpLogicalOr>()) { std::vector<Expression*>& OldOrs = ((OpLogicalOr*)Ops[i])->Ops; std::vector<Expression*> NewOrs(OldOrs.size()); for(size_t j = 0; j < OldOrs.size(); j++) { Ops[i] = OldOrs[j]; NewOrs[j] = LogicalAnd(Ops); } return LogicalOr(NewOrs); } //doppelt? for(size_t j = 0; j < i; j++) if(*Ops[i] == *Ops[j]) goto Erase; i++; continue; Erase: Ops.erase(Ops.begin()+i); } //... |
Wieso nicht? Meiner Meinung nach ist deine Funktion viel zu gross und zu unübersichtlich. Eine Aufteilung in 3 Funktionen, die natürlich passende Namen hätten, fände ich sowieso angebracht. Ich habe mal einen Vorschlag, aber ohne das konkrete Problem zu kennen, ist das nicht so einfach. Tatsache ist aber, dass das goto durch ein return ersetzt werden kann.Zitat von »"Helmut"«
Ne Auslagerung in eine Funktion ist auch nicht sonderlich sinnvoll.
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
void Function2(Parameter) { for(int i = cGS-1; i >= 0; i--) { if(!GS[i].Players[Me].Alive) continue; for(int j = 0; j < 6; j++) { if(GS[i].Players[Me].LastKeys == j) continue; GS[cGS] = GS[i]; GS[cGS].Players[Me].LastKeys = j; if(Frame == 0) GS[cGS].StartKeys = j; if(++cGS == MaxGS) return; //goto Next; } } } void Function3(Parameter) { for(int i = 0; i < cGS; i++) { if(!GS[i].Players[Me].Alive) continue; if(GS[i].CanPlayerShoot(You)) GS[i].Shoot(You)->PlayerOwner = -1; GS[i].Move(Me, GS[i].Players[Me].LastKeys | K_Shoot, GS_.Players[You].LastKeys /*& ~K_Shoot*/); if(!GS[i].Players[Me].Alive && GS[i].FrameNo < GS[i].MinDieTime) GS[i].MinDieTime = GS[i].FrameNo; if(!GS[i].Players[You].Alive && GS[i].Players[You].RespawnTimer == 99) { if(GS[i].FrameNo > GS[i].MaxKillTime) GS[i].MaxKillTime = GS[i].FrameNo; } } } void Function() { for(int Frame = 0; Frame < FutureFrames; Frame++) { if(cGS != MaxGS && Frame%5 == 0) Function2(Argumente); Function3(Argumente); } } |
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 |
Again: foreach(std::vector<bla*>, i, Bla) foreach(std::vector<dword>, j, (*i)->Blub) if(blubber(*j) == 0) { hui(*j); goto Again; } |
Das sehe ich anders. Wenn ich eine kleine Funktion habe, ist normalerweise auch die Schnittstelle (Parameter und Rückgabetyp) kleiner. Dadurch sieht man schneller, was die Funktion verändern kann, worauf sie Zugriff hat. Die Komplexität sinkt, die Funktion erhält einen genau definierten Aufgabenbereich. Const-Correctness kann härter angewandt werden, Exceptionsicherheit wird einfacher. Die Wartung wird erleichtert, da erstens Fehler besser eingeschränkt werden können und zweitens weniger Seiteneffekte vorhanden sind, auf die man bei einer Anpassung des Codes auch noch Rücksicht nehmen muss.Zitat von »"Helmut"«
@Nexus
Naja, einen Codeteil, der nur von einer Stelle aus aufgerufen wird, in eine Funktion auszulagern ist nicht sonderlich sinnvoll. Wenn man einen bestimmten Codeteil benennen will, genügt ein Kommentar. Ein Code mit vielen kleinen Funktionen kann nicht übersichtlicher sein, als das Äquivalent, bei dem die Funktionen so weit zusammengefasst sind, wie möglich.
Zitat von »"Nexus"«
Zum zweiten Code: Wäre es dort nicht möglich, die Elemente erst am Schluss zu entfernen? Das würde verschiedene Aufgaben trennen und wäre nebenbei noch performanter, da erase() in der Mitte von std::vector nicht gerade schnell läuft. Wenn ich das richtig sehe, könntest du damit die Komplexität von quadratisch auf linear herunterschrauben. Also eventuell zuerst die zu löschenden Elemente markieren oder - falls möglich - danach direkt die Löschbedingungen anwenden. Ganz elegant in Zusammenarbeit mit std::remove_if().
Zitat
Das sehe ich anders. Wenn ich eine kleine Funktion habe, ist normalerweise auch die Schnittstelle (Parameter und Rückgabetyp) kleiner. Dadurch sieht man schneller, was die Funktion verändern kann, worauf sie Zugriff hat. Die Komplexität sinkt, die Funktion erhält einen genau definierten Aufgabenbereich. Const-Correctness kann härter angewandt werden, Exceptionsicherheit wird einfacher. Die Wartung wird erleichtert, da erstens Fehler besser eingeschränkt werden können und zweitens weniger Seiteneffekte vorhanden sind, auf die man bei einer Anpassung des Codes auch noch Rücksicht nehmen muss.
Zudem ist es bei mir schon ab und zu vorgekommen, dass ich einen Teil einer Funktion sonst irgendwo gebraucht habe, und dann direkt die kleinere Funktion aufrufen konnte, anstatt Code zu duplizieren.
Werbeanzeige