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; ifnot richtungProbiert[k] then done:=flotte[vofPlayer].SetzeSchiff(a, b);
richtungProbiert[k]:=true; for k:=0 to 3 do ifnot 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:
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)); endelse 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:
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).