Probleme mit Zufallszahlen im Array?

CSANecromancer

Erfahrenes Mitglied
Tja, sorry, aber nur explizit den Part mit der Berechnung der Zahlenwerte extrahieren funktioniert leider nicht, da ich den Generator komplett selber gebastelt habe und von daher auch ganz andere Algorithmen benutzt habe. Aber ich kann dir den Source von mir posten.

Das Formular dazu sieht ganz einfach aus:
Fomular selbst:
Name: Main

Darauf ein TImage:
Name: Image

Und ein TButton:
Name: btGenerate
Caption: "Generate..."

Und hier der Source dazu:
Code:
{*-----------------------------------------------------------------------------
  Kakuro Generator

  Auch bekannt als "Kreuzworträtsel für Legastheniker"

  @author The Necromancer
  @version 0.2
-----------------------------------------------------------------------------*}
unit Dialogs.Main;

interface uses

  Classes, Controls, Dialogs, ExtCtrls, Forms, Graphics, Messages,
  StdCtrls, StrUtils, SysUtils, Variants, Windows;


type
{*-----------------------------------------------------------------------------
  Record für ein einzelnes Feld des Kakurospielfelds
-----------------------------------------------------------------------------*}
  TKakuroField = record
  public
    Name: String;
    Value: Integer;
  end;


type
{*-----------------------------------------------------------------------------
  Klassendefinition für das Hauptformular
-----------------------------------------------------------------------------*}
  TMain = class(TForm)
    Image: TImage;
    btGenerate: TButton;

    procedure FormCreate(Sender: TObject);
    procedure btGenerateClick(Sender: TObject);

  private
    PlayingField: array[0..12, 0..12] of TKakuroField;

    procedure ReadingPlayingFieldTemplate(const p_Field: TStringList);
    procedure PlayingFieldGenerate;
    procedure PlayingFieldDraw;
    procedure DrawGrid;
    procedure DrawBlock( const p_X: Integer;
                         const p_Y: Integer;
                         const p_Color: TColor);

    function IsInRow(const p_Value: Integer;
                     const p_x: Integer;
                     const p_y: Integer): boolean;
    function IsInColumn(const p_Value: Integer;
                        const p_x: Integer;
                        const p_y: Integer): boolean;
    function HorizontalSum(const p_x: Integer;
                           const p_y: Integer): Integer;
    function VerticalSum(const p_x: Integer;
                         const p_y: Integer): Integer;

  end;


var
{*-----------------------------------------------------------------------------
  Objektdefinition für die Klasse des Hauptformulars
-----------------------------------------------------------------------------*}
  Main: TMain;


implementation
{$R *.dfm}


{*-----------------------------------------------------------------------------
  Wird vom Konstruktor aufgerufen

  @param Sender Handle auf das aufrufende Objekt
-----------------------------------------------------------------------------*}
procedure TMain.FormCreate(Sender: TObject);
var
  strlTemplate: TStringList;
  x, y: Integer;
