Registriert seit: 18. Aug 2014
55 Beiträge
Delphi 10.2 Tokyo Starter
|
AW: Tipps und Ratschläge für Spiel & für effizientes Programmieren
3. Sep 2017, 21: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?
Geändert von Danny92 ( 3. Sep 2017 um 21:12 Uhr)
|