import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
public class MainFrame extends JFrame{
boolean start = false;//是否开始计时
boolean winCheck = false;//是否要进行胜利判定
int difficulty = 30;//随机产生题目的难度(即随机产生有多少个空格的题目)。默认为产生30个空格的题目
int[][] origin = new int [9][9];//题目数字。
int[][] matrix = new int [9][9];//当前游戏数字填入情况的数据。
JButton[][] jbt = new JButton[9][9];//按钮
Timekeeper time = new Timekeeper();//计时器
MyReader mr = new MyReader("");//读档器
Solver my = new Solver();//解题器
Creator c = new Creator();//随机出题器
JMenuItem jmi1 = new JMenuItem("退出");
JMenuItem jmi2 = new JMenuItem("快速开局");
JMenuItem jmi3 = new JMenuItem("自定义题目");
JMenuItem jmi4 = new JMenuItem("显示答案");
JMenuItem jmi5 = new JMenuItem("保存题目");
JMenuItem jmi6 = new JMenuItem("载入题目并开局");
JMenuItem jmi7 = new JMenuItem("即时存档");
JMenuItem jmi8 = new JMenuItem("载入先前存档并开局");
JMenuItem jmi9 = new JMenuItem("简单");
JMenuItem jmi10 = new JMenuItem("√标准");
JMenuItem jmi11 = new JMenuItem("困难");
JMenuItem jmi12 = new JMenuItem("骨灰");
JMenuItem jmi13 = new JMenuItem("重玩");
public MainFrame(){//主界面
BorderLayout bl = new BorderLayout(5,5);
setLayout(bl);
JMenuBar jmb = new JMenuBar();
JMenu jm1 = new JMenu("模式");
JMenu jm2 = new JMenu("游戏");
JMenu jm3 = new JMenu("自定义题目");
JMenu jm4 = new JMenu("难度设定");
ActionListener exitListener = new ExitListener();
ActionListener startListener = new StartListener();
ActionListener customListener = new CustomListener();
ActionListener loadListener = new LoadListener();
ActionListener saveInGameListener = new SaveInGameListener();
ActionListener answerListener = new AnswerListener();
ActionListener saveListener = new SaveListener();
ActionListener loadInGameListener = new LoadInGameListener();
ActionListener difficultyListener = new DifficultyListener();
ActionListener replayListener = new ReplayListener();
MouseListener buttonListener = new ButtonListener();
jmi1.addActionListener(exitListener);
jmi2.addActionListener(startListener);
jmi3.addActionListener(customListener);
jmi6.addActionListener(loadListener);
jmi4.addActionListener(answerListener);
jmi5.addActionListener(saveListener);
jmi7.addActionListener(saveInGameListener);
jmi8.addActionListener(loadInGameListener);
jmi9.addActionListener(difficultyListener);
jmi10.addActionListener(difficultyListener);
jmi11.addActionListener(difficultyListener);
jmi12.addActionListener(difficultyListener);
jmi13.addActionListener(replayListener);
jmi4.setEnabled(false);
jmi5.setEnabled(false);
jmi7.setEnabled(false);
jmi13.setEnabled(false);
jm1.add(jmi2);
jm1.add(jmi6);
jm1.add(jmi3);
jm1.add(jmi8);
jm1.add(jmi1);
jm2.add(jmi4);
jm2.add(jmi7);
jm2.add(jmi13);
jm3.add(jmi5);
jm4.add(jmi9);
jm4.add(jmi10);
jm4.add(jmi11);
jm4.add(jmi12);
jmb.add(jm1);
jmb.add(jm2);
jmb.add(jm3);
jmb.add(jm4);
add(jmb,bl.NORTH);
JPanel mainPanel = new JPanel();
add(mainPanel,bl.CENTER);
mainPanel.setLayout(new GridLayout(9,9));
for(int i = 0;i < 9;i++){//设定每个按钮大小、是否可用等参数
for(int j = 0;j < 9;j++){
if (matrix[i][j] == 0)jbt[i][j] = new JButton("");
else jbt[i][j] = new JButton("" + matrix[i][j]);
jbt[i][j].setSize(50,50);
jbt[i][j].addMouseListener(buttonListener);
jbt[i][j].setActionCommand("" + i + j);
jbt[i][j].setEnabled(false);//最开始时不能点击
mainPanel.add(jbt[i][j]);
}
}
time.setPreferredSize(new Dimension(0,30));
add(time,bl.SOUTH);
}
void clear(){//在重新开局之后清空上次游戏的数据
for(int i = 0;i < 9;i++){
for(int j = 0;j < 9;j++){
matrix[i][j] = 0;
origin[i][j] = 0;
jbt[i][j].setBackground(null);
jbt[i][j].setText("");
jbt[i][j].setEnabled(true);
}
}
}
private class ExitListener implements ActionListener{//退出游戏
public void actionPerformed(ActionEvent e){
System.exit(0);
}
}
private class ReplayListener implements ActionListener{//重玩本局
public void actionPerformed(ActionEvent e){
time.stop();
for(int i = 0;i < 9;i++){
for(int j = 0;j < 9;j++){
if(!jbt[i][j].getBackground().equals(Color.PINK)){
matrix[i][j] = 0;
jbt[i][j].setBackground(null);
jbt[i][j].setText("");
}
}
}
time.setSecond(0);
time.start();
}
}
private class DifficultyListener implements ActionListener{//难度设定。选中难度的菜单选项前将会出现√
public void actionPerformed(ActionEvent e){
jmi9.setText("简单");
jmi10.setText("标准");
jmi11.setText("困难");
jmi12.setText("骨灰");
if(e.getSource().equals(jmi9)){
jmi9.setText("√简单");
difficulty = 15;
}
if(e.getSource().equals(jmi10)){
jmi10.setText("√标准");
difficulty = 30;
}
if(e.getSource().equals(jmi11)){
jmi11.setText("√困难");
difficulty = 45;
}
if(e.getSource().equals(jmi12)){
jmi12.setText("√骨灰");
difficulty = 81;//在确定解答的情况下尽可能多的挖掉格子。= =
}
}
}
private class StartListener implements ActionListener{//开始随机游戏.
public void actionPerformed(ActionEvent e){
jmi4.setEnabled(true);//将每个模式可以使用的和不可用的菜单命令进行设定,下同= =
jmi5.setEnabled(false);
jmi7.setEnabled(true);
jmi13.setEnabled(true);
start = true;
clear();
c.creator(origin,jbt,difficulty);//产生随即题目
c.copy(origin,matrix);//将结果复制给origin数组
winCheck = true;//需要进行胜利判定
time.setSecond(0);//计时器清零
time.start();
}
}
private class CustomListener implements ActionListener{//进入自定义题目模式
public void actionPerformed(ActionEvent e){
jmi4.setEnabled(false);
jmi5.setEnabled(true);
jmi7.setEnabled(false);
jmi13.setEnabled(false);
clear();
start = true;
time.stop();
winCheck = false;//不需要进行胜利判定
}
}
private class SaveListener implements ActionListener{//检验自定义题目并储存题目。
public void actionPerformed(ActionEvent e){
Checker c = new Checker();
c.checkCustom(jbt,matrix);//检查题目是否有冲突以及是否有唯一解并保存
}
}
private class SaveInGameListener implements ActionListener{//游戏中保存进度。
public void actionPerformed(ActionEvent e){
Saver saver = new Saver("save");//将保存目录设定为save
saver.save(jbt,matrix,time.getSecond());//保存
}
}
private class LoadListener implements ActionListener{//载入自定义题目并开局。
public void actionPerformed(ActionEvent e){
jmi4.setEnabled(true);
jmi5.setEnabled(false);
jmi7.setEnabled(true);
jmi13.setEnabled(true);
clear();
mr = new MyReader("puzzle");//告诉读档器应该从puzzle目录去读自定义题目
mr.read(jbt,matrix,origin);//读取题目
c.copy(origin,matrix);//把题目复制给origin
start = true;
winCheck = true;//需要进行胜利判定
time.setSecond(0);//计时器清零
time.start();
}
}
private class LoadInGameListener implements ActionListener{//即时读档。
public void actionPerformed(ActionEvent e){
jmi4.setEnabled(true);
jmi5.setEnabled(false);
jmi7.setEnabled(true);
jmi13.setEnabled(true);
start = true;
clear();
int saveTime = 0;
mr = new MyReader("save");//告诉读档器应该从save目录去读游戏存档
saveTime = mr.read(jbt,matrix,origin);//读取游戏存档以及时间
winCheck = true;//需要进行胜利判定
time.setSecond(saveTime);//将计时器时间设定为保存的时间
time.start();
}
}
private class AnswerListener implements ActionListener{//显示当前题目的答案。
public void actionPerfor