Schleifenproblem die 2.

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Hartkern
Beiträge: 69
Registriert: Sa 5. Dez 2015, 20:03
OS, Lazarus, FPC: Win10 IDE 1.6
CPU-Target: 64Bit
Wohnort: Leipzig

Schleifenproblem die 2.

Beitrag von Hartkern »

Hallo,

ich hab in einer ObjectList 200 Objekte vom Typ Feld. Dieser Felder sind Hexagonalfelder auf einem Bitmap
Zur späteren besseren Verwendung (Nachbarfeldermittlung, Wegfindung) muss im Object Feld dessen Position in der Karte gespeichert werden. Ich benötige dazu Spalte (X Wert) und Zeile (Y Wert).
Der unten aufgeführte Code liefert mir bis jetzt das passende Endergebnis. Mein Problem ist, wie ich jeweils den Index in der ObjectList um eins erhöhe und die Werte dann zu schreiben.

Code: Alles auswählen

 
 
Feld := Felderliste.Items[i] as TFeld; // liste hat 200 Items 
 
 
ZaehlerAnzReihen:=0;
Repeat // /Spalte oder auch Reihe
  ZaehlerAnzFeldReihe:=0;
      Repeat    //Innerer Zähler für die Zeilenwert
          inc(ZaehlerAnzFeldReihe);
          //Feld.MapPos.x:=ZaehlerAnzReihen;   ----------------------------->hier fehlt der jeweilige Index
          //Feld.MapPos.y:=ZaehlerAnzFeldReihe;----------------------------->hier fehlt der jeweilige Index
      until ZaehlerAnzFeldReihe = AnzFeldReihe  ;   // im Testfall 8
  Inc(ZaehlerAnzReihen);//Reihe erhöhen
until ZaehlerAnzReihen = AnzReihen;             // im Testfall 25
 
Zuletzt geändert von Hartkern am Mi 20. Jan 2016, 13:57, insgesamt 2-mal geändert.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Schleifenproblem

Beitrag von Michl »

Ich hoffe, ich habe die Frage richtig verstanden:

Code: Alles auswählen

ZaehlerAnzReihen:=0;
Repeat // /Spalte oder auch Reihe
  ZaehlerAnzFeldReihe:=0;
      Repeat    //Innerer Zähler für die Zeilenwert
          Feld := Felderliste.Items[ZaehlerAnzReihen * AnzFeldReihe + ZaehlerAnzFeldReihe] as TFeld;
          inc(ZaehlerAnzFeldReihe);
          //Feld.MapPos.x:=ZaehlerAnzReihen;   ----------------------------->hier fehlt der jeweilige Index
          //Feld.MapPos.y:=ZaehlerAnzFeldReihe;----------------------------->hier fehlt der jeweilige Index
      until ZaehlerAnzFeldReihe = AnzFeldReihe  ;   // im Testfall 8
  Inc(ZaehlerAnzReihen);//Reihe erhöhen
until ZaehlerAnzReihen = AnzReihen; 
PS: Zwei "For To" - Schleifen würden sich meiner Meinung nach wesentlich besser lesen.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Hartkern
Beiträge: 69
Registriert: Sa 5. Dez 2015, 20:03
OS, Lazarus, FPC: Win10 IDE 1.6
CPU-Target: 64Bit
Wohnort: Leipzig

Re: Schleifenproblem

Beitrag von Hartkern »

Vielen Dank Michl,

[ZaehlerAnzReihen * AnzFeldReihe + ZaehlerAnzFeldReihe] :oops:

Hartkern
Beiträge: 69
Registriert: Sa 5. Dez 2015, 20:03
OS, Lazarus, FPC: Win10 IDE 1.6
CPU-Target: 64Bit
Wohnort: Leipzig

Re: Schleifenproblem die 2.

Beitrag von Hartkern »

Da ich bei meinen Projekt nicht um ein dynamisches Array rumkomme, hab ich folgenden Code geschrieben.
Ziel soll es lediglich sein, dass das Array of Array of Integer aFeldId lediglich eine Variable pro Index enthält.

Bei meinem Testfall hab ich 200 Felder. 25 Reihen und 8 Spalten nach unten
Es soll eigentlich nur "hochgezählt" werden.
Bsp. aFeldID[0,0] = 0 ; aFeldID[0,7] = 7, aFeldID[24,7] = 199 (sind ja 200 Felder, zählt ab 0);

jedoch bekomme ich immer in den Repeat Until einen SigSev wenn ich aFeldID[24,7] mir anzeigen lassen will.
Bin ich zu doof?


Code: Alles auswählen

      //aFeldID füllen 0. Reihe aFeldID[0,...]
      setlength(aFeldID,AnzReihen-1,AnzFeldReihe-1);
      For I:=0 to AnzFeldReihe-1 do
          begin
            aFeldID[0,I]:=i;
          end;
 
 
           ZaehlerAnzReihen:=1;//Beginn in Reihe aFeldID[1,...]
      Repeat // /Spalte oder auch Reihe
        ZaehlerAnzFeldReihe:=0;
            Repeat    //Innerer Zähler für die Zeilenwert
                aFeldID[ZaehlerAnzReihen,ZaehlerAnzFeldReihe] :=((ZaehlerAnzReihen * (AnzFeldReihe)) + ZaehlerAnzFeldReihe);
                inc(ZaehlerAnzFeldReihe);
            until ZaehlerAnzFeldReihe = AnzFeldReihe-1;
        Inc(ZaehlerAnzReihen);//Reihe erhöhen
      until ZaehlerAnzReihen = AnzReihen-1;
     showmessage(IntToStr(aFeldid[24,7])); 

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Schleifenproblem die 2.

