Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Array mit Subeigenschaften der Elemente? (https://www.delphipraxis.net/180964-array-mit-subeigenschaften-der-elemente.html)

disso 3. Jul 2014 17:21

Array mit Subeigenschaften der Elemente?
 
Hallo!
Ich hab schon einige Zeit versucht, nach meinem Problem zu googlen, aber ich weiß nicht so recht, mit welchen Stichworten ich da Erfolg habe.
Ich möchte ein Logikrätsel lösen, für das es 10Mio Möglichkeiten gibt. Grundsätzlich hab ich auch schon einiges umgesetzt, aber bei einer Sache hakt es.
Ich habe 8 "Klötze", das ist jeweils ein Stab mit Zinnen und drei Würfeln dran, links und rechts vom Stab. Alle acht sind anders und zusammengesteckt (dafür die Zinnen) ergibt das ein 5x5 Feld, bei dem in der Mitte eine Lücke sein soll. Ich hoffe, das ist halbwegs verständlich - ist ansonsten aber auch nicht allzu wichtig.
Jedenfalls habe ich die Klötze mit a-h benannt (array of int) und die Würfelpositionen als Matrix dargestellt, zB a=
0 1 0 0 1
1 0 0 0 0
(die Längsachse durch die Matrix ist quasi der Stab, die 1en die Würfel.)
Wenn ich jezt meine Schleifen durchlaufen lasse, um die Möglichkeiten der Anordnung durchzugehen, möchte ich die 8 Buchstaben a-h zwei Arrays of char zuweisen, einer für die 4 senkrechten und einer für 4 waagerecht gelegte Klötze.
Aber wenn ich im inneren der Schleifen sage S[1]:=i (zb sei in der Schleife gerade i='a'), dann hat der Eintrag das zugehörige Array ja nicht als Eigenschaft angehängt und ist auch kein Array, sondern nur ein Zeichen.
Frage: Wie programmiere ich, dass anschließend aus S[1]='a' erkannt wird, dass es sich um Klotz a mit entsprechendem Array handelt? Geht das nur umständlich mit Schleifen oder gibt es sowas wie Array of Array of int? "array of array" ist ja eine Matrix, das ist also nicht das richtige.
Danke für Hinweise!

Sir Rufo 3. Jul 2014 17:51

AW: Array mit Subeigenschaften der Elemente?
 
Es gibt durchaus so ein Konstrukt, aber ich denke nicht, dass du damit glücklich wirst.

Ein wesentlich besserer Ansatz ist es hier mit Klassen zu arbeiten und der Klasse dann die Eigenschaften des Klotzes und auch ein Regelwerk womit du überprüfen kannst, ob die Lage eines anderen Klotzes so in Ordnung ist.

disso 3. Jul 2014 17:54

AW: Array mit Subeigenschaften der Elemente?
 
Die Überprüfung mache ich schon mit einer Matrix, ich vergleiche also Soll und Ist.
Die Idee mit ner Klasse hatte ich auch schon, allerdings habe ich das noch nie gemacht und da fehlt mir ein bisschen die Herangehensweise und wie ich die Elemente dann verwende ..

Sir Rufo 3. Jul 2014 18:11

AW: Array mit Subeigenschaften der Elemente?
 
Zitat:

Zitat von disso (Beitrag 1264324)
Die Überprüfung mache ich schon mit einer Matrix, ich vergleiche also Soll und Ist.
Die Idee mit ner Klasse hatte ich auch schon, allerdings habe ich das noch nie gemacht und da fehlt mir ein bisschen die Herangehensweise und wie ich die Elemente dann verwende ..

Du solltest dir ein paar grundlegende Gedanken zu dem Thema machen, sonst kann man auch keine solche Klasse aufbauen, bzw. beschreiben.

Hier mal eine schematische Darstellung:
-x--1--2--3--4--5-
Aab ac 
Bdabdc
C    d
D   c 
E  b  
Eingezeichnet sind 4 Klötze (a=[A1:B5], b=[A2:E3], c=[A4:E5], d=[B1:C5])

a und b können so liegen, b und c auch (die berühren sich gar nicht) aber a und c geht so nicht (Überschneidung auf A4), a und d, b und d, c und d sind wieder ok

Jetzt stellen wir fest, dass sich 2 Klötze immer nur an 4 Punkten (gekreuzt) oder an 5 Punkten (parallel) überlappen, somit ist die Prüfung selber nicht wirklich dramatisch. Eine globale Prüfung muss noch rein, damit das Loch in der Mitte bleibt.

disso 3. Jul 2014 18:23

AW: Array mit Subeigenschaften der Elemente?
 
Hm ich glaube, du hast das falsch verstanden (Oder ich verstehe dich nicht)
- Ich erstelle eine Nullmatrix (mein 5x5 Feld).
- Ich lasse eine Schleife durchlaufen, die alle Kombinationen durchgeht, 8 aus 8 mit Variation ohne Zurücklegen.
n!/(n-k)!=40320
und das in 256 Varianten (wenn ich jeweils den Klotz rotiere), also 10.321.920 Möglichkeiten.
- Diese Kombination weise ich den beiden Arrays zu. S[1..], W[1..4]. Dabei ist der Eintrag im einen Array automatisch "transponiert", um das Wenden drin zu haben (sonst kann man die Zinnen ja nicht ineinander stecken).
- dann folgt in etwa das (wird nach Zuweisung von S, W aufgerufen):
Delphi-Quellcode:
M_reset();         //Matrix resetten
     for k:=0 to 3 do begin   //S und W durchgehen
   for i:=1 to 5 do begin //Senkrechte auf das Feld addieren
       for j:=1 to 2 do begin
      M[i,j+k] := S[k].[i,j]; //<--funktioniert so nicht
       end;
   end;

   for i:=1 to 2 do begin          //Waagerechte auf das Feld addieren
       for j:=1 to 5 do begin    //durch Drehung i/j -> Transponierte
      M[i+k, j] := W[k].[i,j]; //<--funktioniert so nicht
       end;
   end;
     end;

     if comparemem(@M,@SollM,SizeOf(M)) then begin
        result := true;
     end
     else begin
         result:=false;
     end;
   end;
- Das Problem ist also das oben gekennzeichnete.

Sir Rufo 3. Jul 2014 18:36

AW: Array mit Subeigenschaften der Elemente?
 
Und statt diesem umständlichen Array-Verhau möchte ich eine Klotz-Klasse fragen, ob es ihr an der Position auf dem 5x5 Feld gefällt.
Delphi-Quellcode:
// Klotz fragen, ob es ihm in der 3. Reihe waagerecht auf dem Feld gefällt
if Klotz.SatisfiedWith( Feld, 2, horizontal ) then
  ...
Mit diesen Informationen kann der Klotz die Position seiner Würfel im Feld bestimmen und jeder Würfel kann schauen, ob auf dem Feld an seiner Stelle noch ein Plätzchen frei ist.

disso 3. Jul 2014 18:40

AW: Array mit Subeigenschaften der Elemente?
 
Ah, ich glaube ich weiß, was du meinst. Dann fehlen mir also nur noch die Grundkenntnisse zu einer Klasse. Hast du da einen guten Tipp zu ner verständlichen Dokumentation?

Sir Rufo 3. Jul 2014 18:46

AW: Array mit Subeigenschaften der Elemente?
 
Zitat:

Zitat von disso (Beitrag 1264338)
Ah, ich glaube ich weiß, was du meinst. Dann fehlen mir also nur noch die Grundkenntnisse zu einer Klasse. Hast du da einen guten Tipp zu ner verständlichen Dokumentation?

Ja, das Leben :stupid:

Beschreibe doch mal grob ein Fahrrad, so wie es von aussen dir erscheint.
PS Ich meine das tatsächlich ernst

himitsu 3. Jul 2014 18:56

AW: Array mit Subeigenschaften der Elemente?
 
Also den Code kann so kein Schwein lesen.
Ich würde dich bitten deine Codes mal in [delphi]...[/delphi] zu schreiben.

Zitat:

Delphi-Quellcode:
M[i,j+k] := S[k].[i,j]; // funktioniert so nicht

Ja, da diese Syntax eben falsch ist.

Ich hab jetzt nichtgesehn was das ist, aber wenn das ein Array of Array sein sollte, denn ohne Punkt, also
Delphi-Quellcode:
S[k][i,j]
.

PS:
Zitat:

Delphi-Quellcode:
if comparemem(@M,@SollM,SizeOf(M)) then begin
  result := true;
end
else begin
  result:=false;
end;

Delphi-Quellcode:
result:= comparemem(@M,@SollM,SizeOf(M));
:stupid:
Und wenn nur ein Befehl dazwischen steht, dann kann man das Begin-End (= Befehle gruppieren) auch weglassen.

disso 3. Jul 2014 18:57

AW: Array mit Subeigenschaften der Elemente?
 
Ich glaube, ich denke zu kompliziert. :D
Ich weiß schon, dass eine eigene Klasse quasi ein "Datentyp" ist, den es sonst noch nicht gibt. Die hat nen Namen und dann ihre Untereigenschaften, hier also TKlotz = class [Fahrrad]. Und dann im private und/oder public die Eigenschaften. Bei mir sind das also die Klötze [Reifen], die dazugehören, und dazu geordnet die Würfel [Speichen]. In deinem Beispiel ist jetzt zusätzlich satisfiedwith [Katzenauge Platz] eine Funktion der Klasse, ja? Die ruf ich also nach der Kombinationsfindung mit den entsprechenden Parametern 8 Mal auf und warte auf ein "ja, geht".

disso 3. Jul 2014 18:59

AW: Array mit Subeigenschaften der Elemente?
 
Mir ist klar, dass die Syntax so nicht funktioniert, das ist nur prinzipiell das, was ich da an der Stelle tun möchte.

Sir Rufo 3. Jul 2014 19:11

AW: Array mit Subeigenschaften der Elemente?
 
Also nehmen wir mal ein Fahrrad (nur schematisch)
Delphi-Quellcode:
TFahrrad = class
  property Vorderrad : TRad;
  property Hinterrad : TRad;

  function GehtAlsHinterrad( Rad : TRad ) : Boolean;
  function GehtAlsVorderrad( Rad : TRad ) : Boolean;
end;
Das Fahrrad hat Eigenschaften (Vorderrad, Hinterrad) und mit den beiden Methoden, kann ich das Fahrrad fragen, ob ich irgendein Rad da dranbasteln kann.

Denn es gibt ja unterschiedliche Räder (sind zwar alles Räder, aber trotzdem mit unterschiedlichen Eigenschaftswerten)

disso 3. Jul 2014 19:35

AW: Array mit Subeigenschaften der Elemente?
 
das mit dem Property war mir neu.
Ok also für meinen Fall würde ich sowas sagen wie
Delphi-Quellcode:
TFeld = class
   property KlotzA:TKlotz;
   ...
   property KlotzH:TKlotz;
   function PasstSenktrechtInsFeld(Klotz:TKlotz):Boolean;
   function PasstWaagerechtInsFeld(Klotz:TKlotz):Boolean;
end;

TKlotz=class
   private
      Anordnung: array [1..2,1..5] of integer;
end;
oder so ähnlich..?

himitsu 3. Jul 2014 19:44

AW: Array mit Subeigenschaften der Elemente?
 
Das sind ja erstmal nur schematische "Beispiele" und hinter den Property versteckt sich am Ende natürlich dann auch noch entsprechende Felder (Variablen in der TFeld-Klasse).

Warum eigentlich Integer?
Die Ecken sind doch entweder da oder nicht, was dann eher ein Boolean wäre. :zwinker:

disso 3. Jul 2014 19:46

AW: Array mit Subeigenschaften der Elemente?
 
ja geht auch, wenn ich mein "Prüfungskonzept" eh ändern muss. Usprünglich hatte ich alle Würfel aufaddiert, da spar ich mir mit int die Umwandlung.

aber wie definiere ich denn die Klasse TKlotz innerhalb der TFeld? Oder ist TKlotz keine Klasse?

Sir Rufo 3. Jul 2014 20:23

AW: Array mit Subeigenschaften der Elemente?
 
Zitat:

Zitat von disso (Beitrag 1264359)
ja geht auch, wenn ich mein "Prüfungskonzept" eh ändern muss. Usprünglich hatte ich alle Würfel aufaddiert, da spar ich mir mit int die Umwandlung.

aber wie definiere ich denn die Klasse TKlotz innerhalb der TFeld? Oder ist TKlotz keine Klasse?

Das werden beides Klassen, aber du hast eigentlich die wichtigste Klasse vergessen.

Die Würfel!
Delphi-Quellcode:
TLage = (horizontal, vertikal);

TWürfel = class
  PositionImKlotz : Integer; // 0..9
  function GetKoordinate( AIndex : Integer; ALage : TLage ) : TPoint;
end;

TKlotz = class
  Würfel : array of TWürfel;
end;

TKlotzImFeld
  Klotz : TKlotz;
  Index : Integer;
  Lage : TLage;
end;
 
TFeld = class
  Klötze : array of TKlotzImFeld;
  function IstZelleBelegt( x,y : Integer ): Boolean;
end;

function TFeld.IstZelleBelegt( AKoord : TPoint ) : Boolean;
begin
  for LKlotzInFeld in Klötze do
    for LWürfel in LKlotzInFeld.Klotz.Würfel do
      begin
        LKoord := LWürfel.Koordinate( LKlotzInFeld.Index, LKlotzInFeld.Lage );
        if LKoord = AKoord then
          Exit( True );
  Result := False;
end;

disso 3. Jul 2014 20:35

AW: Array mit Subeigenschaften der Elemente?
 
ich hatte gedacht, die Würfel könnte man einfach als array oder Bool machen. Das was du da geschrieben hast, muss ich morgen mal in Ruhe nachvollziehen. Danke jedenfalls schon mal!

Sir Rufo 3. Jul 2014 20:41

AW: Array mit Subeigenschaften der Elemente?
 
Zitat:

Zitat von disso (Beitrag 1264365)
ich hatte gedacht, die Würfel könnte man einfach als array oder Bool machen. Das was du da geschrieben hast, muss ich morgen mal in Ruhe nachvollziehen. Danke jedenfalls schon mal!

Die Würfel sind doch die Elemente, die andere Würfel/Klötze daran hindern auf dem Feld abgelegt zu werden. Und in der Realität passiert doch auch genau diese Interaktion zwischen den Würfeln. Darum würde ich die auch so mit in das Modell hineinnehmen. Und die Aufgabe ist quasi gelöst, wenn der Würfel seine Koordinaten im Feld bestimmen kann.

Kommst du mit einem neuen Klotz und einer gewünschten Position und Lage, dann fragst du für jeden Würfel die Koordinate zu dieser Position und Lage ab und fragst das Feld, ob alle diese Koordinaten noch frei sind.

Delphi-Quellcode:
function TKlotz.KannAnPosition( AFeld : TFeld; AIndex : Integer; ALage : TLage ) : Boolean;
begin
  for LWürfel in Würfel do
    if AFeld.IstZelleBelegt( LWürfel.GetKoordinate( AIndex, ALage ) ) then
      Exit( False );
  Result := True;
end;
Man braucht also eigentlich nur eine kleine Funktion im Würfel, der Rest ist geschicktes Abfragen dieser Funktion :)

PS: Anstatt der Koordinate vom Typ TPoint reicht es allerdings auch aus einfach einen Integer-Wert zurückzugeben 0..24 dadurch wird auch die Berechnung einfacher, schneller und auch der Vergleich insgesamt schneller. :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:24 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz