Also einen schönen guten Abend erstmal.
Ich möchte als Projektarbeit für die Schule ein Sudoku-Generator und -Löser programmieren. Der Ansatz beim Lösen ist dabei folgender: in einem leeren Sodoku könnte in jedem Feld jede Zahl stehen, sprich die 'FeldMenge' jeder Zelle ist [1,2,3,4,5,6,7,8,9]. Ist aber z.B. in der Zeile eine 1, so wird aus den FeldMengen der restlichen 8 Zellen dieser Zeile die 1 gelöscht, Spalten und Blöcke analog. Nach Eingabe des Sudokus (Generator verschiebe ich erstmal in die Zukunft ^^) soll das Programm die FeldMengen der einzelnen Zellen reduzieren, wenn sie nur noch aus einer Zahl besteht, so wird diese Zahl in die Zelle geschrieben und die FeldMengen der Zeile, der Spalte und des Blockes werden wieder verkleinert. Irgendwann müsste das Sudoku gelöst sein.
Auf dem Formular liegen zwei Instanzen von TStringGrid, Nr.1 ist 9x9 und soll das Sudoku darstellen, Nr.2 gibt die RestMenge der angeklickten Zelle aus (wird dann verborgen, ist eigentlich nur zur Überprüfung da).
Delphi-Quellcode:
type
Zahlen = Set of 1..9; //Menge der Zahlen, die in einem Feld stehen könnten
var
Form1: TForm1;
FeldMenge: Array [0..8,0..8] of Zahlen;
implementation
{$R *.dfm}
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
If (Key in ['1'..'9']) and Stringgrid1.focused
then //dient der Eingabe der Zahlen in das gewählte Feld
begin
StringGrid1.cells[StringGrid1.col,StringGrid1.row]:=Key;
RestMengeNeuZuOrdnen(strtoint(Key));
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var i,j:integer;
begin
For i:=0 to 8 do
For j:=0 to 8 do
FeldMenge[i,j]:=[1,2,3,4,5,6,7,8,9] //in jedem Feld kann
// zu Beginn jede Zahl stehen
end;
procedure TForm1.StringGrid1Click(Sender: TObject);
begin
RestMengeAnzeigen;
end;
procedure TForm1.RestMengeNeuZuordnen(EingegebeneZahl:integer);
var NeueZahl:Zahlen;
i:integer;
begin
FeldMenge[StringGrid1.col,StringGrid1.row]:=[]; //da bereits eine Zahl drinsteht
For i:=0 to 8 do
begin
FeldMenge[StringGrid1.col,i]:=FeldMenge[StringGrid1.col,i]-NeueZahl;
FeldMenge[i,StringGrid1.row]:=FeldMenge[i,StringGrid1.row]-NeueZahl;
//Die Zahl aus den Restmengen der Zellen der gleichen Spalte und Zeile löschen)
end;
end;
procedure TForm1.RestMengeAnzeigen;
var RestMengeDerZelle:Zahlen;
begin
RestMengeDerZelle:=FeldMenge[StringGrid1.col,StringGrid1.row];
If 1 in RestMengeDerZelle then Stringgrid2.Cells[0,0]:='1';
If 2 in RestMengeDerZelle then Stringgrid2.Cells[1,0]:='2';
If 3 in RestMengeDerZelle then Stringgrid2.Cells[2,0]:='3';
If 4 in RestMengeDerZelle then Stringgrid2.Cells[0,1]:='4';
If 5 in RestMengeDerZelle then Stringgrid2.Cells[1,1]:='5';
If 6 in RestMengeDerZelle then Stringgrid2.Cells[2,1]:='6';
If 7 in RestMengeDerZelle then Stringgrid2.Cells[0,2]:='7';
If 8 in RestMengeDerZelle then Stringgrid2.Cells[1,2]:='8';
If 9 in RestMengeDerZelle then Stringgrid2.Cells[2,2]:='9';
//geht das irgendwie eleganter ?
StringGrid1.SetFocus;
end;
end.
Das Problem: es funktioniert nicht! Gebe ich z.B. in [0,0] eine Zahl ein und klicke auf [0,1], so zeigt er mir als FeldMenge [1,2,5,6] an -unabhängig von der eingegebenen Zahl. Klicke ich nun auf ein Feld, das nicht in der selben Spalte oder Zeile liegt, so gibt er mir [1,2,3,4,5,6,7,8,9] aus, was ja auch stimmt.
Klicke ich dann aber wieder auf [0,1], so gibt er mir wieder [1,2,3,4,5,6,7,8,9] aus!
Ich weiß ehrlich gesagt überhaupt nicht, wo mein Fehler liegt und ich wäre für jede Hilfe sehr dankbar!