AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi 6-Dimensionale Baumstruktur - Spielfeld
Thema durchsuchen
Ansicht
Themen-Optionen

6-Dimensionale Baumstruktur - Spielfeld

Ein Thema von Tormentor32 · begonnen am 25. Sep 2006 · letzter Beitrag vom 28. Sep 2006
Antwort Antwort
Benutzerbild von Tormentor32
Tormentor32

Registriert seit: 27. Okt 2005
Ort: Düsseldorf
369 Beiträge
 
Delphi XE5 Professional
 
#1

6-Dimensionale Baumstruktur - Spielfeld

  Alt 25. Sep 2006, 12:30
Hallo Leute, ich habe ein Problem bei einem kleinen Spiel, welches ich grade Programmiere.

Es gibt ein Spielfeld, welches aus 6-Ecken besteht, jedes Feld hat entweder Farbe 1 oder Farbe 2.
Wenn man auf ein Feld klickt, dann änder sich die Färbe des Feldes, auf das man geklickt hat, und Die Farben aller benachbarten Felder.

Mein Problem ist folgendes:

Beim erstellen der Felder entstehen manche Felder doppelt, denn wenn ich vom Mittelpunkt aus nach oben und dann nach obenrechts gehe, oder erst nach obenrechts und dann nach oben, erhalte ich die gleichen Felder, sie werden also doppelt erstellt.

Über eine Variable wird die Anzahl der Ebenen angegeben, dh. wieviele "Kreise" sich um den Mittelpunkt ziehen => Je mehr Ebenen ich habe, desto mehr überflüssige Felder weden erstellt. Ich habe das Überflüssige Felder erstellen bereits ein wenig eingedömmt durch eine überprüfung, ob der Direkte Nachbar auch ein Feld ist, oder nil ist.

Ich weiß allerdings nicht, wie ich das über Mehrere Ebenen hinkrigen soll, es muss da doch sicher einen bestimmten algorhytmus geben oder?

Gruß richard
Richard Mahr
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#2

Re: 6-Dimensionale Baumstruktur - Spielfeld

  Alt 25. Sep 2006, 12:39
Hi und herzlich Willkommen in der DP

Nur weil ich mir noch nicht sicher bin, ob ich alles verstanden habe, frage ich mal nach:
Du hast ein Spielfeld dass 6 Ecken hat? Oder besteht das Spielfeld aus Feldern, die jeweils 6 eckig sind?

Ein Feld solltest du als den Mittelpunkt betrachten. Jedes Feld hat dann einfach 6 Nachbarn. Diese Nachbar sind allerdings nur Referenzen (Zeiger auf die Nachbarn). So kannst du dann anfangen dein Feld aufzubauen. Wichtig ist, dass diese Regel dann für die äussersten Felder nicht gelten kann.
Um hier jetzt sagen zu können, wie du am einfachsten dein ganzes Feld erzeugst, musst du allerdings angeben, wie die Größe des Feldes festgelegt wird, wie das Spielfeld also aufgebaut ist (wieviele Felder, wie angeordnet) und kann man die Größe manuell anpassen oder ist die fest?

Gruß Der Unwissende

[Add]
noch ein wenig nachgedacht, ich denke es jetzt so zu verstehen, du hast ein Sechseck und um dieses sechseck herum hast du sechs weitere, jetzt wächst du nach aussen, oder? Also hast jetzt wieder jedes von diesen sechs Nachbarn.
Jedes solches Feld solltest du einfach in einer Struktur speichern, die sich ihre sechs nachbarn (Referenz/Zeiger) merken kann. Nun fängst du mit einem Element an. Am Anfang gibt es nur dieses Feld, du schaust dir jetzt alle 6 Nachbarn an, ist einer dieser Nachbarn noch unbekannt (= nil), so erzeugst du den Nachbarn und weißt hier beiden Feldern den Zeiger auf den jeweiligen Nachbarn zu. Alle Felder speicherst du dabei in einer Liste, bis du die gewünschte Anzahl von Feldern hast.
Wichtig ist, dass du dir auch immer merkst, welche Felder noch nicht komplett fertig sind (da fehlen dann die Nachbarn).
Ist die gewünschte Anzahl von Elementen erreicht, setzt du hier keine neuen Nachbarn mehr ein.

Hoffe es ist halbwegs klar wie ich das meine
[/ADD]
  Mit Zitat antworten Zitat
Benutzerbild von Tormentor32
Tormentor32

Registriert seit: 27. Okt 2005
Ort: Düsseldorf
369 Beiträge
 
Delphi XE5 Professional
 
#3

Re: 6-Dimensionale Baumstruktur - Spielfeld

  Alt 25. Sep 2006, 13:03
Ein Feld sieht folgendermaßen aus:

