diff --git a/Form1.frm b/Form1.frm new file mode 100644 index 0000000..38ca8ca --- /dev/null +++ b/Form1.frm @@ -0,0 +1,167 @@ +VERSION 5.00 +Begin VB.Form Form1 + AutoRedraw = -1 'True + BorderStyle = 1 'Fixed Single + Caption = "Sudoku Calculator" + ClientHeight = 9045 + ClientLeft = 45 + ClientTop = 390 + ClientWidth = 8730 + LinkTopic = "Form1" + MaxButton = 0 'False + MinButton = 0 'False + ScaleHeight = 9045 + ScaleWidth = 8730 + StartUpPosition = 2 '屏幕中心 + Begin VB.CommandButton Command4 + Caption = "Clear" + Height = 375 + Left = 4440 + TabIndex = 4 + Top = 8520 + Width = 1965 + End + Begin VB.CommandButton Command3 + Caption = "Save" + Height = 375 + Left = 2400 + TabIndex = 3 + Top = 8520 + Width = 1965 + End + Begin VB.CommandButton Command2 + Caption = "Open" + Height = 375 + Left = 360 + TabIndex = 2 + Top = 8520 + Width = 1965 + End + Begin VB.CommandButton Command1 + Caption = "Calculate" + Height = 375 + Left = 6480 + TabIndex = 1 + Top = 8520 + Width = 1965 + End + Begin VB.TextBox Text + Height = 300 + Index = 0 + Left = 0 + TabIndex = 0 + Top = 0 + Visible = 0 'False + Width = 300 + End +End +Attribute VB_Name = "Form1" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = True +Attribute VB_Exposed = False +Option Explicit +Dim Start_X, Start_Y, Square_Length, Distance As Integer +Private Sub Init_Object() + Cls + Dim x, y, i + For x = 1 To 9 + For y = 1 To 9 + i = x + y * 9 - 9 + Text(i).Text = "" + Text(i).FontSize = 40 + Text(i).MaxLength = 1 + Text(i).Width = Square_Length + Text(i).Height = Square_Length + Text(i).Left = Start_X + Distance * (x - 0.5) + Square_Length * (x - 1) + Text(i).Top = Start_Y + Distance * (y - 0.5) + Square_Length * (y - 1) + Next y + Next x + For i = 0 To 9 + If Int(i / 3) = i / 3 Then DrawWidth = 3 Else DrawWidth = 1 + Line (Start_X, Start_Y + (Square_Length + Distance) * i)-(Start_X + (Square_Length + Distance) * 9, Start_Y + (Square_Length + Distance) * i) + Line (Start_X + (Square_Length + Distance) * i, Start_Y)-(Start_X + (Square_Length + Distance) * i, Start_Y + (Square_Length + Distance) * 9) + Next i +End Sub +Private Sub Form_Activate() + Text(1).SetFocus +End Sub +Private Sub Form_Load() + Dim i As Integer + For i = 1 To 81 + Load Text(i) + Text(i).Left = 0 + Text(i).Alignment = 2 + Text(i).Appearance = 0 + Text(i).BackColor = Form1.BackColor + Text(i).BorderStyle = 0 + Text(i).FontSize = 40 + Text(i).MaxLength = 1 + Text(i).Visible = True + Next i + Start_X = 300: Start_Y = 300 + Square_Length = 800 + Distance = 100 + Call Init_Object +End Sub +Private Sub Command2_Click() + On Error Resume Next + Dim i As Integer, dat As String + If Dir(App.Path & "\temp") = "" Then + MsgBox "No Saved File" + Exit Sub + End If + For i = 1 To 81 + Text(i).Text = "" + Next i + Open App.Path & "\temp" For Input As #1 + Line Input #1, dat + For i = 1 To 81 + If Mid(dat, i, 1) <> "0" Then Text(i).Text = Mid(dat, i, 1) + Next i + Close #1 +End Sub +Private Sub Command3_Click() + On Error Resume Next + Dim i As Integer + Open App.Path & "\temp" For Output As #1 + For i = 1 To 81 + Print #1, Trim(Val(Text(i).Text)); + Next i + Close #1 + If Dir(App.Path & "\temp") <> "" Then + MsgBox "Saved Successfully" + Else + MsgBox "Failed Save" + End If +End Sub +Private Sub Command4_Click() + Dim i As Integer + If MsgBox("Are you sure ?", vbQuestion + vbYesNo, "Tips") = vbYes Then + For i = 1 To 81 + Text(i).Text = "" + Next i + End If +End Sub +Private Sub Command1_Click() + On Error Resume Next + Dim i As Integer + Open App.Path & "\Data_Input.txt" For Output As #1 + For i = 1 To 81 + Print #1, Trim(Val(Text(i).Text)); + Next i + Close #1 + Kill App.Path & "\Compete" + If Dir(App.Path & "\Sudoku_Engine.exe") = "" Then + MsgBox "Sudoku Engine not Found", vbCritical + Exit Sub + Else + Shell App.Path & "\Sudoku_Engine.exe" + End If + Form2.Timer1.Enabled = True + Form2.Show 1 +End Sub +Private Sub Form_Unload(Cancel As Integer) + On Error Resume Next + Kill App.Path & "\Compete" +End Sub diff --git a/Form2.frm b/Form2.frm new file mode 100644 index 0000000..33bbb90 --- /dev/null +++ b/Form2.frm @@ -0,0 +1,74 @@ +VERSION 5.00 +Begin VB.Form Form2 + BorderStyle = 0 'None + Caption = "Please Wait..." + ClientHeight = 660 + ClientLeft = 0 + ClientTop = 0 + ClientWidth = 3240 + LinkTopic = "Form2" + MaxButton = 0 'False + MinButton = 0 'False + ScaleHeight = 660 + ScaleWidth = 3240 + ShowInTaskbar = 0 'False + StartUpPosition = 2 '屏幕中心 + Begin VB.Timer Timer1 + Interval = 300 + Left = 0 + Top = 0 + End + Begin VB.Label Label1 + AutoSize = -1 'True + Caption = "Please Wait..." + BeginProperty Font + Name = "宋体" + Size = 26.25 + Charset = 134 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 690 + Left = 0 + TabIndex = 0 + ToolTipText = "Double Click to Exit..." + Top = 0 + Width = 3240 + End +End +Attribute VB_Name = "Form2" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = True +Attribute VB_Exposed = False +Private Sub Form_DblClick() + If MsgBox("Are you sure to exit?", vbQuestion + vbOKCancel, "Tips") = vbOK Then + Shell "taskkill /f /im Sudoku_Engine.exe" + Timer1.Enabled = False + Form2.Hide + End If +End Sub +Private Sub Label1_DblClick() + Call Form_DblClick +End Sub +Private Sub Timer1_Timer() + On Error Resume Next + If Dir(App.Path & "\Compete") <> "" Then + Open App.Path & "\Compete" For Input As #1 + Line Input #1, dat + If Trim(dat) = "Error!!!" Then + MsgBox "Error or No-Solution", vbCritical + Timer1.Enabled = False + Form2.Hide + Close #1 + Exit Sub + End If + Close #1 + Timer1.Enabled = False + Form1.Visible = False + Form2.Hide + Form3.Show + End If +End Sub diff --git a/Form3.frm b/Form3.frm new file mode 100644 index 0000000..9bba45c --- /dev/null +++ b/Form3.frm @@ -0,0 +1,165 @@ +VERSION 5.00 +Begin VB.Form Form3 + AutoRedraw = -1 'True + BorderStyle = 1 'Fixed Single + Caption = "Sudoku Displayer" + ClientHeight = 8985 + ClientLeft = 45 + ClientTop = 375 + ClientWidth = 8730 + LinkTopic = "Form3" + MaxButton = 0 'False + MinButton = 0 'False + ScaleHeight = 8985 + ScaleWidth = 8730 + StartUpPosition = 2 '屏幕中心 + Begin VB.CommandButton Command3 + Caption = "-" + Height = 375 + Left = 3600 + TabIndex = 3 + Top = 8520 + Width = 1455 + End + Begin VB.CommandButton Command2 + Caption = ">" + Height = 375 + Left = 5160 + TabIndex = 0 + Top = 8520 + Width = 3015 + End + Begin VB.CommandButton Command1 + Caption = "<" + Height = 375 + Left = 480 + TabIndex = 2 + ToolTipText = "Try to Press A or D..." + Top = 8520 + Width = 3015 + End + Begin VB.Timer Timer1 + Interval = 5000 + Left = 0 + Top = 0 + End + Begin VB.TextBox Text + Height = 300 + Index = 0 + Left = 0 + TabIndex = 1 + Top = 0 + Visible = 0 'False + Width = 300 + End +End +Attribute VB_Name = "Form3" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = True +Attribute VB_Exposed = False +Dim Input_Data() As String +Dim Start_X, Start_Y, Square_Length, Distance As Integer +Dim use As Long +Private Sub Init_Object() + On Error Resume Next + Cls + For x = 1 To 9 + For y = 1 To 9 + i = x + y * 9 - 9 + Text(i).Text = "" + Text(i).FontSize = 40 + Text(i).MaxLength = 1 + Text(i).Width = Square_Length + Text(i).Height = Square_Length + Text(i).Left = Start_X + Distance * (x - 0.5) + Square_Length * (x - 1) + Text(i).Top = Start_Y + Distance * (y - 0.5) + Square_Length * (y - 1) + Next y + Next x + For i = 0 To 9 + If Int(i / 3) = i / 3 Then DrawWidth = 3 Else DrawWidth = 1 + Line (Start_X, Start_Y + (Square_Length + Distance) * i)-(Start_X + (Square_Length + Distance) * 9, Start_Y + (Square_Length + Distance) * i) + Line (Start_X + (Square_Length + Distance) * i, Start_Y)-(Start_X + (Square_Length + Distance) * i, Start_Y + (Square_Length + Distance) * 9) + Next i +End Sub +Private Sub Form_Load() + On Error Resume Next + For i = 1 To 81 + Load Text(i) + Text(i).Left = 0 + Text(i).Alignment = 2 + Text(i).Appearance = 0 + Text(i).BackColor = Form3.BackColor + Text(i).BorderStyle = 0 + Text(i).FontSize = 40 + Text(i).MaxLength = 1 + Text(i).Locked = True + Text(i).Visible = True + Next i + Start_X = 300: Start_Y = 300 + Square_Length = 800 + Distance = 100 + Call Init_Object + Call Data_Input + Call Data_Output(0) + use = 0 +End Sub +Private Sub Data_Input() + Open App.Path & "\Data_Input.txt" For Input As #1 + Line Input #1, dat + For i = 1 To 81 + If Mid(dat, i, 1) <> "0" Then Text(i).ForeColor = vbRed + Next i + Close #1 + Open App.Path & "\Data_Output.txt" For Input As #1 + ReDim Input_Data(0) + Do While Not EOF(1) + Line Input #1, Input_Data(UBound(Input_Data)) + ReDim Preserve Input_Data(UBound(Input_Data) + 1) + Loop + Close #1 +End Sub +Private Sub Data_Output(Num As Long) + dat = Input_Data(Num) + Form3.Caption = "Sudoku Displayer(" & Trim(Num + 1) & "/" & Trim(UBound(Input_Data)) & ")" + Call Init_Object + For i = 1 To 81 + Text(i).FontSize = 40 + Text(i).MaxLength = 1 + a = Mid(dat, i, 1) + If a = "0" Then a = "" + Text(i).Text = a + Next i +End Sub +Private Sub Command1_Click() + If use > 0 Then use = use - 1 + Call Data_Output(use) +End Sub +Private Sub Command2_Click() + If use < UBound(Input_Data) - 1 Then use = use + 1 + Call Data_Output(use) +End Sub +Private Sub Command3_Click() + On Error Resume Next + dat = Int(InputBox("Please input a number", "Tips")) - 1 + If dat >= 0 And dat < UBound(Input_Data) Then use = dat: Data_Output (use) +End Sub +Private Sub Command1_KeyPress(KeyAscii As Integer) + If KeyAscii = 97 Then Call Command1_Click + If KeyAscii = 100 Then Call Command2_Click +End Sub +Private Sub Command2_KeyPress(KeyAscii As Integer) + If KeyAscii = 97 Then Call Command1_Click + If KeyAscii = 100 Then Call Command2_Click +End Sub +Private Sub Command3_KeyPress(KeyAscii As Integer) + If KeyAscii = 97 Then Call Command1_Click + If KeyAscii = 100 Then Call Command2_Click +End Sub +Private Sub Form_DblClick() + Call Data_Input + Call Data_Output(use) +End Sub +Private Sub Form_Unload(Cancel As Integer) + Form1.Visible = True +End Sub diff --git a/Sudoku.vbp b/Sudoku.vbp new file mode 100644 index 0000000..695938f --- /dev/null +++ b/Sudoku.vbp @@ -0,0 +1,36 @@ +Type=Exe +Form=Form1.frm +Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\..\..\..\..\..\Windows\SysWOW64\stdole2.tlb#OLE Automation +Form=Form2.frm +Form=Form3.frm +IconForm="Form1" +Startup="Form1" +HelpFile="" +Title="Sudoku" +ExeName32="Sudoku.exe" +Command32="" +Name="Sudoku" +HelpContextID="0" +CompatibleMode="0" +MajorVer=1 +MinorVer=0 +RevisionVer=0 +AutoIncrementVer=0 +ServerSupportFiles=0 +VersionCompanyName="Dnomd343" +VersionProductName="Sudoku Calculator" +CompilationType=0 +OptimizationType=0 +FavorPentiumPro(tm)=0 +CodeViewDebugInfo=0 +NoAliasing=0 +BoundsCheck=0 +OverflowCheck=0 +FlPointCheck=0 +FDIVCheck=0 +UnroundedFP=0 +StartMode=0 +Unattended=0 +Retained=0 +ThreadPerObject=0 +MaxNumberOfThreads=1 \ No newline at end of file diff --git a/Sudoku_Engine.cpp b/Sudoku_Engine.cpp new file mode 100644 index 0000000..f48851b --- /dev/null +++ b/Sudoku_Engine.cpp @@ -0,0 +1,235 @@ +#include +#include +#include +using namespace std; +ifstream File_Input; +ofstream File_Output; + +struct Sudoku_Class{ //涓涓鏍肩殑鍐呭 + unsigned char Data; //鏁板瓧1~9锛0琛ㄧず鏈畬鎴 + bool May[9]; //鍋囪鏁 +}; +struct Try_Point_Class{ //鍋囪閾句笂鐨勮妭鐐 + unsigned char Block_Num; //琚亣璁剧殑瀹牸缂栧彿 + unsigned char Point_Num; //褰撳墠姝e湪琚亣璁剧殑Item缂栧彿 + vector Item; //鑺傜偣涓殑鎵鏈夊亣璁炬暟 +}; + +struct Sudoku_Class Base[81]; //鍏ㄩ儴81涓鏍 +struct Sudoku_Class Backup[81]; //杩涜鍋囪鐨勬椂鍊欐殏瀛樹娇鐢 +unsigned char Addr_Kind[3][9][9]; //琛屽垪瀹搴旂殑浣嶇疆琛 +unsigned char Addr_Block[81][3]; //瀹牸鎵鍦ㄨ鍒楀鐨勭紪鍙 +vector Try; //鍋囪閾 +struct Try_Point_Class Empty_Point; //绌虹殑鍋囪鑺傜偣 + +void Init(); +void Analyse(); +void Engine(); +bool Check_Compete(); +bool Check_Error(); +void Create_New_Point(); +void Solve_Output(); +bool Try_Next(); +bool Data_Input(); +unsigned int Calculate(); +unsigned char Next_Empty_Block(unsigned char Start); +void Init_Point(unsigned char Block_Num,unsigned char Point_Num); + +int main(){ + cout<<"Welcome to Sudoku-Calculator by Dnomd343"<>dat; + File_Input.close(); + for(i=0;i<=80;i++){ + Base[i].Data=dat[i]-48; + if(Base[i].Data>9){return false;} + } + return true; +} +void Solve_Output(){ + unsigned char i; + char Data[82]; + for(i=0;i<=80;i++){ + Data[i]=Base[i].Data+48; + } + Data[81]=0; + File_Output<=(Try[Try.size()-1].Item.size()-1))){ + if(Try.size()==1){return false;} + Try.resize(Try.size()-1); + } + Try[Try.size()-1].Point_Num++; //鍋囪閾炬湯鑺傜偣鎸囧悜涓嬩竴涓狪tem + for(i=0;i<=80;i++){ //灏嗗浠芥暟鎹噸鏂拌杞 + Base[i]=Backup[i]; + } + return true; //鎴愬姛 +} +void Create_New_Point(){ //鍒涘缓鏂扮殑鍋囪閾捐妭鐐 + Try.push_back(Empty_Point); + if(Try.size()==1){ //鑻ヤ负鏍硅妭鐐 + Init_Point(Next_Empty_Block(0),0); //浠庣涓鏍煎紑濮嬫悳绱㈡湭瀹屾垚瀹牸 + } + else{ //鑻ヤ笉鏄牴鑺傜偣 + Init_Point(Next_Empty_Block(Try[Try.size()-2].Block_Num+1),Try.size()-1); //浠庝笂涓鑺傜偣鎸囧悜鐨勫鏍煎紑濮嬫悳绱㈡湭瀹屾垚瀹牸 + } +} +void Init_Point(unsigned char Block_Num,unsigned char Point_Num){ //鍒濆鍖栧亣璁鹃摼鑺傜偣 Block_Num->琚亣璁惧鏍肩殑缂栧彿 Point_Num->鑺傜偣鐨勭紪鍙 + unsigned char i; + Try[Point_Num].Block_Num=Block_Num; + for(i=0;i<=8;i++){ + if(Base[Try[Point_Num].Block_Num].May[i]==true){ //閬嶅巻鐩爣瀹牸鐨勬墍鏈夊亣璁炬暟骞跺姞鍏ュ埌璇ヨ妭鐐圭殑Item涓 + Try[Point_Num].Item.push_back(i+1); + } + } + Try[Point_Num].Point_Num=0; //鎸囧悜Item涓殑绗竴涓亣璁炬暟 +} +unsigned char Next_Empty_Block(unsigned char Start){ //鎵惧埌涓嬩竴涓湭纭畾绛旀鐨勫鏍煎苟杩斿洖鍏剁紪鍙 + unsigned char i; + for(i=Start;i<=80;i++){ + if(Base[i].Data==0){return i;} + } + return 0; //娌℃湁鏈‘瀹氬鏍 +} +bool Check_Error(){ //妫鏌ユ暟鐙槸鍚﹀瓨鍦ㄩ敊璇 + unsigned char kind,num,add,item; + for(kind=0;kind<=2;kind++){ //鍒嗗埆鎵弿琛屽垪瀹 + for(num=0;num<=8;num++){ + for(item=1;item<=9;item++){ + add=0; + for(unsigned char k=0;k<=8;k++){ + if(Base[Addr_Kind[kind][num][k]].Data==item){add++;} + } + if(add>=2){return true;} //鑻ヤ竴缁勮鍒楀涓瓨鍦ㄤ袱涓浉鍚岀殑鏁 -> 閿欒閫鍑 + } + } + } + for(num=0;num<=80;num++){ //鎵弿鍏ㄩ儴瀹牸 + if(Base[num].Data==0){ //鑻ユ湭瀹屾垚 + add=0; + for(unsigned char k=0;k<=8;k++){ //閬嶅巻鍏舵墍鏈夊亣璁炬暟 + if(Base[num].May[k]==true){add++;} + } + if(add==0){return true;} //娌℃湁鍙兘鐨勬暟 -> 閿欒閫鍑 + } + } + return false; //鏆傛椂鏈彂鐜伴敊璇 +} +bool Check_Compete(){ //鍒ゆ柇鏁扮嫭鏄惁瀹屾垚 + unsigned char i; + for(i=0;i<=80;i++){ + if(Base[i].Data==0){return false;} + } + return true; +} +void Engine(){ //浣跨敤鎺掗櫎娉 + unsigned char kind,num,item,add,dat; + bool Could_Solve; + Again:; + Analyse(); //姣忔鎺掗櫎鍓嶅簲鍏堟秷鍘诲亣璁炬暟 + Could_Solve=false; + for(kind=0;kind<=2;kind++){ //鍒嗗埆鎵弿琛屽垪瀹 + for(num=0;num<=8;num++){ + for(item=0;item<=8;item++){ + add=0; + for(unsigned char k=0;k<=8;k++){ + if((Base[Addr_Kind[kind][num][k]].Data==0)&&(Base[Addr_Kind[kind][num][k]].May[item]==true)){add++;dat=k;} //璁板綍涓缁勮鍒楀涓殑鍙兘鏁 + } + if(add==1){Base[Addr_Kind[kind][num][dat]].Data=item+1;Could_Solve=true;} //鑻ヤ粎鏈夊敮涓鍙兘鏁帮紝鍒欒瀹牸绛旀纭畾 + } + } + if(Could_Solve==true){goto Again;} //涓鐩村惊鐜洿鍒版病鏈夋帓闄ゅ璞 + } +} +void Analyse(){ //娑堝幓鍋囪鏁 + unsigned char num,kind,item; + for(num=0;num<=80;num++){ //閬嶅巻鎵鏈夊鏍 + if(Base[num].Data!=0){ //鑻ヨ瀹牸宸插畬鎴 + for(kind=0;kind<=2;kind++){ //鍒嗗埆瀵硅鍒楀鎿嶄綔 + for(item=0;item<=8;item++){ + Base[Addr_Kind[kind][Addr_Block[num][kind]][item]].May[Base[num].Data-1]=false; //娑堝幓鍚岃鍚屽垪鍚屽鐨勫亣璁炬暟 + } + } + } + } +} +void Init(){ //鍒濆鍖栧鍣 + unsigned char i,j,x,y; + for(i=0;i<=8;i++){ //鍒濆鍖栬涓庡垪鐨勪綅缃〃 + for(j=0;j<=8;j++){ + Addr_Kind[0][i][j]=i*9+j; + Addr_Kind[1][i][j]=j*9+i; + } + } + for(x=0;x<=2;x++){ //鍒濆鍖栦節瀹牸鐨勪綅缃〃 + for(y=0;y<=2;y++){ + for(i=0;i<=2;i++){ + for(j=0;j<=2;j++){ + Addr_Kind[2][y*3+x][j*3+i]=(y*3+j)*9+(x*3+i); + } + } + } + } + for(i=0;i<=2;i++){ //鍒濆鍖栧鏍兼墍鍦ㄨ鍒楀鐨勭紪鍙 + for(x=0;x<=8;x++){ + for(y=0;y<=8;y++){ + Addr_Block[Addr_Kind[i][x][y]][i]=x; + } + } + } + for(i=0;i<=80;i++){ //娓呯┖鎵鏈夊亣璁炬暟 + for(j=0;j<=8;j++){ + Base[i].May[j]=true; + } + } + for(i=0;i<=80;i++){ //娓呯┖鎵鏈夋暟瀛 + Base[i].Data=0; + } +}