begin
  // Um unschönes Flackern beim Neuzeichnen des Programms zu vermeiden
  self.DoubleBuffered := true;

  // Wird nur hier und einmalig aufgerufen, so wie es auch in der
  // Delphi-Hilfe steht
  Randomize;

  // In der Stringlist mit dem Template steht die Struktur des
  // Kakuro-Feldes drin. Anhand dieses Templates wird das
  // Spielfeld erstmal grundlegend eingerichtet.
  strlTemplate := TStringList.Create;
  strlTemplate.Clear;
  strlTemplate.Add('MMMSSSSMMSSS');
  strlTemplate.Add('MMSNNNNSSNNN');
  strlTemplate.Add('MSNNNNNNSNNN');
  strlTemplate.Add('SNNSNNNSNNMM');
  strlTemplate.Add('SNNSSNNSNNSS');
  strlTemplate.Add('MSNNSNNSNNNN');
  strlTemplate.Add('SNNNNNSNNNNN');
  strlTemplate.Add('SNNNNSNNSNNS');
  strlTemplate.Add('MMSNNSNNSSNN');
  strlTemplate.Add('MSSNNNSNNSNN');
  strlTemplate.Add('SNNNSNNNNNNM');
  strlTemplate.Add('SNNNMSNNNNMM');

  ReadingPlayingFieldTemplate(strlTemplate);
  FreeAndNil(strlTemplate);

  // Ich mag es nicht, eine graphische Ausgabe direkt auf den Canvas
  // des Formulars zu zeichnen. Lieber kapsel ich das Ganze in die Bitmap
  // eines unskalierten TImage.
  // Damit ich aber (ohne ein Bild explizit zu laden), mit der Bitmap
  // des TImage arbeiten kann, muß ich es erstmal einrichten, wobei das
  // wichtigste die Zuweisung von Breite und Höhe ist.
  // Die Zahlenwerte kommen daher:
  // Breite des Spielfeldes: 12 Felder
  // Höhe des SpielfeldeS:   12 Felder
  // Pixelgrösse eines einzelnen Feldes des Spielfelds: 32x32
  Image.Picture.Bitmap.Width  := 12 * 32;
  Image.Picture.Bitmap.Height := 12 * 32;

  // Gitterraster in das Spielfeld einzeichnen
  // Dabei wird die Anzeige des Spielfelds automatisch gelöscht
  DrawGrid;

  // Das geladene Template wird auf dem Spielfeld angezeigt, ohne daß dabei
  // die Ziffernwerte der Spielfelder berücksichtigt werden.
  for y := 0 to 11 do
  begin
    for x := 0 to 11 do
    begin
           if PlayingField[y][x].Name = 'M' then DrawBlock(x, y, clBlack)
      else if PlayingField[y][x].Name = 'S' then Image.Picture.Bitmap.Canvas.TextOut(x * 32 + 6, y * 32 + 6, 'S')
      else if PlayingField[y][x].Name = 'N' then DrawBlock(x, y, clSilver)
      else                                       DrawBlock(x, y, clRed);
    end;
  end;
end;


{*-----------------------------------------------------------------------------
  Aktionsmethode des Buttons "Generate..."

  In dieser Methode wird das eigentliche Spielfeld generiert und ggf.
  angezeigt. Sehr einfach gehalten.

  @param Sender Handle auf das aufrufende Objekt
-----------------------------------------------------------------------------*}
procedure TMain.btGenerateClick(Sender: TObject);
begin
  Screen.Cursor := crHourglass;
  btGenerate.Enabled := false;
  PlayingFieldGenerate;
  Screen.Cursor := crDefault;
  btGenerate.Enabled := true;
end;


{*-----------------------------------------------------------------------------
  Übertragen des Templates auf das Spielfeld

  Wie der Methodenname schon sagt. Allerdings wird das Spielfeld vorher
  noch sauber mit Leerwerten initialisiert.

  @param Sender Handle auf das aufrufende Objekt
-----------------------------------------------------------------------------*}
procedure TMain.ReadingPlayingFieldTemplate(const p_Field: TStringList);
var
  x, y: Integer;
begin
  // Leeren des Spielfelds
  for y := 0 to 11 do
  begin
    for x := 0 to 11 do
    begin
      PlayingField[y][x].Value := -1;
      PlayingField[y][x].Name := '';
    end;
  end;

  // Übernehmen der Spielfeldnamen aus dem Template
  for y := 0 to p_Field.Count - 1 do
  begin
    for x := 0 to Length(p_Field.Strings[y]) - 1 do
      PlayingField[y][x].Name := MidStr(p_Field.Strings[y], x + 1, 1);
  end;
end;


