//=========================================================================== // SUDOKU // 24 May 2006 //=========================================================================== // Place a StringGrid component on the Form (5th icon under Additional tab) // Look in "Help" under "TStringGrid" // Property changes: // Align = alCustom // FixedCols = 0, FixedRows = 0 // DefaultColWidth = 30, DefaultRowHeight = 30 // ColCount = 9, RowCount = 9 // ScrollBars = ssNone // Height = 282, Width = 282 // Font->Size = 18 // Options: goEditing = true // // You need to paste in an OpenDialog component (Dialogs tab) // You need to paste in a SaveDialog component (Dialogs tab) //=========================================================================== //--------------------------------------------------------------------------- #include #pragma hdrstop #include "Unit1.h" #include // for streaming file handling //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { DoubleBuffered = true; // eliminates flicker } //--------------------------------------------------------------------------- //=========================================================================== // VARIABLES //=========================================================================== bool cellSelected = true; int numSelected; int col, row; int enteredCol, enteredRow; int tally[10] = {0}; // tally for duplicate digits //=========================================================================== // FUNCTIONS //=========================================================================== //--------------------------------------------------------------------- CLEAR void clear (void) { for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { Form1->StringGrid1->Cells[i][j] = ""; } } } //---------------------------------------------------------------- DRAW LINES void drawLines (void) { Form1->StringGrid1->Canvas->Pen->Color = clBlack; Form1->StringGrid1->Canvas->Pen->Width = 3; Form1->StringGrid1->Canvas->MoveTo(0, 92); Form1->StringGrid1->Canvas->LineTo(282, 92); Form1->StringGrid1->Canvas->MoveTo(0, 184); Form1->StringGrid1->Canvas->LineTo(282, 184); Form1->StringGrid1->Canvas->MoveTo(92, 0); Form1->StringGrid1->Canvas->LineTo(92, 282); Form1->StringGrid1->Canvas->MoveTo(184, 0); Form1->StringGrid1->Canvas->LineTo(184, 282); Application->ProcessMessages(); } //--------------------------------------------------------------- ERROR FOUND void errorFound (void) { Form1->Color = clRed; Application->ProcessMessages(); Sleep(200); Application->ProcessMessages(); Form1->Color = clBtnFace; Form1->StringGrid1->Cells[enteredCol][enteredRow] = ""; drawLines(); Application->ProcessMessages(); } //-------------------------------------------------------------- TALLY DIGITS void clearTally (void) { for (int i = 0; i < 10; i++) tally[i] = 0; } //---------------------------------------------------------- CHECK FOR ERRORS void checkForErrors (void) { // check columns for (int col = 0; col < 9; col++) { clearTally(); for (int row = 0; row < 9; row++) { if (Form1->StringGrid1->Cells[col][row] != "") { int num = StrToInt(Form1->StringGrid1->Cells[col][row]); tally[num]++; if (tally[num] > 1) errorFound(); } } } // check rows for (int row = 0; row < 9; row++) { clearTally(); for (int col = 0; col < 9; col++) { if (Form1->StringGrid1->Cells[col][row] != "") { int num = StrToInt(Form1->StringGrid1->Cells[col][row]); tally[num]++; if (tally[num] > 1) errorFound(); } } } // check block 1: clearTally(); for (int col = 0; col < 3; col++) { for (int row = 0; row < 3; row++) { if (Form1->StringGrid1->Cells[col][row] != "") { int num = StrToInt(Form1->StringGrid1->Cells[col][row]); tally[num]++; if (tally[num] > 1) errorFound(); } } } // check block 2: clearTally(); for (int col = 3; col < 6; col++) { for (int row = 0; row < 3; row++) { if (Form1->StringGrid1->Cells[col][row] != "") { int num = StrToInt(Form1->StringGrid1->Cells[col][row]); tally[num]++; if (tally[num] > 1) errorFound(); } } } // check block 3: clearTally(); for (int col = 6; col < 9; col++) { for (int row = 0; row < 3; row++) { if (Form1->StringGrid1->Cells[col][row] != "") { int num = StrToInt(Form1->StringGrid1->Cells[col][row]); tally[num]++; if (tally[num] > 1) errorFound(); } } } // check block 4: clearTally(); for (int col = 0; col < 3; col++) { for (int row = 3; row < 6; row++) { if (Form1->StringGrid1->Cells[col][row] != "") { int num = StrToInt(Form1->StringGrid1->Cells[col][row]); tally[num]++; if (tally[num] > 1) errorFound(); } } } // check block 5: clearTally(); for (int col = 3; col < 6; col++) { for (int row = 3; row < 6; row++) { if (Form1->StringGrid1->Cells[col][row] != "") { int num = StrToInt(Form1->StringGrid1->Cells[col][row]); tally[num]++; if (tally[num] > 1) errorFound(); } } } // check block 6: clearTally(); for (int col = 6; col < 9; col++) { for (int row = 3; row < 6; row++) { if (Form1->StringGrid1->Cells[col][row] != "") { int num = StrToInt(Form1->StringGrid1->Cells[col][row]); tally[num]++; if (tally[num] > 1) errorFound(); } } } // check block 7: clearTally(); for (int col = 0; col < 3; col++) { for (int row = 6; row < 9; row++) { if (Form1->StringGrid1->Cells[col][row] != "") { int num = StrToInt(Form1->StringGrid1->Cells[col][row]); tally[num]++; if (tally[num] > 1) errorFound(); } } } // check block 8: clearTally(); for (int col = 3; col < 6; col++) { for (int row = 6; row < 9; row++) { if (Form1->StringGrid1->Cells[col][row] != "") { int num = StrToInt(Form1->StringGrid1->Cells[col][row]); tally[num]++; if (tally[num] > 1) errorFound(); } } } // check block 9: clearTally(); for (int col = 6; col < 9; col++) { for (int row = 6; row < 9; row++) { if (Form1->StringGrid1->Cells[col][row] != "") { int num = StrToInt(Form1->StringGrid1->Cells[col][row]); tally[num]++; if (tally[num] > 1) errorFound(); } } } drawLines(); } //--------------------------------- SAVE THE STUFF THAT WE COMPUTED FUNCTION void saveStuff (void) { if (Form1->SaveDialog1->Execute()) { ofstream outfile(Form1->SaveDialog1->FileName.c_str()); int num; for (int row = 0; row < 9; row++) { for (int col = 0; col < 9; col++) { if (Form1->StringGrid1->Cells[col][row] == "") num = 0; else num = StrToInt(Form1->StringGrid1->Cells[col][row]); outfile << num << " "; } outfile << endl; } outfile.close(); } } //--------------------------------------- OPEN THE STUFF THAT WE SAVED BUTTON void openStuff (void) { if (Form1->OpenDialog1->Execute()) { ifstream infile(Form1->OpenDialog1->FileName.c_str()); int num; for (int row = 0; row < 9; row++) { for (int col = 0; col < 9; col++) { infile >> num; if (num == 0) Form1->StringGrid1->Cells[col][row] = ""; else Form1->StringGrid1->Cells[col][row] = num; } } infile.close(); } } //=========================================================================== // EVENT HANDLERS //=========================================================================== //-------------------------------------------------------- STRING GRID KEY UP void __fastcall TForm1::StringGrid1KeyUp(TObject *Sender, WORD &Key, TShiftState Shift) { drawLines(); } //----------------------------------------------------- STRING GRID DRAW CELL void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int ACol, int ARow, TRect &Rect, TGridDrawState State) { drawLines(); } //------------------------------------------------- STRING GRID SET EDIT TEXT void __fastcall TForm1::StringGrid1SetEditText(TObject *Sender, int ACol, int ARow, const AnsiString Value) { if (Value == "1" || Value == "2" || Value == "3" || Value == "4" || Value == "5" || Value == "6" || Value == "7" || Value == "8" || Value == "9") { enteredCol = ACol; enteredRow = ARow; checkForErrors(); } else { StringGrid1->Cells[ACol][ARow] = ""; } } //--------------------------------------------------------------- SAVE BUTTON void __fastcall TForm1::ButtonSaveClick(TObject *Sender) { saveStuff(); } //--------------------------------------------------------------- OPEN BUTTON void __fastcall TForm1::ButtonOpenClick(TObject *Sender) { openStuff(); } //-------------------------------------------------------------- CLEAR BUTTON void __fastcall TForm1::ButtonClearClick(TObject *Sender) { clear(); } //---------------------------------------------------------------------------