最近正在学习Java,所以用Java实现了一个解数独游戏的控制台程序,觉得里面缺点很多,好多代码可以优化,本人初学,希望大家不吝赐教!(本代码系本人初学java时所写,所以存在好多的问题,命名不按规范,当时甚至还不知道有集合的存在!里面有很多的笑话!)
import java.util.*;
class Stack//创建一个栈
{
private int[][] StackData = new int[81][2];//定义一个二维数组用来存放加入的元素的坐标
private int Top=0;
public void getStack(int x,int y)//入栈
{
StackData[Top][0]=x;
StackData[Top][1]=y;
Top++;
}
public void PopStack(int[] x,int[] y)//出栈
{
if(Top!=0)
{
Top--;
x[0] = StackData[Top][0];
y[0]= StackData[Top][1];
}
else
System.out.println("堆栈已空");
}
}
class Sudoku
{
private static final int X=9;
private static final int Y=9;
private int[][] a = {
{0,0,0,7,0,4,0,0,0},
{7,1,0,5,0,6,0,3,8},
{0,0,5,0,1,0,2,0,0},
{5,0,0,0,4,0,0,0,1},
{0,2,6,0,0,0,8,5,0},
{4,0,0,0,9,0,0,0,7},
{0,0,3,0,6,0,9,0,0},
{1,5,0,9,0,2,0,6,3},
{0,0,0,3,0,7,0,0,0}
};//用来装数独数据
Scanner in = new Scanner(System.in);
public void WriteIn()
{
System.out.println("请输入数独数");
for(int k=0;k<9;k++)
for(int v=0;v<9;v++)
{
a[k][v] = in.nextInt();
}
}
public void setA(int x,int y,int temp)//将temp赋给a[y][x];
{
a[y][x]=temp;
}
public void getA()//输出数独数据
{
for(int i=0;i<Y;i++)
{
for(int j=0;j<X;j++)
System.out.printf("%2d",a[i][j]);
System.out.println();
}
}
public boolean FindEmpty(int[] x,int[] y)//查找数独数据为空的找到第一个停止将坐标返回
{
for(int i=0;i<Y;i++)
for(int j=0;j<X;j++)
{
if(a[i][j]==0)
{
y[0]=i;
x[0]=j;
return true;
}
}
return false;
}
public boolean FindEqual(int x,int y,int b)//查看b数据是否复合规则
{
int i;
int j;
for(i=0;i<9;i++)
{
if(a[y][i]==b)
{
return false;
}
if(a[i][x]==b)
{
return false;
}
}
if(x<3&&y<3)
{
for(i=0;i<3;i++)
for(j=0;j<3;j++)
{
if(a[i][j]==b)
return false;
}
}
else if(x<3&&(y>2&&y<6))
{
for(i=3;i<6;i++)
for(j=0;j<3;j++)
{
if(a[i][j]==b)
return false;
}
}
else if(x<3&&y>5)
{
for(i=6;i<9;i++)
for(j=0;j<3;j++)
{
if(a[i][j]==b)
return false;
}
}
else if((x>2&&x<6)&&y<3)
{
for(i=0;i<3;i++)
for(j=3;j<6;j++)
{
if(a[i][j]==b)
return false;
}
}
else if((x>2&&x<6)&&(y>2&&y<6))
{
for(i=3;i<6;i++)
for(j=3;j<6;j++)
{
if(a[i][j]==b)
return false;
}
}
else if((x>2&&x<6)&&y>5)
{
for(i=6;i<9;i++)
for(j=3;j<6;j++)
{
if(a[i][j]==b)
return false;
}
}
else if(x>5&&y<3)
{
for(i=0;i<3;i++)
for(j=6;j<9;j++)
{
if(a[i][j]==b)
return false;
}
}
else if(x>5&&(y>2&&y<6))
{
for(i=3;i<6;i++)
for(j=6;j<9;j++)
{
if(a[i][j]==b)
return false;
}
}
else if(x>5&&y>5)
{
for(i=6;i<9;i++)
for(j=6;j<9;j++)
{
if(a[i][j]==b)
return false;
}
}
return true;
}
}
class Temp//用来装尝试过的数据
{
private int[][][] TryData = new int[9][9][9];//为每一个格子创建一个大小为9的数组用来装尝试过的数据
private int [][] Size ={
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0}
} ;//为每一个格子创建一个数组初始为0用来装尝试过的数据的数组的大小
public void getTry(int x,int y,int TryData_1)
{
TryData[y][x][(Size[y][x])]=TryData_1;
(Size[y][x])++;
}
public boolean FindTry(int x,int y,int temp)//查看temp数据是否已被尝试过
{
for(int j=0;j<Size[y][x];j++)
{
if(temp==TryData[y][x][j])
{
return false;
}
}
return true;
}
public void setSize(int x,int y)//将Size对应的坐标设置为0
{
Size[y][x]=0;
}
}
class SokudoDemo
{
public static void main(String [] arge)
{
boolean flag = false;
int[] EmptyX = new int[1];//存储空格子的坐标
int[] EmptyY = new int[1];
int[] PopStaX = new int[1];//存储出栈的数据
int[] PopStaY = new int[1];
int x ;
int y ;
boolean m = true;
Stack Sta = new Stack();
Temp Tem= new Temp();
Sudoku Sok = new Sudoku();
System.out.println("使用方法如下:");
Sok.getA();
System.out.println("按照上面方式将数独数输入\n数与数之间用空格隔开(空格子用0表示)");
Sok.WriteIn();
System.out.println("………………………………………………………………………………………………………………………………………………………………………………\n得出的结果为:");
while(Sok.FindEmpty(EmptyX,EmptyY))
{
x = EmptyX[0];
y = EmptyY[0];
for(int i=1;i<10;i++)
{
if(Sok.FindEqual(x,y,i)&&Tem.FindTry(x,y,i))//判断i数据是否符合基本规则和是否被尝试过
{
Sok.setA(x,y,i);//将i数据加入到坐标为x.y格子里
Sta.getStack(x,y);//将x.y坐标入栈
Tem.getTry(x,y,i);//将i数据加入到已尝试数组坐标为x.y
flag=false;
break;
}
else
flag =true;
}
if(flag)
{
Sta.PopStack(PopStaX,PopStaY);//出栈
Sok.setA(PopStaX[0],PopStaY[0],0);//将坐标为PopStaX[0].PopStaY[0]的数据归0
Tem.setSize(x,y);//将坐标为x.y的已尝试过数组大小归0
flag=false;
}
}
Sok.getA();
}
}