moin moin,
ich hab in einem Programm das ich mit Delphi 7 programmiere(also es soll ein kleines Spiel werden) folgende Vorstellung wie es funktionieren soll:
- 4 Planeten
- 2 Spieler mit verschiedenen Werten(Rohstoffe, Militäreinheiten,...)
Jetzt bin ich dabei, dafür ein Object zu definieren:
Type
Planet = Object
Spieler1 : Record // Spieler1 = Mensch
{Variablen für
Rohstoffe, Miltär,
Wirtschaft,...}
End; // End Of Record
Spieler2 : Record // Spieler2 = Computergegner
{Variablen für
Rohstoffe, Miltär,
Wirtschaft,...}
End; //End Of Record
End; // End Of Object
Var
Planet_ : Array [1..4] Of Planet
dann möchte ich später das im folgenden Sinne verwenden:
Planet[1].Spieler[1].Gold := x;
oder
Planet[4].Spieler[1].Gold := y;
halt so, dass die Werte der Variablen vom Planeten, den der Spieler besitzt, abhängt, aber trotzdem beide einem Spieler zugeordnet sind...
Jetzt finde ich das aber unprofessionell dass ich die Variablen alle doppelt deklarieren muss. Also dachte ich an einen Array[1..2](Also dann Player[1].Gold zum Beispiel und Player2.Gold) des Records, aber das ist nicht möglich, bzw ich weiß nich wie man das programmiert...
Ich hoffe ich konnte meine Vorstellung einigermaßen klar darstellen.
Wäre nett wenn mir da jemand weiterhelfen könnte...
MfG KoRny Boy
Programmieren - alles kontrollieren 4.941 Themen, 20.715 Beiträge
Hi!
Du könnhtest das ganze obektorientiert angehen. Das tehma hatten wir ja schon. ;-)
Ich musste aber auch erstmal etwas nachdenken, aber ich denke, man bekommt das ohne zuviel Verrenkungen hin. :-)
Letzendlich ist es ja so, dass du mehrere Planeten hast und jeder Spieler hat Besitz auf einem oder emhrerern Planeten. Es liegt also nahe, den besitz in Klassen zu verwalten.
TypeGameBesitz: class
owner:longint; {Variablen für Rohstoff, Militär, Wirtschaft usw.}
end;
Die Platen wären dann ebenfalls eine Klasse (ich nenne sie jetzt einfach TypeGamePlanet) und würden als Attribut/Variable dann einen Array auf Instanzen von TypeGameBesitz enthalten. Am besten stattet man die Klasse mit Methoden/Funktionen aus, über die man auf Besitze von einzelen Spielern zugreifen kann.
Da könnte man dann z.B. GetBesitz(OwnerID) benutzen, um einen zeiger auf den besitz des Spielers OwnerID zurückzugeben. Mit PutBesitz(PointerAufBesitz) würde man dann einen Besitz neu speichern (er enthält ja einer Owner-Kennung, damit kann man dann feststellen, ob der Besitz für diesen Speiler schon vorhanden ist und dann ein entsprechendes Update durchführen).
Wenn man dann noch weitertreiben will, dann bildet man die einzelnen Variablen in TypeGameBesitz auch noch in Klassen ab. hier sollte man dann mit abgleiteten Klassen arbeiten, man verwendet also einen Basistyp und leitet dann die Klassen für Wirtschaft, Militär, Rohstoffe usw. von der Basisklasse ab. In TypeGameBesitz kann man dann wieder einen Array (oder eine andere Struktur einsetzen), um die BesitzInstanzen zu verwalten.
Bis dann
Andreas
Okay.....das werd ich mir dann mal in ruhe reinziehn...
Hab 1000 Dank
ich nehm an man schreibt sich mal wieder ;-)
Bis denn
KoRny Boy
hmmmmmmmmm.....
type TWirtschaft1 = Object
Menge,
Ertrag : Integer;
Kosten:Record
Energie,
Metall : Integer;
End; //End Of Record
End; // End Of TWirtschaft1
type TMilitaer1 = Object
AP : Integer;
Menge : LongInt;
End; // End Of TMilitaer1
type TPlanet = Object
Name,
Besitzer : String[20];
Metall,
Energie : LongInt;
Kernkraftwerk,
Metallmine : TWirtschaft1;
Raumsoldat,
Scharfschuetze,
Transportschiff,
Kriegsraumschiff,
Flugabwehrkanone,
Atombombe : TMilitaer1;
End; // End Of TPlanet
var
Planet : Array [1..4] Of TPlanet;
erst war TPlanet eine class....dann hatte ich irgendein problem damit und hab dann einfach mal "class" durch "object" ersetzt....der compiler schluckt das ;-) ....
@Andreas: ich glaub, dass das hier nicht deinen Ansätzen entspricht, aber irgendwie funktioniert das...aber ich kann mir vorstellen, dass ich das ziemlich unpraktisch mache......
ich wünsche also ein wenig kritik....was kann ich daran besser machen? oda @Andreas , kannst du das mit der class und so was ich nich so ganz gecheckt hab, an Hand dieser Vorlage irgendwie mir deutlich machen, ganz vllt, wenn du nochmal zeit dafür opfern könntest.......
also bis denn
KoRny Boy
Btw.: In der Aktuellen Form könntest Du auch einfach Object durch Record ersetzen (das wolltest Du ja oben wohl ursprünglich auch?)...
@borlander: ist das nur eine feststellung oder hätte das auch vorteile??
Hi!
Ich hab' im Moment leider kein Delphi oder Turbo-Pascal da, deshalb mache ich meine Beispiele mal aus dem Gedächtnis im TurboPascalformat. Ich nutze Records, damits nicht zu komplex wird (für den Anfang). Ja, es ist übrigends so, dass man RECORD durch OBJECT ersetzen kann. CLASS hat (glaube ich) eine leicht andere Syntax.
Ich würde mir einen Datensatz für die einzelnen Besitzvarianten erstellen. Das hat IMHO den Vorteil, dass man dann beim Verwalten mit allgemeinen Routinen auskommen kann, ohne dass man dabei dann sachen wie Milität oder Landwirtschaft unterscheiden muss.
Irgendwie werden die ganzen Dinge ja vergleichbar sein: man muss ein paar Werte verwalten, dass wird bei Milität und bei Landwirtschaft auch so sein.
TypeGameBesitz:record
TypeID:integer;
OwnerID:integer;
Desc:string;
Wert1:extended;
end;
In TypeID wird ein Wert eingetragen, der festlegt, um was es geht, am besten definiert man die Rypen als Konstanten:
const
ID_Militaer = 1;
ID_Landwirtschaft = 2;
ID_Energiewitschaft = 3;
ID_Kulturstand = 4;
Der Vorteil ist, dass du dann später recht einfach neue Typen hinzufügen kannst: an den eigentlichen Verwaltungsroutinen braucht man nichts zu ändern, nur die Auswertung muss erweitert werden.
Die OwnerID ist ein kleiner Kunstgriff im Voraus: da speichern wir die Nummer des Spielers ab, der dann diesen Besitz zugeordnet wird. Desc ist einfach eine Beschreibung, die sollte man auch als Konstante anlegen:
const
ID_DescMilitaer = 'Militär';
ID_DescLandwirtschaft = 'Landwirtschaft';
ID_DescEnergiewitschaft = 'Energiewirtschaft';
ID_DescKulturstand = 'Kultur';
OK, kommen wir zu den Planeten:
TypeGamePlanet:record
PlanetID:integer;
Desc:string;
besitz:array[1..20] of ^TypeGameBesitz;
end;
Das meiste ist schon bekannt: der Planet bekommt eine Kennung (Kennnummer) und eine Beschreibung. Würde ich wieder als Konstanten anlegen.
Die Besitztümer speichern wir einfach in einem Array ab. Die Beschränkung auf 20 Elemente ist jetzt willkührlich. Dassann man erweitern, sinnvoll wäre eigentlich eine variable Grösse, da kannst du dich ja austoben. ;-)
Im Prinzip braucht man jetzt noch ein paar Routinen zur Verwaltung des ganzen. fangen wir mit einer zur Initialisierung der Besitzthümer an.
Ich hoffe, ich komme mit der Systax für zeiger nicht durcheinander...
function InitGameBesitz(ID;Owner:interger; NewDesc:string; NewValue:Extended):^TypeGameBesitz;
begin
InitGameBesitz := new(TypeGameBesitz);
with InitGameBesitz^ do
begin
TypeID:0id,
OwnerID:=Owner;
Desc:=NewDesc;
Wert1:=NewValue;
end;
end;
Für den Planet muss man nun drei Funktionen schreiben:
1. Eine Init zum Initialisieren des Planeten mit seiner Nummer, der Beschreibung.
Hier sollte dann auch der Array gelöscht werden.
2. Eine Funktion zum Abspeichern oder ändern eines Besitzes.
Als Parameter würde die Funktion nur einen zeiger auf einen besitz bekommen. Mit dessen BesitzID (die den Typ des Besitzes festlegt) und der OwnerID kann man feststellen, ob der Spieler (OwnderID) bereits einen solchen Besitz auf dem Planeten hat, falls nein, wird er neu im Array gespeichert, falls ja, dann muss man den Eintrag austauschen.
3. Eine Funktion, die einen Besitz in ihrem Array sucht. Sie erwartet ebenfalls den BesitzTyp und die Nummer des Spielers. Sie durchsucht dann das Array und liefert NIL oder einen Zeiger auf den entsprechenden Besitz zurück.
Wie gesagt: der Vorteil ist, dass diese ganzen Verwaltungsroutinen dann unabhängig vom besitztyp funktionieren. Egal, ob das nun Militär oder Landwirtschaft ist.
Was so noch nicht geht, ist verschiedene Definition von Besitztypen parallel zu nutzen. dazu muss man dann an die Objekte ran. Das wäre aber auch nciht alzu schwer, da ich mit meinem "Plan" bereits eine typische Struktur erzeugt habe, die man dann recht einfach in Objekte überführen kann: es gibt feste Datentypen und Routinen, die nur einen speziellen datentyp bearbeiten können - aber es gibt noch keine formelle Verbindung zwischen diesen beiden Bestandteilen. das machen erst Objekte: die können dann neben variablen auch Prozeduren und Funktionen wie eine Vraiable aufnehmen. Die Deklaration des Besitzes als Objekt sieht dann so aus:
TypeGameBesitz:object
{Variablen des Objektes:}
TypeID:integer;
OwnerID:integer;
Desc:string;
Wert1:extended;
{Funktionen des Objektes:}
constructor Init(ID;Owner:interger; NewDesc:string; NewValue:Extended);
function GetValue:extended;
end;
constructor TypeGameBesitz.Init(ID;Owner:interger; NewDesc:string; NewValue:Extended)
begin
TypeID:=ID;
OnerID:=Owner;
Desc:=NewDesc;
Wert1:=NewValue;
end;
function TypeGameBesitz.GetValue:extended;
begin
GetValue:=Wert1;
end;
Eine neue Variable (bei Objekten spricht man von Instanz) legt man dann per New an:
var NewBesitz:^TypeGameBesitz;
NewBesitz:=new(TypeGameBesitz,Init(ID_Militaer, IDPlayerI1, D_DescMilitaer, 1.5));
Wenn man nun Wert1 aus der Waribake lesen will, dann kann man die Funktion nutzen:
var DummyE:extended;
DummyE:=NewBesitz^.GetValue;
So, dass reicht für Heute. ;-)
Ach ja, das Verwenden von abgekieteten Objekten:
Nur ein schnelles Beispiel, indem wir eine Klasse für eine Flotte anlegen:
TypeGameBesitzFlotte:object(TypeGameBesitz)
{Variablen des Objektes:}
TypeGameBesitz{Funktionen des Objektes:}
shipname:string;
constructor Init(ID;Owner:interger; NewDesc:string; NewValue:Extended; NewShipName:string);
end;
Den Construktor muss man entsprechend neu schreiben, er kann aber kann den Contructor der Parent-Klasse aufrufen:
constructor TypeGameBesitzFlotte.Init(...)
begin
{Erst die geerbten Variablen initialisieren:}
inherited Init(usw...);
{dann die eigene:}
shipname:=NewShipname;
end;
Später kann man in dieser Klasse dann auch die Funktionen oder Variablend es Vorgängers erreichen, also kann man GetValue ganz normal nutzen. Was auch eght, ist eine Variable vom tp TypeGameBesitzFlotte anzulegen und diese als Parameter an einen Wert zu übergeben,d er eigentlich vom Typ TypeGameBesitz sein müsste.
-> Die Routinen von TypeGamePlanet laufen also auch, wenn ich dort diese abgeleitete Version übergebe, man muss also9 dort nichts ändern!
Bis dann
Andreas
@Andreas:
Hmmmmmmmmmmmmmmmmmmm.......
Also ehrlich gesagt blicke ich langsam nicht mehr durch....Ich hab an diesem Board wohl doch nichts verloren....
Hab jetzt n Weg gefunden, er is zwar mühsam und umständlich, aber für mich durchschaubar.....
@All:
Aber danke für jeden Hilfeversuch....
MfG
KoRny Boy