Browse Source

Add files via upload

Windows-GUI v1.1
dnomd343 5 years ago
committed by GitHub
parent
commit
0779ee6267
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 167
      Form1.frm
  2. 74
      Form2.frm
  3. 165
      Form3.frm
  4. 36
      Sudoku.vbp
  5. 235
      Sudoku_Engine.cpp

167
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

74
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

165
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

36
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

235
Sudoku_Engine.cpp

@ -0,0 +1,235 @@
#include<iostream>
#include<vector>
#include<fstream>
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; //当前正在被假设的Item编号
vector <unsigned char> 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 <struct Try_Point_Class> 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"<<endl;
cout<<"Please wait..."<<endl;
Init();
if(Data_Input()==false){cout<<"Something Wrong!"<<endl;return 0;}
unsigned int i;
i=Calculate();
cout<<"Calculate Compete"<<endl;
File_Output.open("Compete");
if(i==0){File_Output<<"Error!!!"<<endl;}
File_Output.close();
return 0;
}
bool Data_Input(){
unsigned char i;
char dat[81];
File_Input.open("Data_Input.txt");
File_Input>>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<<Data<<endl;
}
unsigned int Calculate(){ //主计算函数
unsigned char i;
int Solve_Num=0;
File_Output.open("Data_Output.txt");
Engine(); //初步排除运算
if(Check_Error()==true){File_Output.close();return 0;} //输入的数独有误
if(Check_Compete()==true){Solve_Output();File_Output.close();return 1;} //输入的数独已完成
for(i=0;i<=80;i++){Backup[i]=Base[i];} //备份数据 假设时暂存
Create_New_Point(); //创建假设链根节点
while(1){
for(i=0;i<=(Try.size()-1);i++){ //装载假设链
Base[Try[i].Block_Num].Data=Try[i].Item[Try[i].Point_Num];
}
Engine(); //进行排除运算
if(Check_Error()==true){ //当前假设错误
if(Try_Next()==false){break;} //没有下一个假设,则该数独无解,退出
}
else{ //当前假设可能正确
if(Check_Compete()==false){ //若仍未完成,则创建新的假设节点
Create_New_Point();
}
else{ //已完成
Solve_Output();
Solve_Num++; //答案数目+1
if(Try_Next()==false){break;} //没有下一个假设,求解完成,退出
}
}
}
File_Output.close();
return Solve_Num;
}
bool Try_Next(){ //当前假设错误,装载下一个假设
unsigned char i;
while((Try[Try.size()-1].Point_Num>=(Try[Try.size()-1].Item.size()-1))){
if(Try.size()==1){return false;}
Try.resize(Try.size()-1);
}
Try[Try.size()-1].Point_Num++; //假设链末节点指向下一个Item
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;
}
}
Loading…
Cancel
Save