Objekte ohne Namen erstellen?
-
Hallo,
Ich habe ich gefragt, ob man Objekte auch ohne Objektnamen erstellen kann.
Beispiel:Ich möchte in einem Spiel 100 Gegner erscheinen lassen...
Dann möchte ich ja nicht in meinem Code schreiben:Gegner g1;
Gegner g2;
...
Gegner g100;Ich möchte also viele Objekte mit einer Schleife erstellen, ohne jeden einzelnen einen Namen zu geben. (natürlich bekommen sie über den Konstruktor dann eine ID)
Könnt ihr mich erklären wie man das geschickter löst? Oder eventuell ein Stichwort geben, über das ich mich informieren kann?
-
Hallo Haolong
Das Stichwort ist "Array":
Enemy enemies[100]; // erstelle 100 Gegner mit den Indizes 0 bis 99 inklusive enemies[3].attack(); // der vierte (!) Gegner soll angreifen
Die ID, die dir vorgeschwebt hat, ist hinfällig; der Index (=Platznummer) reicht zur Identifikation aus.
Wenn du dann etwas für alle 100 Gegner machen möchtest, nutzt du eine Schleife:
for(int i = 0; i < 100; ++i) enemies[i].revive();
LG
PS: Ich würde dir empfehlen, alle Namen auf Englisch zu machen.
-
Fytch schrieb:
Das Stichwort ist "Array":
Ich würde eher auf das Stichwort
std::vector
verweisen. Die Anzahl der Gegner ist ja nicht fest, dann kannst du bei Bedarf mehr oder weniger Gegner haben.
-
Danke schon mal für die Hilfen aber irgendwie klappt das noch nicht ganz so wie ich möchte.
Zu meinem Fall:
Ich versuche ein Schachspiel zu programmieren. Dafür habe ich zwei Klassen erstellt.
-Schachfeld
-PositionDas Schachfeld soll in einem Array(oder auch Vector) alle 64 Positionen (Kacheln) gespeichert haben.
Durch eine Abfrage von statischen Variablen der Klasse Position bekommt jede Position im Konstruktor einen x-Wert und einen y-Wert zugewiesen.
Im Versuch mit dem Array sah das Ganze dann so aus:
//Spielfeld.cpp #include "Spielfeld.h" Spielfeld::Spielfeld() { } Spielfeld::~Spielfeld() { }
//Spielfeld.h #pragma once class Spielfeld { public: Position Positionen[64]; Spielfeld(); ~Spielfeld(); };
//Position.cpp #include "Position.h" Position::Position() { pos_x = counter_x; pos_y = counter_y; if (counter_x <= 6) { counter_x++; } else { counter_x = 0; counter_y++; } } Position::~Position() { } int Position::getPos_x() { return pos_x; } int Position::getPos_y() { return pos_y; } int Position::counter_x = 0; int Position::counter_y = 0;
//Position.h #pragma once class Position { private: static int counter_x; static int counter_y; int pos_x; int pos_y; public: Position(); ~Position(); int getPos_x(); int getPos_y(); };
Erstelle ich damit schon die Objekte? Ich glaube nicht, denn der Konstruktor von Position wird nicht aufgerufen.
Was fehlt mir denn dafür noch?
-
Das passt schon so, vermutlich fehlt dir schlicht ein Schachfeld-Objekt.
Und bitte keine Destruktoren explizit anlegen, wenn du sie nicht brauchst. Was die static pos_x/pos_y bezwecken sollen, ist mir auch nicht ganz klar.
-
Danke schon mal für die Hilfen aber irgendwie klappt das noch nicht ganz so wie ich möchte.
du machst das viel zu kompliziert
//8x8=64 Felder constexpr size_t MAX_X = 8; constexpr size_t MAX_Y = 8;
entweder
position spielfed[MAX_X][MAX_Y]
und dann einfach
positon& pos = spielfeld[3][4];
oder
position spielfed[MAX_X*MAX_Y]; position& get_position(x,y) { assert(x >= 0 && x < MAX_X); assert(y >= 0 && y < MAX_Y); return fields[y*MAX_Y+x]; }
das ganz geht auch mit vector - falls du dynamische Spielfeldgroessen haben willst?
std::vector<std::vector<position>> spielfeld(MAX_X, std::vector<position>(MAX_Y));
und dann auch wieder
position& pos = spielfeld[3][4];
dein static Zeug ist total sinnfrei und nutzlos - du löst mit viel Code ein Problem das gar nicht existiert technisch besonders umständlich
-
Ich würde ein std::array<std::array<Feldinfo, 8>, 8> als Schachbrett nehmen.
Und Feldinfo wäre eine Enumeration, in der empty vorkommt und jede Figur.
Dann könnte man Funktionen mit Templatespezialisierung nutzen, um mit den Feldinfos zu arbeiten.
-
Dann könnte man Funktionen mit Templatespezialisierung nutzen, um mit den Feldinfos zu arbeiten.
was auch immer du damit sagen möchtest - Beispiel?
-
Bin gerade am Handy, tut mir leid. Später, ok?
-
Das mit dem Schachspiel ist so eine typische Interviewfrage: man sollte es besser nicht zu kompliziert machen!
Ich möchte hier ein einfaches 1d-Array vorschlagen. Und zwar, wie wir es hier vor kurzem in einem anderen Thread hatten, würde ich "oben" und "unten" je 2 Extrazeilen mit ungültigen Feldern einfügen und links und rechts vom Feld je eine zusätzliche Spalte, d.h. in 1d hat man dann erst 2x10=20 ungültige Felder, dann noch 1 ungültiges Feld am Rand, dann, 8 gültige, wieder 2 ungültige usw.
So sähe das Brett so aus:
uuuuuuuuuu uuuuuuuuuu uRNBQKBNRu uPPPPPPPPu u--------u u--------u u--------u u--------u uppppppppu urnbqkbnru uuuuuuuuuu uuuuuuuuuu
Mit Großbuchstaben=Schwarze Figuren, u=ungültig, -=leer, Kleinbuchstaben=weiß
Insgesamt also 120 Felder als 1d-Array. Vorteil dieser Darstellung ist, dass man z.B. Springerbewegungen durch eine einzige Addition oder Subtraktion darstellen kann, und der Test, ob der Zug überhaupt geht, ist dann einfach, dass das Feld != u sein muss (ok, man muss dann noch testen, ob der König dadurch im Schach stehen würde). Bei Turm und Läufer hat man je 4 Richtungen und man addiert/subtrahiert einfach so lange, bis man auf eine Figur oder den Rand (u) trifft.
Ich weiß nicht, wie das in modernen Schachprogrammen implementiert ist, aber ich denke, dass dies ein brauchbarer Ansatz wäre. Viel schwieriger als die erlaubten Züge zu finden ist es sowieso, eine anständige Bewertungsfunktion zu schreiben sowie wahrscheinlich gute Züge in der Suche möglichst als erstes zu finden.
-
wob schrieb:
Ich weiß nicht, wie das in modernen Schachprogrammen implementiert ist, aber ich denke, dass dies ein brauchbarer Ansatz wäre. Viel schwieriger als die erlaubten Züge zu finden ist es sowieso, eine anständige Bewertungsfunktion zu schreiben sowie wahrscheinlich gute Züge in der Suche möglichst als erstes zu finden.
Die führenden Schachprogramme heutzutage nutzen ausschließlich Bitboards (=
std::uint64_t
). Dabei macht man sich zunutze, dass die 64 Felder eines Schachbretts gerade schön in ein Register eines x86_64-Prozessors passen. Man nutzt je ein Bitboard pro Figurentyp und eins für Schwarz (Läufer & Schwarz == SchwarzeLäufer).