解数独游戏(Java实现)


  最近正在学习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();
	}
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值