Java制作数独小游戏

题目要求:
制作一个数独游戏。数据游戏拼图由一个3*3的九宫格组成,每个格式又分成一个小九宫格,共九九八十一个小格子。游戏规则:游戏开始前会有一些格式了写好了1-9的数,在剩下的格式里填写1-9的数,直到把所有格式填满,要求任何一行或一列或者任一个小九宫中没有相同的数字。拼图示例如下:
在这里插入图片描述

任务要求:
(1) 可以根据在九宫格中初始给出的数字个数设定游戏难度,如初始给出30个数设定为难、35个数设定为中等难度、40个数设定为容易。
(2) 对于初始给出的数据要能验证题目的合法性(即验证给出数据本身是否符合游戏规则,行、列及小九宫中不能出现重复数字1-9),对玩游戏中填入的数字在提交后要能验证其正确性(任何一行或一列或者任一个小九宫中没有相同的数字)。
(3) 程序能保存玩家的信息、游戏记录以及成绩(最高分),并能够在游戏结束时查看玩家排名。

工作流程如下:
在这里插入图片描述
该数独游戏需要连接数据库,登录用户和保存数据记录,连接数据库创建表等暂不作显示。主要数独游戏部分(除去登录页面,注册页面,查看排名页面不做显示)分为Main(生成数独,将生成100个数独保存在文件中,也可以不保存,每次生成数独都为一次新的数独不做记录,效率较差)和Play(数独显示页面,同时包括填写数独和判断数独是否正确)两类。
1、Main类

