Einzelnen Beitrag anzeigen

Benutzerbild von Danny92
Danny92

Registriert seit: 18. Aug 2014
55 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#30

AW: Tipps und Ratschläge für Spiel & für effizientes Programmieren

  Alt 3. Sep 2017, 20:09
Hier noch einmal die Prozedur zum Setzen der Flotte:

Delphi-Quellcode:
procedure TForm1.SetzeFlotte(ofPlayer: boolean);
var
  zahl, i, j, k, fehlenNoch, vofPlayer: Integer;
  done, alleProbiert: Boolean;
  richtungProbiert: array[0..3] of Boolean;
begin
  vofPlayer:=StrToInt(BoolToStr(ofPlayer, false)) + 1;
  flotte[vofPlayer].Free;
  flotte[vofPlayer]:=TFlotte.Create(flottengroesse[5], flottengroesse[4],
  flottengroesse[3], flottengroesse[2], flottengroesse[1]);
  for i:=5 downto 1 do
  begin
    j:=1;
    fehlenNoch:=flotte[vofPlayer].AnzahlFehlenderSchiffeDerGroesse(i);
    while j <= fehlenNoch do
    begin
      done:=false;
      repeat
        zahl:=random(feldgroesse * feldgroesse) + 1;
        for k:=0 to 3 do richtungProbiert[k]:=false;
        a:=Point(((zahl - 1) mod feldgroesse) + 1, ((zahl - 1) div feldgroesse) + 1);
        repeat
          k:=random(4);
          alleProbiert:=true;
          case k of
          0: if a.Y >= i then b:=Point(a.X, a.Y - i + 1);
          1: if a.Y + i - 1 <= feldgroesse then b:=Point(a.X, a.Y + i - 1);
          2: if a.X >= i then b:=Point(a.X - i + 1, a.Y);
          3: if a.X + i - 1 <= feldgroesse then b:=Point(a.X + i - 1, a.Y);
          end;
          if not richtungProbiert[k]
          then done:=flotte[vofPlayer].SetzeSchiff(a, b);
          richtungProbiert[k]:=true;
          for k:=0 to 3 do
            if not richtungProbiert[k] then alleProbiert:=false;
        until alleProbiert or done;
      until done;
      Inc(j);
    end;
  end;
  FeldPlayer.Repaint;
end;
Hier die darin benutzte boolsche Funktion SetzeSchiff(a, b: TPoint) aus der Klasse TFlotte, die genau dann true zurückgibt, wenn das Platzieren des Schiffes im Feld unter den bekannten Regeln erfolgreich war:

Delphi-Quellcode:
function TFlotte.SetzeSchiff(a: TPoint; b: TPoint): boolean;
var
  laenge, vmin, vmax, i: integer;
begin
  if IstGueltig(a, b) then
  begin
    if a.X=b.X
    then laenge:=max(a.Y,b.Y)-min(a.Y,b.Y)+1
    else laenge:=max(a.X,b.X)-min(a.X,b.X)+1;
    if laenge>1
    then Inc(schiffsanzahl);
    SetLength(vSchiff[laenge],Length(vSchiff[laenge])+1);
    vSchiff[laenge,high(vSchiff[laenge])]:=TSchiff.Create;
    if a.X=b.X then
    begin
      vmin:=min(a.Y,b.Y); vmax:=max(a.Y,b.Y);
      for i:=vmin to vmax do
      if laenge=1
      then feld[a.X-1,i-1]:=3
      else feld[a.X-1,i-1]:=1;
      result:=vSchiff[laenge,high(vSchiff[laenge])].SetzeSchiff(Point(a.X,vmin),Point(a.X,vmax));
    end else
    if a.Y=b.Y then
    begin
      vmin:=min(a.X,b.X); vmax:=max(a.X,b.X);
      for i:=vmin to vmax do
      if laenge=1
      then feld[i-1,a.Y-1]:=3 //Setze Mine
      else feld[i-1,a.Y-1]:=1;
      result:=vSchiff[laenge,high(vSchiff[laenge])].SetzeSchiff(Point(vmin,a.Y),Point(vmax,a.Y));
    end
    else
      result:=false
  end
  else
    result:=false
end;
Und hier zuletzt die darin benutzte boolsche Funktion SetzeSchiff(a, b: TPoint) aus der Klasse TSchiff, die bei Erfolg ebenfalls true liefert:

Delphi-Quellcode:
function TSchiff.SetzeSchiff(a,b: TPoint): boolean;
var
  istSchiff: boolean;
  i: integer;
begin
  istSchiff:=(a.X=b.X) and (abs(a.Y-b.Y)<5) or (a.Y=b.Y) and (abs(a.X-b.X)<5);
  if istSchiff then
  begin
    vStart:=a; vEnde:=b;
    if a.X=b.X
    then laenge:=abs(a.Y-b.Y)+1
    else laenge:=abs(a.X-b.X)+1;
    vWaagerecht:=a.Y=b.Y;
    SetLength(vSchiff,laenge);
    for i:=1 to laenge do vSchiff[i-1]:=false;
  end;
  result:=istSchiff;
end;
So und jetzt kommt das Irre: bleibt die äußerste Zählschleife in SetzeFlotte als i:=5 downto 1, wird in manchen Fällen das 5er Schiff nicht gezeichnet, die Flotte besteht also nur aus dem 3er (linkes Bild im Anhang). Ändere ich die Zählschleife aber in i:=1 to 5, wird (wenn auch noch seltener) das 3er Schiff vergessen und nur das 5er Schiff plaziert (rechtes Bild im Anhang).

Was ist da los?! Bug?
Miniaturansicht angehängter Grafiken
5fehlt_downto.jpg   3fehlt_to.jpg  

Geändert von Danny92 ( 3. Sep 2017 um 20:12 Uhr)
  Mit Zitat antworten Zitat