Delphi-Quellcode:
TFeld = Class(TObject)
    FFarbe: TColor;

    FEbene: integer;

    FIdentNr: string;
    FPosition: TPoint;

    Image: Timage;

    FFelder: Array[1..6] of TFeld;
    FParent: TFeld;

    FIndex: integer;
    procedure Initialisiere(Ebene,Nummer: integer; const EbeneMax: integer; Parent: TFeld;Position: TPoint);
end;
Jedes feld hat wie du gesagt hast 6 Nachbarn. Das erste Feld ist in der Mitte auf der Ebene 0.
in der Prozedur "Initialsiere" wird 1 Feld erstellt, und anschließend von jedem Nachbar die Prozedeur "Initialsiere" erneut rekursiv aufgerufen und die Ebene erhöht, bis sie den gewünschten Wert erreicht hat.

Am Anfang hatte ich noch gar keine Überprüfung, das heißt es wurden 6^Ebenen Felder erstellt.

Da ich noch nicht viel mit Rekursion zu tun hatte, weiß ich nicht, wie ich auf ein bestimmtes feld zugreifen kann. Daraus folgt, dass ich schlecht überprüfen kann, ob zwei verschiedene Wege zum selben Feld führen, und somit das Feld doppelt erstellt wird.
Richard Mahr
  Mit Zitat antworten Zitat
Cöster

Registriert seit: 6. Jun 2006
589 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: 6-Dimensionale Baumstruktur - Spielfeld

  Alt 25. Sep 2006, 15:02
was ist daran denn jetzt 6-dimensional?
  Mit Zitat antworten Zitat
Benutzerbild von Tormentor32
Tormentor32

Registriert seit: 27. Okt 2005
Ort: Düsseldorf
369 Beiträge
 
Delphi XE5 Professional
 
#5

Re: 6-Dimensionale Baumstruktur - Spielfeld

  Alt 25. Sep 2006, 15:58
Zitat von Cöster:
was ist daran denn jetzt 6-dimensional?
Jedes Feld zeigt auf 6 weitere Felder des gleichen Typs
Richard Mahr
  Mit Zitat antworten Zitat
Benutzerbild von Tormentor32
Tormentor32

Registriert seit: 27. Okt 2005
Ort: Düsseldorf
369 Beiträge
 
Delphi XE5 Professional
 
#6

Re: 6-Dimensionale Baumstruktur - Spielfeld

  Alt 28. Sep 2006, 12:30
So, ich habe das Konzept verworfen und ein neues gemacht, dabei habe ich aber auch wieder ein Problem

Ich habe ein Klasse TFeld und drei Unterklassen TMittelFeld, THauptFeld und TKindFeld

Delphi-Quellcode:
  TFeld = class(Tobject)
    FKoordinate: TPunkt;
    FFarbe: integer;
    image: Timage;
    constructor create;
  end;

    TKindFeld = class(TFeld)
      FNextKindFeld: TKindFeld;
      FLetzter: boolean;
      procedure inititialisiere(Ader,Ebene,Index: Integer; Letzter: Boolean);
    end;
    THauptFeld = class(TFeld)
      FKindFeld: TKindFeld;
      FNextHauptFeld: THauptFeld;
      FLetzter: boolean;
      procedure initialisiere(Ader,Ebene: integer; Letzter: Boolean);
    end;

    TMittelFeld = class(TFeld)
      FHauptFelder: array[1..6] of THauptFeld;
      procedure initialisiere;
    end;
Die Prozedur TMittelFeld.initialisiere erstellt ein Feld über create, welches die Mitte darstellt
und anschließend 6 Felder vom Typ THauptFeld über die prozedur THauptFeld.initialisiere, die im array FHauptFelder gespeichert sind.

Das Problem ist, dass die Variable

Mitte: TMittelFeld;

nach der Prozedur

Mitte.initialisiere

wieder auf nil zeigt, nur in der Prozedur selbst kann ich auf sie zufreifen, und wenn die Prozedur fertig ist, und ich darauf zugreifen will, kommt die Fehlermeldung

"Zugriffsverletzung"

da Mitte wieder den Wert "nil" hat.

Wie kriege ich es hin, dass die variable auch nach der initialisierung immer noch den Wert hat, und nicht wieder auf nil zeigt?

vielen dank schonmal

MFG Richard
Richard Mahr
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#7

Re: 6-Dimensionale Baumstruktur - Spielfeld

  Alt 28. Sep 2006, 13:02
Ohne Code kann man dazu weniger als nichts sagen, also stelle ich dir mal mein Konzept vor:

Du hast eine Methode BuildNodes oderwieauchimmer, die das nördlichste bzw. östlichste - je nachdem, wie dein Spielfeld ausgelegt ist - Feld, die zu erzeugende Ebenennummer und die maximale Ebene entgegennimmt. Die Methode wandert nun ausgehend vom nördlichsten Element einmal am Rand herum und erzeugt die nächsten Felder. Dabei werden neu erzeugte Felder sofort mit dem zuvor erzeugten und dem bisherigen Rand verbunden, das letzte Element muss natürlich zusätzlich mit dem zuerst erzeugten verbunden werden. Nun kannst du ganz einfach die Methode mit dem neuen nödlichsten Feld und der inkrementierten Ebenennummer rekursiv aufrufen, die Abbruchbedingung sollte klar sein .
Mit dieser Methode benötigst du keine weitere Liste außer den Referenzen in den Feldern selbst, auch ist eine Klasse für alle Felder vollkommen genügend.
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
Benutzerbild von Tormentor32
Tormentor32

Registriert seit: 27. Okt 2005
Ort: Düsseldorf
369 Beiträge
 
Delphi XE5 Professional
 
#8

Re: 6-Dimensionale Baumstruktur - Spielfeld

  Alt 28. Sep 2006, 13:17
Hi!

Ich gehe Sternförmig vom Mittelpunkt aus nach außen.

Delphi-Quellcode:
//Mittelpunkt des Spielfeldes
procedure TMittelFeld.Initialisiere;
var i: integer;
begin
  self := TMittelfeld.Create;
  self.image.Left := Mittelpoint.X;
  self.image.Top := Mittelpoint.Y;
  self.image.Show;
  self.FKoordinate := MittelPunkt;
  FrmMain.SechsEck(self.image.Canvas,breite div 2,0,breite);
  for i := 1 to 6 do
    begin
      // Abarbeitung der 6 Zweige
      self.FHauptFelder[i].{HauptFeld}Initialisiere(i,1,false);
    end;
end;
Es wird 6 mal, also für jede Kante des Sechseck, die Prozedur

Delphi-Quellcode:
procedure THauptFeld{TFrmMain}.{HauptFeld}Initialisiere({Feld: THauptFeld;}Ader,Ebene: integer; Letzter: Boolean);
var bHilf: Boolean;
begin
  self := THauptFeld.Create;

  self.FKoordinate.Ader := Ader;
  self.FKoordinate.Ebene := Ebene;
  self.FKoordinate.Index := 0;

  self.image.Left := FrmMain.PunktToPoint({Feld}self.FKoordinate).X;
  self.image.Top := FrmMain.PunktToPoint({Feld}self.FKoordinate).Y;

  self.image.Show;

  FrmMain.SechsEck({Feld}self.image.Canvas,breite div 2,0,breite);
  self.image.Canvas.TextOut(breite div 2,2,inttostr(ader)+ ' '+inttostr(Ebene)+' 0');
  self.Fletzter := Letzter;
  bHilf := ((ebene+1) >= AnzahlEbenen);

  if not self.FLetzter
    then
      self.FNextHauptFeld.Initialisiere(ader,Ebene+1,bHilf);

  bHilf := (ebene = 2);
  if (ebene > 1)
    then
      self.FKindFeld.inititialisiere(Ader,Ebene,1,bHilf);
end;
Sie erstellt Hauptfelder, die Auf ein nächstes Hauptfeld, sowie auf ein Kindfeld zeigen, Es werden n Hauptfelder erzeugt, wobei n die Anzahl an Ebenen ist, also Kreisen, die sich um den Mittelpunkt herumziehen. Die "KindFelder" füllen die Zwischenräume zwischen den 6 "Adern" der Mitte, also die verlängerten Seiten, die aus Hauptfeldern bestehen.

Das Problem ist wie gesagt, dass die Felder nach der Prozedur wieder alle nil sind.

MFG richard
Richard Mahr
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#9

Re: 6-Dimensionale Baumstruktur - Spielfeld

  Alt 28. Sep 2006, 13:43
self := TMittelfeld.Create; Was willst du damit erreichen? So geht es jedenfalls auf keinen Fall. So in etwas schon eher:
Delphi-Quellcode:
Mitte := TMittelFeld.Create;
Mitte.Initialize;
DoSomething;


Mitte.Free;
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
Benutzerbild von Tormentor32
Tormentor32

Registriert seit: 27. Okt 2005
Ort: Düsseldorf
369 Beiträge
 
Delphi XE5 Professional
 
#10

Re: 6-Dimensionale Baumstruktur - Spielfeld

  Alt 28. Sep 2006, 14:08
Ich bin doch an der Stelle in der Prozedur von Mitte, also müsste das self sich doch auf Mitte beziehen oder?


edit: Juhu! Ich habs endlich hingekriegt, ich habe einfach einen Weiter Parameter übergeben, der das Feld angibt! Danke für die Hilfe!
Richard Mahr
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:29 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz