Java实现数独小游戏

本文实例为大家分享了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) {
              e.printStackTrace();
          } finally {
              if (reader != null) {
                  try {
                      reader.close();
                  } catch (IOException e1) {
                  }
              }
          }
          for(int i=0;i<9;i++)
           for(int j=0;j<9;j++)
            shudu[i][j]=answer[i][j];
      int t=grade;
      while(t>0){
       //随机抽到x,y
       int x=new Random().nextInt(9);
       int y=new Random().nextInt(9);
       //若x,y没有被挖空则挖空x,y
       if(shudu[x][y]!=0){
        row[x]--;
        col[y]--;
        places[(y/3)*3+x/3]--;
        if((row[x]==0&&emptyrow)||(col[y]==0&&emptycol)||(places[(y/3)*3+x/3]==0&&emptyplaces))
        {
         System.out.println(x+" "+y+" 不可以");
         continue;
        }
        else{
        shudu[x][y]=0;
        t=t-1;}
        if(row[x]==0)
         emptyrow=true;
        if(col[y]==0)
         emptycol=true;
        if(places[(y/3)*3+x/3]==0)
         emptyplaces=true;
       }
      }

      //获得最终游戏数独
       for(int i=0;i<9;i++)
        for(int j=0;j<9;j++)
         game[i][j]=shudu[i][j];

     }
      //获得最终游戏数独
     public int[][] getArr(){
      int t=0;
      for(int i=0;i<9;i++){
       for(int j=0;j<9;j++){
        System.out.print(game[i][j]);
        if(game[i][j]==0)
         t++;

       }
        System.out.println();
       }
   System.out.println("###################");
   System.out.println("挖空数为:"+t);
      return this.game;
     }

     //获得答案数独
     public int[][] getAnswer(){
      for(int i=0;i<9;i++){
        for(int j=0;j<9;j++)
         System.out.print(answer[i][j]);
         System.out.println();
        }
   System.out.println("###################");
      return this.answer;
     }
}

2、Play类

package shudu;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.Border;

import SQLconnect.UserDao;
import shudu.Main;
import vo.User;

//游戏界面的设计
public class Play {

 //设置全局变量,九宫格
 JTextField[][] numberFields=new JTextField[9][9];

 //游戏数独数组
 int[][] gamearr=new int[9][9];

 //游戏答案数组
 int[][] answerarr=new int[9][9];

 //灰色
 Color green=new Color(93, 200, 138);
 Color lightGray = new Color(217, 217, 217);
 Color blue = new Color(102, 183, 255);

 //挖空数!
 private int grade=40;
    //过去的
 private int usedgrade=0;
 //计时器
 Timer time;
 JLabel timeLabel;
 TimerTask task;

 //用标签表示游戏进展
 JLabel labelsc=new JLabel();

 //创建字体,之后所有的字体为该字体
 Font f=new Font("方正仿宋简体", Font.BOLD, 25);

 //选择九宫格中的格子的坐标
 int sx=10;
 int sy=10;

 //是否已经看过答案
    private boolean isanswer;

  //用户名
    JLabel username=new JLabel();
    JLabel usergrade=new JLabel();
    private int gamegrade=0;//游戏分数

    //登录
    login loger=new login();
 User user=loger.user;

 //读取文件名
 private String filename=new String("C:\\Users\\liaolilan\\Desktop\\SuDoKu.txt");

 //以前游戏数组
 private int[][] usedgame=new int[9][9];

 //以前的游戏时间
 private int usedtim=1;

 //判断是不是新用户
  //是否为新用户
 private boolean isnew=true; 

 //保存用户名存在在第几行
 private int act=-1;
 //关卡
 JLabel levels=new JLabel();
 int levs=1;
 //窗口
 private JFrame jf ;
    public Play(){
     //制作游戏界面
     System.out.println(user.getUsername()+" "+user.getUserpwd()+" "+user.getUsergrade());
       jf = new JFrame();
       jf.setTitle("数独游戏");
       jf.setBounds(400, 0, 1100, 1000);
       jf.setResizable(false);//不允许窗口最大化
       jf.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);//不执行任何操作;要求程序在已注册的 WindowListener 对象的 windowClosing 方法中处理该操作
       jf.setLocationRelativeTo(null);//居中,不用定位窗口大小
       jf.setVisible(true);
       //打开时,判断是否上一局游戏
        jf.addWindowListener(new WindowAdapter() {
                  @Override
                  public void windowOpened(WindowEvent arg0) {
                      //如果是新用户,保存数组
                   //保存记录,读取文件,读出文件,在开始游戏的时候读出
                       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;
                              // 一次读入一行,直到读入null为文件结束
                              while ((tempString = reader.readLine()) != null) {
                                  // 显示行号
                                  System.out.println(" line " + line + ": " + tempString);
                                  if(tempString.equals(user.getUsername())){
                                   act=line;
                                   isnew=false;
                                  }
                                  else if(isnew==false){
                                    //关卡
                                    levs=Integer.valueOf(tempString);
                                          System.out.println(levs);
                                          break;
                                  }
                                  line++;
                              }
                              reader.close();
                          } catch (IOException e) {
                              e.printStackTrace();
                          } finally {
                              if (reader != null) {
                                  try {
                                      reader.close();
                                  } catch (IOException e1) {
                                  }
                              }
                          }
                   newGame(grade,levs);
                  }
              });
       //关闭时,保存关卡记录
        jf.addWindowListener(new WindowAdapter() {
                     @Override
                     public void windowClosing(WindowEvent arg0) {
                          BufferedReader reader = null;
                          //保存记录,读取文件,读出文件,在开始游戏的时候读出
                            File file=new File(filename);
                                     int num=0;//第几行
                                  boolean flag=false;
                                  System.out.println("act:"+act);
                                  List list = new ArrayList();
                                  try{
                                   reader = new BufferedReader(new InputStreamReader(new FileInputStream(file),"utf-8"));
                                        // reader = new BufferedReader(new FileReader(file));
                                         String str = null;
                                         // 一次读入一行,直到读入null为文件结束
                                         while ((str = reader.readLine())!= null) {
                                             ++num;
                                             System.out.println(num+"行:"+str);
                                      if(isnew==false&&(num==act||num==act+1)){
                                       System.out.println(str);
                                       continue;
                                      }
                                  list.add(str);
                                  }
                                  }catch(IOException e){
                                       e.printStackTrace();
                                      }
                                  System.out.println("list size:"+list.size());
                                  System.out.println("删除成功");
                                  //重新写入
                                  try{
                                  FileWriter fileWritter = new FileWriter(filename);
                                      BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename), "utf-8"));
                                      //BufferedWriter bw= new BufferedWriter(fileWritter);
                                  for( int i=0;i<list.size();i++ ){
                                  System.out.println("list["+i+"]"+list.get(i));
                                  bw.write(list.get(i).toString());
                                  bw.newLine();
                                  }
                                  String data = user.getUsername();
                                   //用户名,保存用户所通过的关卡?
                                   bw.write(data+"\r\n");
                                   //关卡
                                   bw.write(levs+"\r\n");
                                  System.out.println("Done");
                                  bw.flush();
                                  bw.close();

                             }catch(IOException e){
                                e.printStackTrace();
                               }
                                   System.exit(0);
                     }
                 });
       //中间数独部分

       JPanel bodyPanel=new JPanel();
       bodyPanel.setBackground(lightGray);
       jf.add(bodyPanel,BorderLayout.CENTER);
       bodyPanel.setLayout(new GridLayout(9,9,0,0));

       //右边布局,难易程度,计时,重新开始,换一题等选择按钮
       JPanel rightPanel=new JPanel();
       //宽度大小设置
       rightPanel.setPreferredSize(new Dimension(200, 789));
       jf.add(rightPanel, BorderLayout.EAST);

       //显示用户名和当前分数
       username.setText("用户名:  "+user.getUsername());
       username.setFont(f);
       rightPanel.add(username);
       usergrade.setText("总分数:   "+user.getUsergrade());
       usergrade.setFont(f);
       rightPanel.add(usergrade);
       //显示当前关卡
       levels.setText("关卡:    "+levs);
       levels.setFont(f);
       rightPanel.add(levels);
       //难度选择,默认为容易
       JLabel label1=new JLabel("请选择模式");
       label1.setFont(f);
       rightPanel.add(label1);
       //容易,中等,难
       String[] btnstr={"容易","中等","难"};
       for(int i=0;i<3;i++){
        JButton btn=new JButton(btnstr[i]);
        btn.setFont(f);
        btn.setBackground(lightGray);
        btn.setPreferredSize(new Dimension(120,60));
        //为难度按钮加上监听器
        btn.addActionListener(new funactionListener());

        rightPanel.add(btn);

        //加监听器
       }

       //功能按钮
       JLabel label2=new JLabel("功能按钮 ");
       label2.setFont(f);
       rightPanel.add(label2);
       //换一题
       JButton changebtn=new JButton("换一题");
       changebtn.setFont(f);
       changebtn.setPreferredSize(new Dimension(120,60));
       changebtn.setBackground(lightGray);
       changebtn.setForeground(Color.black);
       changebtn.addActionListener(new funactionListener());
       rightPanel.add(changebtn);

       //重做
       JButton newbtn=new JButton("重玩");
       newbtn.setFont(f);
       newbtn.setPreferredSize(new Dimension(120,60));
       newbtn.setBackground(lightGray);
       newbtn.setForeground(Color.BLACK);
       newbtn.addActionListener(new funactionListener());
       rightPanel.add(newbtn);

       //答案
       JButton answerbtn=new JButton("答案");
       answerbtn.setFont(f);
       answerbtn.setPreferredSize(new Dimension(120,60));
       answerbtn.setBackground(Color.red);
       answerbtn.setForeground(Color.WHITE);
       answerbtn.addActionListener(new funactionListener());
       rightPanel.add(answerbtn);

       //计时
       JLabel label3=new JLabel("    计时    ");
       label3.setFont(f);
       rightPanel.add(label3);
       timeLabel=new JLabel("00:00");
       timeLabel.setFont(f);
       rightPanel.add(timeLabel);

       //放一个游戏进展
       rightPanel.add(labelsc);
       labelsc.setVisible(false);

       //下面布局
       JPanel lastPanel=new JPanel();
       jf.add(lastPanel,BorderLayout.SOUTH);
       lastPanel.setPreferredSize(new Dimension(1333, 100));
       lastPanel.setLayout(new GridLayout(0, 10, 0, 0));

       //放选择按钮
       JButton[] setNum=new JButton[10];
       for(int i=0;i<10;i++){
        if(i==9){
         setNum[i]=new JButton("清除");
         //加清除的监听器
        }
        else{
         setNum[i]=new JButton(i+1+"");
         //加按钮的监听器
        }
        setNum[i].setFont(f);
        setNum[i].setForeground(Color.WHITE);
        setNum[i].setBackground(green);
        setNum[i].setPreferredSize(new Dimension(90,70));
        setNum[i].setFocusPainted(false);
           //加下方按钮监听器
        setNum[i].addActionListener(new buttonaction());
        lastPanel.add(setNum[i]);
       }
       //对中间布局进行控制
       //组件边框
       Border centernBorder = BorderFactory.createMatteBorder(1, 1, 1, 1, Color.GRAY);
       Border rightAndBottomBorder = BorderFactory.createMatteBorder(1, 1, 4, 4, Color.GRAY);
       Border bottomBorder = BorderFactory.createMatteBorder(1, 1, 4, 1, Color.GRAY);
       Border rightBorder = BorderFactory.createMatteBorder(1, 1, 1, 4, Color.GRAY);
             //循环设置组件JTextField,九宫格
       //numberFields = new JTextField[9][9];
       for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
         //System.out.println(i+j+"");
         numberFields[i][j] = new JTextField();
         //不可编辑
         numberFields[i][j].setEditable(false);
         numberFields[i][j].setFont(new Font("微软雅黑", Font.BOLD, 35));
         numberFields[i][j].setHorizontalAlignment(JTextField.CENTER);
         numberFields[i][j].setBackground(Color.WHITE);
         numberFields[i][j].setForeground(Color.BLACK);
         //加边框!
         if (i == 2 && j == 2 || i == 2 && j == 5 || i == 5 && j == 2 || i == 5 && j == 5) {
          numberFields[i][j].setBorder(rightAndBottomBorder);
         } else if (j == 2 || j == 5) {
          numberFields[i][j].setBorder(rightBorder);
         } else if (i == 2 || i == 5) {
          numberFields[i][j].setBorder(bottomBorder);
         } else {
          numberFields[i][j].setBorder(centernBorder);
         }
         //对每个格子加上名称来标识
         numberFields[i][j].setName(Integer.toString(i) + Integer.toString(j));

         //对每个格子加上监听器
         numberFields[i][j].addFocusListener(new textfocusaction());;
         bodyPanel.add(numberFields[i][j]);
        }
       }
    }
    //开始新游戏
    public void newGame(int grade,int level){
     isanswer=false;
     //显示总分数
     usergrade.setText("总分数: "+user.getUsergrade());
     //显示当前关卡
  levels.setText("关卡:"+levs+"");
     Main maker=new Main();
     maker.diger(grade, level);
     gamearr=maker.getArr();
     answerarr=maker.getAnswer();
     for(int i=0;i<9;i++){
        for(int j=0;j<9;j++)
         System.out.print(answerarr[i][j]);
         System.out.println();
        }
   System.out.println("###################");
     //先清空九宫格
     for(int i=0;i<9;i++)
      for(int j=0;j<9;j++){
       if(gamearr[i][j]!=0){
        numberFields[i][j].setText(gamearr[i][j]+"");
        numberFields[i][j].setBackground(lightGray);
        numberFields[i][j].setForeground(Color.BLACK);
        //加监听器!
       }
       else{
        numberFields[i][j].setText("");
        numberFields[i][j].setBackground(Color.WHITE);
        numberFields[i][j].setForeground(Color.BLACK);
       }
      }
     //开始计时
     startTime();
    }

    //游戏开始计时
    public void startTime(){
     //游戏开始计时!
  time = new Timer();
  task = new TimerTask() {
   int count = usedtim;

   @Override
   public void run() {

    timeLabel.setText(gettime(count));
    count++;
   }
  };
  time.schedule(task, 1000L, 1000L); // 开始游戏时自动计时
    }

    //时间重新计时
    public void restartTime(){
     //删除time记录,要使用过才能删除
     time.cancel();
     time=new Timer();
     timeLabel.setText("00:00");
     task = new TimerTask() {
   int count = 1;

   @Override
   public void run() {

    timeLabel.setText(gettime(count));
    count++;

   }
  };
  time.schedule(task, 1000L, 1000L);
    }
    //将时间转换成分:秒
    public String gettime(int count){
     String second = null;
  String minute = null;
  if (count / 60 < 10) {
   minute = "0" + (count / 60);
  } else {
   minute = "" + (count / 60);
  }
  if (count % 60 < 10) {
   second = ":0" + count % 60;
  } else {
   second = ":" + count % 60;
  }
  return minute + second;

    }

    //重玩该关
    public void again(){
     //重新设置
     for(int i=0;i<9;i++)
      for(int j=0;j<9;j++){
       if(gamearr[i][j]!=0){
        numberFields[i][j].setText(gamearr[i][j]+"");
        numberFields[i][j].setBackground(lightGray);
        //加监听器!
       }
      }
    }

    //输出答案!!
    public void answer(){
     //gamearr中为0的地方放答案!!
     for(int i=0;i<9;i++)
      for(int j=0;j<9;j++){
       if(gamearr[i][j]==0){
        numberFields[i][j].setText(answerarr[i][j]+"");
        numberFields[i][j].setForeground(Color.RED);
       }
      }
    }

    //清空九宫格!!!重新对获取新数独
    public void resetfields(){
     for(int i=0;i<9;i++)
      for(int j=0;j<9;j++){
       numberFields[i][j].setText("");
    numberFields[i][j].setBackground(Color.WHITE);
      }
    }
  //下面为各事件的处理!!!

    //右边处理数独按钮监听器(难度类别监听,换一题,重玩,答案)
    class funactionListener implements ActionListener{
     //难度监听器
        String btnstr;
     @Override
     public void actionPerformed(ActionEvent e) {
      // TODO Auto-generated method stub
      btnstr=e.getActionCommand();
      if(btnstr.equals("容易")){
       grade=40;
       //若选择按钮难度为容易,重新开始游戏
       resetfields();
       newGame(grade,levs);
       restartTime();
      }
      else if(btnstr.equals("中等")){
       grade=45;
       //若选择按钮难度为中等,重新开始游戏
       resetfields();
       newGame(grade,levs);
       restartTime();
      }
      else if(btnstr.equals("难")){
       //同上
       grade=50;
       resetfields();
       newGame(grade,levs);
       restartTime();
      }
      else if(btnstr.equals("换一题")){
       resetfields();
       newGame(grade,levs);
       restartTime();
      }
      //重新开始计分
      else if(btnstr.equals("重玩")){
       resetfields();
       again();
       restartTime();
      }
      //将分归零
      else if(btnstr.equals("答案")){
       answer();
       time.cancel();
       isanswer=true;
      }
     }

    }
    //九宫格数组的监听器
 class textfocusaction implements FocusListener{

   //该各自获得焦点
  @Override
  public void focusGained(FocusEvent e) {
   // TODO Auto-generated method stub
   JTextField jt=(JTextField) e.getSource();
   //点击之前还原颜色
   replace();
   sameNumber(jt);
  }

  //该格子失去焦点,将颜色还原
  @Override
  public void focusLost(FocusEvent e) {
   // TODO Auto-generated method stub
   labelsc.setVisible(false);
   replace();
  }
 }

 //处理获得焦点的文本格子
 public void sameNumber(JTextField jt){
  String name=jt.getName();
  System.out.println(name);
  int x=Integer.parseInt(name.substring(0,1));
  int y=Integer.parseInt(name.substring(1));
  String number=jt.getText();

  //System.out.println(x+"  "+y);
        if(gamearr[x][y]!=0){
         sx=10;
         sy=10;
        }
        else{
         sx=x;
         sy=y;
         System.out.println(sx+"  "+sy);
         //格子为空
         if(number.equals("")){
          //使该行该列和该小九宫格的颜色置blue,提醒用户
          for(int i=0;i<9;i++){
           numberFields[i][sy].setBackground(blue);
           numberFields[sx][i].setBackground(blue);
          }
          for(int i=(sx/3)*3;i<((sx/3)+1)*3;i++)
           for(int j=(sy/3)*3;j<((sy/3)+1)*3;j++)
            numberFields[i][j].setBackground(blue);
          numberFields[sx][sy].setBackground(green);
         }
         //格子不为空,使与格子相同的数显示粉色
         else{
                  for(int i=0;i<9;i++)
                   for(int j=0;j<9;j++)
                    if(numberFields[i][j].getText().equals(number))
                     numberFields[i][j].setBackground(Color.pink);
         }
        }

 }

 //使格子颜色还原
 public void replace(){
  if(sx<10&&sy<10){
   for(int i=0;i<9;i++){
    if(gamearr[i][sy]!=0)
       numberFields[i][sy].setBackground(lightGray);
    else
     numberFields[i][sy].setBackground(Color.WHITE);
    if(gamearr[sx][i]!=0)
           numberFields[sx][i].setBackground(lightGray);
     else
     numberFields[sx][i].setBackground(Color.WHITE);
      }
   for(int i=(sx/3)*3;i<((sx/3)+1)*3;i++)
       for(int j=(sy/3)*3;j<((sy/3)+1)*3;j++)
       if(gamearr[i][j]!=0)
        numberFields[i][j].setBackground(lightGray);
    else
     numberFields[i][j].setBackground(Color.WHITE);
   for(int i=0;i<9;i++)
             for(int j=0;j<9;j++)
              if(numberFields[i][j].getText().equals(numberFields[sx][sy].getText())&&!(i==sx&&j==sy)){
               if(gamearr[i][j]!=0)
              numberFields[i][j].setBackground(lightGray);
       else
        numberFields[i][j].setBackground(Color.WHITE);

              }
  }

 }

 //为下方的按钮增加监听器

 class buttonaction implements ActionListener{

  @Override
  public void actionPerformed(ActionEvent e) {
   // TODO Auto-generated method stub
   String btnstr;
   btnstr=e.getActionCommand();
   replace();
   //如果按钮为清除,则将格子置空
   if(btnstr.equals("清除")&&(sx<10&&sy<10)){
    numberFields[sx][sy].setText("");
    numberFields[sx][sy].setBackground(Color.white);
   }
   //若为其他的,在格子中放入值
   else if(sx<10&&sy<10){
    numberFields[sx][sy].setText(btnstr);
    numberFields[sx][sy].setForeground(Color.blue);
    numberFields[sx][sy].setBackground(Color.white);

    //判断值放的是否正确,若不正确,则将该值和相冲突的格子背景颜色置为红色

    jugewrong(btnstr);
   }
  }

 }

 //判断值放的是否正确,若不正确,则将该值和相冲突的格子背景颜色置为红色
 public void jugewrong(String number){
   boolean flag=false; //该值是否正确
  //行列是否有相同的
  for(int i=0;i<9;i++){
   if(i!=sy&&(numberFields[sx][i].getText().equals(number))){
    numberFields[sx][i].setBackground(Color.red);
    flag=true;
   }
   if(i!=sx&&(numberFields[i][sy].getText().equals(number))){
    numberFields[i][sy].setBackground(Color.red);
    flag=true;
   }
  }
    //小九宫格内是否有已经存在过这个值
  for(int i=(sx/3)*3;i<((sx/3)+1)*3;i++)
   for(int j=(sy/3)*3;j<((sy/3)+1)*3;j++){
    if(!(i==sx&&j==sy)&&(numberFields[i][j].getText().equals(number))){
     numberFields[i][j].setBackground(Color.red);
     flag=true;
    }
   }
  if(flag){
   labelsc.setText("已有该数字,请检查!");
   labelsc.setFont(new Font("方正仿宋简体", Font.BOLD, 21));
   labelsc.setForeground(Color.RED);
   labelsc.setVisible(true);
  }
  else{
   //挑战成功后!!!
   if(isanswer==false&&gamesc()){
    //关卡加一
    levs++;
    time.cancel();
    String runtime=new String();
    runtime=timeLabel.getText();
    System.out.println(runtime);
    //转换成秒
    int tim=((runtime.charAt(0)-48)*10+(runtime.charAt(1))-48)*60+
      (runtime.charAt(3)-48)*10+runtime.charAt(4)-48;
    //计分规则
    System.out.println(tim);
    if(grade==40){
     if(tim<=180)
              gamegrade=80;
     else if(tim<=600)
                    gamegrade=70;
     else if(tim<=1800)
      gamegrade=60;
     else
      gamegrade=50;
    }
    else if(grade==45){
      if(tim<=180)
               gamegrade=90;
      else if(tim<=600)
                     gamegrade=85;
      else if(tim<=1800)
       gamegrade=75;
      else
       gamegrade=65;
    }
    else{
     if(tim<=180)
               gamegrade=100;
      else if(tim<=600)
                     gamegrade=90;
      else if(tim<=1800)
       gamegrade=85;
      else
       gamegrade=80;
    }
    user.setUsergrade(user.getUsergrade()+gamegrade);
    System.out.println(user.getUsergrade());
    UserDao dao=new UserDao();
    dao.modifyuser(user);
    //弹出一个成功的对话框!
    Object[] options = { "查看排名", "继续挑战"};
    //查看排名是0,继续挑战是1
    int x = JOptionPane.showOptionDialog(null, "挑战成功!分数为"+gamegrade,  "挑战成功!",
                  JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options, options[0]);
    System.out.println(x);
    if(x==0){
     rank ranker;
     ranker=new rank();
     //newGame(grade);
    }
    else{
     newGame(grade,levs);
    }
  }
  }

 }
  //判断点完之后数独是否成功!
  public boolean gamesc(){
   for(int i=0;i<9;i++)
    for(int j=0;j<9;j++){
     System.out.println(numberFields[i][j].getText());
     System.out.println("点击!");
     if(numberFields[i][j].getText().equals("")){
     // System.out.println("111失败!");
      return false;
     }
     for(int k=0;k<9;k++)
      if((k!=j&&numberFields[i][k].getText().equals(numberFields[i][j].getText()))||(k!=i&&numberFields[k][j].getText().equals(numberFields[i][j].getText()))){
      numberFields[i][j].setBackground(Color.RED);
      numberFields[i][k].setBackground(Color.red);
       return false;
      }
     for(int m=(i/3)*3;m<(i/3+1)*3;m++)
      for(int n=(j/3)*3;n<(j/3+1)*3;n++)
       if(!(m==i&&n==j)&&(numberFields[m][n].getText().equals(numberFields[i][j].getText())))
       {
        return false;
       }
    }
   System.out.println("成功!");
     return true;
  }

}