{*-----------------------------------------------------------------------------
  Erzeugen des Spielfelds

  Für eine genauere Beschreibung kommentiere ich die Funktion direkt im
  Source. Hier nur eine Beschreibung des verwendeten Variablen:

  x, y: Die X- und Y-Koordinate des aktuell betrachteten Feldes

  nTempWert: Übernimmt zeitweilig die neue Zufallszahl, die in das
             Feld geschrieben werden soll.

  bEingetragen: Flag ob der neue Wert in das Feld eingetragen werden konnte.

  bUnsuccessful: Flag ob das Kakuro nicht mehr erstellt werden kann.

  nTryCounter: Zähler wie oft versucht wurde, einen neuen Wert in das
               aktuell betrachtete Feld zu schreiben.

  @param Sender Handle auf das aufrufende Objekt
-----------------------------------------------------------------------------*}
procedure TMain.PlayingFieldGenerate;
var
  x, y: Integer;
  nTempWert: Integer;
  bEingetragen: boolean;
  bUnsuccessful: boolean;
  nTryCounter: Integer;
begin
  // Generell wird davon ausgegangen, daß das Spielfeld erstellt
  // werden kann.
  bUnsuccessful := false;

  // Nochmal Leeren der Zahlenwerte der einzelnen Felder.
  // Ist dafür gut, daß durch erneutes Klicken auf "Generate..."
  // unterschiedliche Kakuros auf das gleiche Template gebastelt
  // werden können.
  for y := 0 to 11 do
    for x := 0 to 11 do
      PlayingField[y][x].Value := -1;

  // Zeile für Zeile...

  for y := 0 to 11 do
    // ...und pro Zeile Feld für Feld
    for x := 0 to 11 do

      if PlayingField[y][x].Name = 'N' then
      begin
        // Für jedes Feld wird neu versucht, einen Zufallswert
        // reinzuschreiben
        nTryCounter := 0;

        // Logisch, daß bislang noch kein neuer Zufallswert
        // reingeschrieben wurde.
        bEingetragen := false;

        // Solche Bedingungen mag ich. Die sind einfach zu lesen
        // und zu verstehen.
        // Solange noch kein neuer Wert eingetragen wurde und das
        // Kakuro noch nicht als unlösbar bewertet wurde, wird
        // versucht, einen neuen Wert reinzuschreiben.
        while (not bEingetragen) and
              (not bUnsuccessful) do
        begin
          nTempWert := Random(9) + 1;
          Inc(nTryCounter);

          // Wenn auch nach 100 Versuchen noch kein passender
          // neuer Wert gefunden wurde, dann wird das Kakuro
          // als nicht lösbar gewertet
          if nTryCounter > 100 then
            bUnsuccessful := true;

          // Auch die Bedingung sollte direkt verständlich sein:
          // Die beiden Funktionen prüfen, ob der gewählte neue
          // Zufallswert schon in der Zeile und/oder der Spalte
          // vorkommt. Wenn nein, dann wird er eingetragen.
          if  ((not IsInRow(nTempWert, x, y)) and
              (not IsInColumn(nTempWert, x, y))) then
          begin
            PlayingField[y][x].Value := nTempwert;
            bEingetragen := true;
          end;
        end;

  end;

  // Falls das Kakuro gebaut werden konnte, wird es angezeigt...
  if not bUnsuccessful then
    PlayingFieldDraw
  // ...andernfalls wird das Spielfeld gelöscht und eine entsprechende
  // Hinweismeldung ausgegeben.
  else
  begin
    DrawGrid;
    ShowMessage('Generating unsuccessful.' + #13 + 'Ran into an unsolvable puzzle.');
  end;
end;


{*-----------------------------------------------------------------------------
  Prüfen des neuen Zahlenwerts auf die Zeile

  Die Vorgehensweise ist sehr direkt: Es werden für die Zeile der Start- und
  der Endpunkt in Relation zum angewählten Feld bestimmt. Der Startpunkt ist
  das links vom angewählten Feld liegende Summenfeld + 1 und der Endpunkt
  entsprechend das rechts vom angewählten Feld liegende Feld, das keine Zahlen
  beinhaltet - 1. Es muß nur aufgepasst werden, daß die Spielfeldbegrenzungen
  korrekt erkannt werden.
  Sobald Anfang und Ende bekannt sind, wird einfach geschaut, ob der
  übergebene (neue) Zahlenwert schon vorkommt oder nicht.

  @param p_Value Der neue Zahlenwert, der überprüft werden soll
  @param p_X X-Koordinate des angewählten Feldes
  @param p_Y Y-Koordinate des angewählten Feldes
  @return Flag ob der Wert schon vorhanden ist
-----------------------------------------------------------------------------*}
function TMain.IsInRow(const p_Value: Integer;
                       const p_x: Integer;
                       const p_y: Integer): boolean;
var
  RowStart: Integer;
  RowEnd: Integer;
  i: Integer;
begin
  // Sicher ist sicher, daher die Initialisierung
  RowStart := 0;
  RowEnd := 0;

  // Ermitteln des Startpunkts
  if p_x > 0 then
    for i := p_x downto 0 do
      if PlayingField[p_y][i].Name <> 'N' then
      begin
        RowStart := i + 1;
        break;
      end;

  // Ermitteln des Endpunkts
  if p_x <= 11 then
    for i := p_x to 11 do
      if i = 11 then
        RowEnd := 11
      else if PlayingField[p_y][i].Name <> 'N' then
      begin
        RowEnd := i - 1;
        break;
      end;

  // Sicherstellen, daß die Spielfeldgrenzen gewahrt bleiben
  if RowStart < 0 then RowStart := 0;
  if RowStart > 11 then RowStart := 11;
  if RowEnd < 0 then RowEnd := 0;
  if RowEnd > 11 then RowEnd := 11;

  // Rückgabewertermittlung, ob es den Wert des ausgewählten
  // Feldes in der Reihe schon gibt oder nicht.
  Result := false;

  for i := RowStart to RowEnd do
    if PlayingField[p_y][i].Value = p_Value then
      Result := true;
end;


{*-----------------------------------------------------------------------------
  Prüfen des neuen Zahlenwerts auf die Spalte

  Funktioniert genauso wie die Reihenprüfung, weswegen ich mir eine exzessive
  Dokumentation spare.

  @param p_Value Der neue Zahlenwert, der überprüft werden soll
  @param p_X X-Koordinate des angewählten Feldes
  @param p_Y Y-Koordinate des angewählten Feldes
  @return Flag ob der Wert schon vorhanden ist
-----------------------------------------------------------------------------*}
function TMain.IsInColumn(const p_Value: Integer;
                          const p_x: Integer;
                          const p_y: Integer): boolean;
var
  ColStart: Integer;
  ColEnd: Integer;
  i: Integer;
begin
  ColStart := 0;
  ColEnd := 0;

  if p_y > 0 then
    for i := p_y downto 0 do
      if PlayingField[i][p_x].Name <> 'N' then
      begin
        ColStart := i + 1;
        break;
      end;

  if p_y <= 11 then
    for i := p_y to 11 do
      if i = 11 then
        ColEnd := 11
      else if PlayingField[i][p_x].Name <> 'N' then
      begin
        ColEnd := i - 1;
        break;
      end;

  if ColStart < 0 then ColStart := 0;
  if ColStart > 11 then ColStart := 11;
  if ColEnd < 0 then ColEnd := 0;
  if ColEnd > 11 then ColEnd := 11;

  Result := false;
  for i := ColStart to ColEnd do
    if PlayingField[i][p_x].Value = p_Value then
      Result := true;
end;


{*-----------------------------------------------------------------------------
  Zeichnen des Spielfeldes

  Macht fast das gleiche wie das Zeichnen des Templates, nur daß diesmal
  die Zahlenwerte der Felder mit angegeben werden und die Summenfelder auch
  passend beschriftet werden.
-----------------------------------------------------------------------------*}
procedure TMain.PlayingFieldDraw;
var
  x, y: Integer;
  Text: String;
  pCanvas: TCanvas;
begin
  pCanvas := Image.Picture.Bitmap.Canvas;

  // Gitterraster einzeichnen (und damit das Spielfeld löschen)
  DrawGrid;

  // Und wieder: Zeile für Zeile...
  for y := 0 to 11 do
    // ...und pro Zeile Feld für Feld
    for x := 0 to 11 do

      // Blockfelder werden einfach als schwarze Kästchen dargestellt
      if PlayingField[y][x].Name = 'M' then
        DrawBlock(x, y, clBlack)

      // Zahlenfelder bekommen einen grauen Hintergrund und danach
      // wird der Zahlenwert reingeschrieben
      else if PlayingField[y][x].Name = 'N' then
      begin
        DrawBlock(x, y, clSilver);

        Text := IntToStr(PlayingField[y][x].Value);
        pCanvas.Brush.Style := bsClear;
        pCanvas.TextOut(x * 32 + 8, y * 32 + 6, Text);
        pCanvas.Brush.Style := bsSolid;
      end

      // Es stimmt irgendwas nicht mit dem Feld, also wird es
      // rot gefärbt.
      else if PlayingField[y][x].Name <> 'S' then
        DrawBlock(x, y, clRed);

  // Jetzt kommen noch die Summenfelder dran
  pCanvas.Font.Size := 8;

  // Der Durchlauf ist ja bekannt
  for y := 0 to 11 do
  begin
    for x := 0 to 11 do
    begin
      if PlayingField[y][x].Name = 'S' then
      begin
        // Falls eine Horizontalsumme vorhanden ist: Anzeigen
        if HorizontalSum(x, y) > 0 then
          pCanvas.TextOut(x * 32 + 18, y * 32 + 2, IntToStr(HorizontalSum(x, y)));

        // Falls eine Vertikalsumme vorhanden ist: Anzeigen
        if VerticalSum(x, y) > 0 then
          pCanvas.TextOut(x * 32 + 2, y * 32 + 18, IntToStr(VerticalSum(x, y)));

        // Zeichnen der schwarzen Schräglinie bei Summenfeldern
        pCanvas.Pen.Color   := clBlack;
        pCanvas.MoveTo(x * 32, y * 32);
        pCanvas.LineTo(x * 32 + 32, y * 32 + 32);
        pCanvas.Pen.Color := clWhite;
      end;
    end;
  end;

  // Die gesamte Spielfläche neu zeichnen
  Image.Invalidate;
end;


{*-----------------------------------------------------------------------------
  Bestimmen der horizontalen Summe eines Summenfeldes

  @param p_X X-Spielfeldkoordinate des Summenfeldes
  @param p_Y Y-Spielfeldkoordinate des Summenfeldes
  @return Horizontalsumme
-----------------------------------------------------------------------------*}
function TMain.HorizontalSum(const p_x: Integer;
                             const p_y: Integer): Integer;
var
  i: Integer;
begin
  Result := 0;

  for i := p_x + 1 to 11 do
  begin
    if PlayingField[p_y][i].Name = 'N' then
      Result := Result + PlayingField[p_y][i].Value
    else
      break;
  end;
end;


{*-----------------------------------------------------------------------------
  Bestimmen der vertikalen Summe eines Summenfeldes

  @param p_X X-Spielfeldkoordinate des Summenfeldes
  @param p_Y Y-Spielfeldkoordinate des Summenfeldes
  @return Vertikalsumme
-----------------------------------------------------------------------------*}
function TMain.VerticalSum(const p_x: Integer;
                           const p_y: Integer): Integer;
var
  i: Integer;
begin
  Result := 0;

  for i := p_y + 1 to 11 do
  begin
    if PlayingField[i][p_x].Name = 'N' then
      Result := Result + PlayingField[i][p_x].Value
    else
      break;
  end;
end;


{*-----------------------------------------------------------------------------
  Zeichnen eines Blocks in einem Feld des Spielfelds

  Der wesentliche Punkt ist nur, daß dabei die alten Zeichenfarben beibehalten
  werden.

  @param p_X X-Spielfeldkoordinate des angewählten Feldes
  @param p_Y Y-Spielfeldkoordinate des angewählten Feldes
  @param p_Color Farbe des zu zeichnenden Blocks
-----------------------------------------------------------------------------*}
procedure TMain.DrawBlock( const p_X: Integer;
                           const p_Y: Integer;
                           const p_Color: TColor);
var
  OldPenColor: TColor;
  OldBrushColor: TColor;
  pCanvas: TCanvas;
begin
  pCanvas := Image.Picture.Bitmap.Canvas;
  OldPenColor := pCanvas.Pen.Color;
  OldBrushColor := pCanvas.Brush.Color;
  pCanvas.Pen.Color := p_Color;
  pCanvas.Brush.Color := p_Color;
  pCanvas.Rectangle(p_x * 32 + 1, p_y * 32 + 1, p_x * 32 + 32, p_y * 32 + 32);
  pCanvas.Pen.Color := OldPenColor;
  pCanvas.Brush.Color := OldBrushColor;
end;


{*-----------------------------------------------------------------------------
  Zeichnen des Spielgitters

  Löscht gleichzeitig die Anzeige des Spielfelds
-----------------------------------------------------------------------------*}
procedure TMain.DrawGrid;
var
  pCanvas: TCanvas;
  x, y: Integer;
begin
  // Leeren des Spielfelds
  pCanvas := Image.Picture.Bitmap.Canvas;
  pCanvas.Pen.Color   := clWhite;
  pCanvas.Pen.Style   := psSolid;
  pCanvas.Brush.Color := clWhite;
  pCanvas.Brush.Style := bsSolid;
  pCanvas.Font.Name   := 'Arial';
  pCanvas.Font.Size   := 16;
  pCanvas.Rectangle(0, 0, Image.Picture.Bitmap.Width, Image.Picture.Bitmap.Height);

  // Vorbereiten auf das Zeichnen der Gitterlinien
  pCanvas.Pen.Color := clBlack;
  pCanvas.Brush.Color := clBlack;

  // Zeichnen der horizontalen Linien
  for y := 0 to 11 do
  begin
    pCanvas.MoveTo(0, y * 32);
    pCanvas.LineTo(Image.Picture.Bitmap.Width, y * 32);
  end;

  // Zeichnen der vertikalen Linien
  for x := 0 to 11 do
  begin
    pCanvas.MoveTo(x * 32, 0);
    pCanvas.LineTo(x * 32, Image.Picture.Bitmap.Height);
  end;

  // Rücksetzen der Farben, sonst kommen andere Outputmethoden in
  // Schwierigkeiten
  pCanvas.Pen.Color   := clWhite;
  pCanvas.Brush.Color := clWhite;
end;


end.

Damit kannst du mal vergleichen und schauen, wo dann bei dir den Haken war.
 

jackie05

Erfahrenes Mitglied
Vielen Dank für die Mühe.

Eigentlich habe ich mir das so vorgestellt:
Man Setzt im ersten Sumen Block eine Zufallszahl und dann geht man ein Feld weiter, danach wird wieder eine Zufallszahl eingesetzt und prüft die Zahl nach links in der gleichen Reihe, wenn es die gleiche Zahl entspricht, wird sie um 1 erhöt und das gleiche Spiel wieder von vorne, bis die Zahl in der reihe nicht existiert.
So müsste man keine 100 versuche durch eine Zufallszahl testen.

So habe ich das ja gemacht, was auch nicht 100% funktionierte.
Ich arbeite ja mit mehreren Programmiersprache und habe diese Funktion in BlitzMax testweise mal umgeschrieben und getestet, läuft fehlerfrei, wirklich seltsam.

Edit: Hier ist mal ein Screen von mir:
http://www.qpic.ws/viewimage.php?file=/images/LeZ77736.png
Wie man auf dem Screen erkennen kann, fehlt unten rechts eine Zahl.
Es passiert nur manchmal, das wenn ich die Zahlen neu generiere, das eine Zahl dann fehlt.
Das ist nur bei den großen Spielfeldern so, die kleinere Spielfeldern funktionieren Top.

Naja, ich werde mir mal in Ruhe deinen Code ankucken und vielen Dank für die Hilfe.

MfG
 
Zuletzt bearbeitet:

CSANecromancer

Erfahrenes Mitglied
Genau der von dir gepostete Screenshot zeigt das Problem:
Welche Ziffer würdest du denn in das Feld eintragen, um zu einer eindeutigen Lösung zu kommen? Denn die Ziffern von 1-9 sind schon waagrecht und senkrecht vergeben.

Bei meinem Programm werden sämtliche Ziffern genauso komplett zufällig verteilt wie in deinem. Der Unterschied bei mir ist, daß ich mir gedacht habe, daß dieses Programm keine zeitkritische Anwendung ist und ich ohne weiteres ein paar hundert bis tausend Zyklen verbraten kann.

Natürlich lässt sich das Ganze noch optimieren mit Abgleichsarrays senkrecht und waagrecht von 1-9. Aber das zu implementieren war mir zu viel Aufwand für ein schnell runtergetipptes Programm. Da lasse ich den Zufallszahlengenerator eher einfach 100 Ehrenrunden drehen, bevor ich sage: "Jetzt langt's".

Das Kernproblem ist doch das Generieren von "unmöglichen" Puzzeln. Ob die Zufallszahlen jetzt mit einem Inkrementierungsalgorithmus (wie bei dir) oder mit schon fast "brute force" (wie bei mir) im Feld landen, spielt da ja keine Musik. Aber die Generierungsmethode muß mitbekommen, wenn sie entweder gegen die Wand läuft (bei mir die 100er-Schwelle) oder wenn ein fehlerhaftes Rätsel gebildet wird (z.B. bei deinem Leerfeld).
 
Zuletzt bearbeitet:

jackie05

Erfahrenes Mitglied
Achso, das ist mir noch garnicht aufgefallen, da kann ja keine Zahl mehr hinein passen.

Also, dann ist ja mein Code in Ordnung, weil es ansonsten funktioniert und die Schleifen arbeiten auch sehr schnell.

Jetzt muss ich nur noch überprüfen, wenn keine Zahl (1-9) passt, das er versucht in dieser Reihe eine andere passende Zahl zu setzen.

Ich bin dir sehr dankbar, ich hätte den fehler irgendwie nie bemerkt, da ich nicht so besonders drauf geachtet habe.

Nochmals, vielen Dank.

MfG
 

CSANecromancer

Erfahrenes Mitglied
Achso, das ist mir noch garnicht aufgefallen, da kann ja keine Zahl mehr hinein passen.
Da habe ich auch etwas suchen müssen.

Also, dann ist ja mein Code in Ordnung, weil es ansonsten funktioniert und die Schleifen arbeiten auch sehr schnell.

Jetzt muss ich nur noch überprüfen, wenn keine Zahl (1-9) passt, das er versucht in dieser Reihe eine andere passende Zahl zu setzen.
Jup, entweder das oder du verwirfst das alte Ergebnis und startest die Generierung neu. So oft hatte ich es nicht, daß ein unlösbares Rätsel rauskam. Ca. 12mal bei 100 Versuchen.

Ich bin dir sehr dankbar, ich hätte den fehler irgendwie nie bemerkt, da ich nicht so besonders drauf geachtet habe.

Nochmals, vielen Dank.
Keine Ursache, über Bewertungen freue ich mich immer. :)
 

jackie05

Erfahrenes Mitglied
Ich hab das einfacher gemacht, indem ich prüfe, ob ein oder mehrere Felder leer sind, wenn ja, dann lasse ich die Funktion noch einmal ausführen, bis alle Felder vollständig gefüllt sind.

Es passiert ja nur manchmal, das dort keine Zahl hinein passt und die Schleife somit auch nicht in die Hose geht. ;)

Wenn ich z.B. Spielfelder habe, indem immer 1 Feld leer bleibt, dann würde die Schleife nie eine Ende geben, was aber nicht passieren würde. :)

MfG