package shudu;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.SystemColor;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Main {
   

     private int[][] Arry;   //得到一个9*9的数独
     private int[][] shudu;  //挖空arry数组中的数字
     private int[][] answer; //存储数独答案
     private int[][] game;  //最终数独
     private int grade; 
     private int[] row; //每一行的个数
     private int[] col;  //每一列的个数
     private int[] places;  //每一个九宫格的个数
     private boolean flag=false;
   //读取文件名
 	private String filename=new String("C:\\Users\\liaolilan\\Desktop\\shudu.txt");
 	 public static void main(String[] args){
   
		  Main mainer=new Main();
		 // mainer.UI();
	  }
     
     public void  UI(){
   
    	 for(int k=0;k<100;k++){
   
    		 this.Arry=new int[9][9];
        	 this.shudu=new int[9][9];
        	 this.game=new int[9][9];
        	 this.answer=new int[9][9];
        	 this.row=new int[9];
        	 this.col=new int[9];
        	 this.places=new int[9];
        	 this.grade=grade;
        	 flag=false;
    	 //初始化数组
    	 for(int i=0;i<9;i++)
    		 row[i]=col[i]=places[i]=9;
    	 //调试
    	// this.answer=new int[9][9]; //最终答案存储再arry中
    	 rand();//先产生15个随机数加上随机位置,一定需要随机生成,不然就会一直都是一个数组
    	 
    	 for(int i=0;i<9;i++){
   
    		 for(int j=0;j<9;j++)
    			 System.out.print(Arry[i][j]);
    		 System.out.println();
    	 }
    	 dfs(Arry,0);//获得一个数组答案d
	
    	// diger(grade);//挖空数组
		//将100个数独写入文件中
    	
    	 try{
   
    	      String data = "";
    	      File file =new File(filename);
    	      //if file doesnt exists, then create it
    	      if(!file.exists()){
   
    	       file.createNewFile();
    	      }
    	      //true = append file
    	      FileWriter fileWritter = new FileWriter(filename,true);
    	             BufferedWriter bufferWritter = new BufferedWriter(fileWritter);
    	             bufferWritter.write(k+1+"\r\n");
    	             for(int i=0;i<9;i++){
   
    	            	 data="";
    	            	 for(int j=0;j<9;j++){
   
    	            		 data=data+answer[i][j]+"";
    	            	 }
    	            	 System.out.println(data);
    	            	 bufferWritter.write(data+"\r\n");
    	             }
    	             bufferWritter.close();
    	         System.out.println("Done");
    	     }catch(IOException e){
   
    	      e.printStackTrace();
    	     }
    	 }
     }
     //随机给数
     public void rand(){
   
    	 int t=0;
    	 //t=14不随机性太高,容易产生没有解的数独,经过参考资料发现,当t=6的时候,几乎100%有解
    	 while(t<6){
   
    		int x=new Random().nextInt(9);
    		int y=new Random().nextInt(9); 
    		int i=new Random().nextInt(9)+1;
    		if(Arry[x][y]==0){
   
    			if(istrue(Arry,x,y,i)){
     //判断数是否能填
    				Arry[x][y]=i;
    				t++;
    			}
    		}
    	 }
     }
     //判断在arry[x][y]上是否能放num
     public boolean istrue(int arry[][],int x,int y,int num){
   
    	 //横竖是否有num
		for(int i=0;i<9;i++){
   
			if(arry[x][i]==num||arry[i][y]==num)
				return false;
		}
		
		for(int i=(x/3)*3;i<(x/3+1)*3;i++)
			for(int j=(y/3)*3;j<(y/3+1)*3;j++)
				if(arry[i][j]==num)
					return false;
		return true;
     }
     //根据前面放的数获得一个正确的答案,dfs获取
     public void dfs(int arry[][],int n){
   
    	 if(n<81){
   
    		 if(flag==true) return;
    		 int x=n/9;//x第N个数的横坐标
    		 int y=n%9;//y第N个数的纵坐标
    		 if(arry[x][y]==0){
   
    			 //若第N个数为0,没有被填过,则判断0~9是否能被填
    			 for(int i=1;i<10;i++){
   
    				 if(istrue(arry,x,y,i)){
   
    					 //第N个数可以填i,填入然后dfs
    					 arry[x][y]=i;
    					 dfs(arry,n+1);
    					 //dfs回溯
    					 arry[x][y]=0;
    				 }
    			 }
    		 }
    		 else{
   
    			 dfs(arry,n+1);
    		 }
    	 }
    	 else{
   
    		 //获得第一个结果,flag置true!!!!!
    	
    		 flag=true;
    		 //将获得的数组放入shudu中然后再挖空
    		 //if(all==false){
   
    			 for(int i=0;i<9;i++)
    				 for(int j=0;j<9;j++)
    					 shudu[i][j]=answer[i][j]=arry[i][j];
    			 
    			 System.out.println("###################");
    			 for(int i=0;i<9;i++){
   
    		      		for(int j=0;j<9;j++)
    		      			System.out.print(arry[i][j]);
    		      			System.out.println();
    		      		}
    	 } 
     }
     //为了避免数独无解,保证数独有唯一解
     //挖空数组,分难易程度,,grade为挖空个数
     //是否有一个行、列、九宫格已经为空
     boolean emptyrow=false,emptycol=false,emptyplaces=false;
     //挖空数、关卡
     public void diger(int grade,int level){
   
    	 this.shudu=new int[9][9];
    	 this.game=new int[9][9];
    	 this.answer=new int[9][9];
    	 this.row=new int[9];
    	 this.col=new int[9];
    	 this.places=new int[9];
    	 this.grade=grade;
    	  File file=new File(filename);
    	  BufferedReader reader = null;
          try {
   
              System.out.println("以行为单位读取文件内容,一次读一整行:");
              reader = new BufferedReader(new InputStreamReader(new FileInputStream(file),"utf-8"));
             // reader = new BufferedReader(new FileReader(file));
              String tempString = null;
              int line = 1,k=0;
              boolean flag=false;
              // 一次读入一行,直到读入null为文件结束
              while ((tempString = reader.readLine()) != null&&k<9) {
   
                  // 显示行号
                  System.out.println(" line " + line + ": " + tempString);
                  if(tempString.equals(level+"")){
   
                	 flag=true;
                	 continue;
                  }
                 if(flag==true){
   
                	 for(int i=0;i<9;i++)
                		 answer[k][i]=tempString.charAt(i)-48;
                	 k++;
                 }
                  line++;
              }
              reader.close();
          } catch (IOException e) 
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值