最后生成数独页面的效果如下:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java实现解数独的小程序

    前言 数独相信很多人都玩过,趣味性很强,十分的耐玩.可有没有程序员想过玩实现一个数独布局的算法呢?算法是个很有意思,很神奇的东西. 算法如下,需要预先给出几个固定的值,目前解决的一个最难的数独是大概26个已知值的情况,理论上应该能解决任意已知值的数独,不过不知道会不会迭代栈溢出--因为在26个已知值的情况下就迭代了3000多次了,囧~~~ 结果显示如下: 这是已知值: 1 1 2 1 4 8 1 5 5 1 6 1 1 7 7 1 8 3 2 1 1 2 2 6 2 4 4 3 5 9 3 7

  • java版数独游戏核心算法(一)

    之前学习javascript时用javascript写过一个数独游戏,最近看了一点java的内容,于是就心血来潮想搞一个java版的数独游戏. 现在将全部代码分享出来和大家学习交流,当然代码中有着各种各样的问题和不足之处,望各位朋友批评指点. 以下是生成数独地图的核心算法,算法不是很好,也是之前参考过网上的一些思想: package hlc.shudu.src; /* * 数独的帮助类,里面提供数据所需的所有算法 */ public class ShuduHelper { //数独地图数组 pr

  • python实现数独游戏 java简单实现数独游戏

    使用python和java实现数独游戏,有比较才有收获哦. 1.Python版 #--coding:utf-8-- import random import itertools from copy import deepcopy def make_board(m=3): numbers = list(range(1,m**2+1)) #可能出现的数字为1-9 board = None #board是数度二维列表 while board is None: board = get_board(m,n

  • java版数独游戏界面实现(二)

    本文实例为大家分享了java版数独游戏界面实现的具体代码,供大家参考,具体内容如下 实现效果图: 这里写图片描述 主函数用于启动程序: package hlc.shudu.app; import hlc.shudu.src.ShuduHelper; import hlc.shudu.ui.ShuduMainFrame; public class AppStart { public static void main(String[] args) { ShuduMainFrame mainFrame

  • Java实现蓝桥杯数独游戏的示例代码

    你一定听说过"数独"游戏. 如图,玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行.每一列.每一个同色九宫内的数字均含1-9,不重复. 数独的答案都是唯一的,所以,多个解也称为无解. 本图的数字据说是芬兰数学家花了3个月的时间设计出来的较难的题目.但对会使用计算机编程的你来说,恐怕易如反掌了. 本题的要求就是输入数独题目,程序输出数独的唯一解.我们保证所有已知数据的格式都是合法的,并且题目有唯一的解. 格式要求: 输入9行,每行9个数字,0代表未知,其它数字为

  • java数独游戏完整版分享

    本文实例为大家分享了java数独游戏的具体代码,供大家参考,具体内容如下 自己写的数独游戏,共9关,代码如下: 1.DoShudu类用于产生数独数组 import java.util.Random; public class DoShudu { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int[][] cells=newshudu(); //ce

  • Java基于二维数组实现的数独问题示例

    本文实例讲述了Java基于二维数组实现的数独问题.分享给大家供大家参考,具体如下: 这里利用Java二维数组实现数独问题. (1)生成简易数独 (2)生成数独问题** 代码 import java.util.Random; import java.util.ArrayList; public class Suduku { /** *打印二维数组,数独矩阵 */ public static void printArray(int a[][]) { for (int i = 0; i < 9; i+

  • java回溯算法解数独问题

    本文实例为大家分享了java回溯算法解数独问题,供大家参考,具体内容如下 下面来详细讲一下如何用回溯算法来解数独问题. 下图是一个数独题,也是号称世界上最难的数独.当然了,对于计算机程序来说,只要算法是对的,难不难就不知道了,反正计算机又不累.回溯算法基本上就是穷举,解这种数独类的问题逻辑比较简单. 不管算法懂不懂,先把类建出来,变量定义好,那放大学试卷上就是可以拿两分了. package shudu; /** * Created by wolf on 2016/3/17. */ public

  • 简单实现java数独游戏

    本文实例为大家分享了java数独游戏的具体代码,供大家参考,具体内容如下 打算把javaFx需要的组件装好以后直接用javaFx的,但似乎eclipse的版本不对,安装了也不能用... 数独代码是在之前寒假受命写的,学了一个月java的成果,现在看来有些不足但毕竟是第一个程序,就直接放上来,数独终盘的实现直接用了暴力,时间复杂度有点高,懒得改了直接放代码 终盘实现: import java.util.Random; public class SudokuPuzzleGenerator { pri

  • java使用回溯法求解数独示例

    复制代码 代码如下: import java.util.Calendar;import java.util.Date; public class Matrix { private int matrix[][]; private long timeAfter=0;  private long timeBefore =0; public Matrix(int m[][]) {  matrix = new int[9][9];  for (int i=0; i<9 ; i++)   for(int j

随机推荐