Beitrag von Michl »

Warum machst du das nicht mit einer "for to" Schleife wie oben geschrieben? Sollte doch übersichtlicher sein:

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var
  aFeldID: Array of Array of Integer;
  aFeld, aReihe: Integer;
const
  AnzReihen = 25;
  AnzFeldReihe = 8;
begin
  //1. Größen des dynamischen Arrays definieren
  SetLength(aFeldID, AnzReihen);
  for aReihe := 0 to High(aFeldID) do
    SetLength(aFeldID[aReihe], AnzFeldReihe);
 
  //2. FeldID belegen
  for aReihe := 0 to High(aFeldID) do
    for aFeld := 0 to High(aFeldID[aReihe]) do
      aFeldID[aReihe, aFeld] := aReihe * AnzFeldReihe + aFeld;
 
  ShowMessage(IntToStr(aFeldid[24, 7]));
end; 

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Hartkern
Beiträge: 69
Registriert: Sa 5. Dez 2015, 20:03
OS, Lazarus, FPC: Win10 IDE 1.6
CPU-Target: 64Bit
Wohnort: Leipzig

Re: Schleifenproblem die 2.

Beitrag von Hartkern »

weil ich wahrscheinlich daran gescheitert wäre.

Code: Alles auswählen

SetLength(aFeldID[aReihe], AnzFeldReihe);
ich hab das noch nie gesehen. :oops:

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Schleifenproblem die 2.

Beitrag von Michl »

Das must du ja auch nicht so machen, so

Code: Alles auswählen

  SetLength(aFeldID, AnzReihen, AnzFeldReihe);  
gehts ja auch. Das hat ja aber nichts mit dem Ersatz der Repeat Schleife zu tun, wo ich eine klarere Struktur bevorzugen würde.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Hartkern
Beiträge: 69
Registriert: Sa 5. Dez 2015, 20:03
OS, Lazarus, FPC: Win10 IDE 1.6
CPU-Target: 64Bit
Wohnort: Leipzig

Re: Schleifenproblem die 3.

Beitrag von Hartkern »

Hallo,

ich hab ein Problem und komme nicht auf die Lösung.
Mit der Funktion wird geprüft ob ein Polygon angeklickt wurde, und wenn ein positives Ergebnis, dann spuckt er mir es aus. Soweit läuft es. Klicke ich ausserhalb der Hexfelder, sollte er ja gemäß meiner Until Bedingungen lediglich bis zum ObjectList Ende durchprüfen und dann fertig. Jedoch bekomme ich immer ein List out of Bounds!!

Code: Alles auswählen

function TMap.MousePosToID(MousePos: TPoint): Integer;
Var
 I,C : integer;
 FHex: array[0..5] of TPoint;
begin
 I := -1;
 C:=Felderliste.Count-1;
 repeat
   Inc(I);
   Feld := Felderliste.Items[I] as TFeld;
   FHex[0] := Feld.P0;
   FHex[1] := Feld.P1;
   FHex[2] := Feld.P2;
   FHex[3] := Feld.P3;
   FHex[4] := Feld.P4;
   FHex[5] := Feld.P5;
 until ((IsPointInPolygon(MousePos.x,MousePos.y,FHex) = True) or (I=c)); //wenn i 199 ist und c 199 müsste er abbrechen??!!!!
   IF IsPointInPolygon(MousePos.x,MousePos.y,FHex) = True then Result:=I;
end; 

Mathias
Beiträge: 6918
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Schleifenproblem die 2.

Beitrag von Mathias »

Bitte löschen, falscher Post.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Schleifenproblem die 2.

Beitrag von Michl »

Würde ich so lösen (ungetestet):

Code: Alles auswählen

function TMap.MousePosToID(MousePos: TPoint): Integer;
var
  i: Integer;
  FHex: array[0..5] of TPoint;
  Feld: TFeld;
begin
  Result := -1;
  for i := 0 to Felderliste.Count - 1 do begin
    Feld := Felderliste.Items[i] as TFeld;
    FHex[0] := Feld.P0;
    FHex[1] := Feld.P1;
    FHex[2] := Feld.P2;
    FHex[3] := Feld.P3;
    FHex[4] := Feld.P4;
    FHex[5] := Feld.P5;
    if IsPointInPolygon(MousePos.x, MousePos.y, FHex) then Exit(i);
  end;
end;
Hartkern hat geschrieben:

Code: Alles auswählen

 until ((IsPointInPolygon(MousePos.x,MousePos.y,FHex) = True) or (I=c)); //wenn i 199 ist und c 199 müsste er abbrechen??!!!!
Ja

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Antworten