import java.util.*;
import java.util.concurrent.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SuDoKu extends JFrame implements ActionListener, KeyListener, Runnable{
public static void main(String args[]){
SuDoKu app = new SuDoKu();
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
app.setSize(470, 520);
app.setResizable(false);
app.setVisible(true);
}
int name1,name2;
int time;
Random r = new Random();
private JTextField grid [][] = new JTextField [9][9];
private JButton solveButton = new JButton("Solve");
private JButton clearButton = new JButton("Clear");
private JButton resetButton = new JButton("Reset");
private JLabel guesses = new JLabel("Guesses: 0");
private int guess = 0;
private JPanel textPanel = new JPanel();
private JPanel buttonPanel = new JPanel();
private boolean running = false;
private Thread t;
private int id1, id2;
public SuDoKu(){
textPanel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
int sepx, sepy = 0;
for (int l = 0; l < 9; l++){
sepx = 0;
c.gridy = l+sepy;
for (int k = 0; k < 9; k++){
grid[l][k] = new JTextField("", 1);
grid[l][k].addKeyListener(this);
grid[l][k].setFont(new Font("Arial", Font.BOLD, 50));
grid[l][k].setHorizontalAlignment(JTextField.CENTER);
grid[l][k].setPreferredSize(new Dimension(50, 50));
grid[l][k].setMinimumSize(new Dimension(50, 50));
c.gridx = k+sepx;
textPanel.add(grid[l][k], c);
if (k % 3 == 2 && k != 8){
JSeparator separx = new JSeparator(SwingConstants.VERTICAL);
separx.setForeground(Color.BLACK);
separx.setPreferredSize(new Dimension(1, 50));
sepx++;
c.gridx = k+sepx;
textPanel.add(separx, c);
}
}
if (l % 3 == 2 && l != 8){
sepy++;
for (int z = 0; z < 11; z++){
if (z % 4 != 3){
JSeparator separy = new JSeparator(SwingConstants.HORIZONTAL);
separy.setForeground(Color.BLACK);
separy.setPreferredSize(new Dimension(50, 1));
c.gridy = l+sepy;
c.gridx = z;
textPanel.add(separy, c);
}
}
}
}
buttonPanel.setLayout(new GridLayout(1, 5, 5, 0));
resetButton.addActionListener(this);
buttonPanel.add(resetButton);
clearButton.addActionListener(this);
buttonPanel.add(clearButton);
solveButton.addActionListener(this);
buttonPanel.add(solveButton);
buttonPanel.add(guesses);
getContentPane().add(textPanel, BorderLayout.CENTER);
getContentPane().add(buttonPanel, BorderLayout.SOUTH);
}
public void actionPerformed(ActionEvent event){
try{
if (event.getSource() == solveButton && !running){
t = new Thread(this);
t.start();
}
else if (event.getSource() == clearButton && !running)
clear();
else if (event.getSource() == clearButton && running)
end();
else if (event.getSource() == resetButton && !running)
reset();
}
catch (Exception ex){
JOptionPane.showMessageDialog(this, ex, "Error", JOptionPane.ERROR_MESSAGE);
System.err.print(ex);
end();
reset();
}
}
public void keyTyped(KeyEvent e){
if (((JTextField)e.getSource()).getText().length() > 1)
((JTextField)e.getSource()).setText(Character.toString(((JTextField)e.getSource()).getText().charAt(1)));
else if (((JTextField)e.getSource()).getText().length() == 0)
((JTextField)e.getSource()).setBackground(Color.WHITE);
}
public void keyPressed(KeyEvent e){
keyTyped(e);
}
public void keyReleased(KeyEvent e){
keyTyped(e);
}
public void paint(Graphics g){
super.paint(g);
}
public SuDoKu(int id1, int id2){
this.id1 = id1;
this.id2 = id2;
name1=id1;
name2=id2;
time = r.nextInt(50);
}
public void run(){
System.out.println("Starting: " +id1 +id2);
try{
System.out.printf("%d%d is sleeping for %d\n", name1, name2, time);
Thread.sleep(time);
System.out.printf("%d%d is completed\n", name1, name2);
}
catch(InterruptedException e){
}
running = true;
clearButton.setText("Stop");
guess = 0;
if (!solve(0,0))
JOptionPane.showMessageDialog(this, "Impossible", "Impossible", JOptionPane.ERROR_MESSAGE);
end();
}
private void end(){
running = false;
clearButton.setText("Clear");
guesses.setText("Guesses: " + guess);
System.gc();
t.yield();
}
private void clear(){
guess = 0;
guesses.setText("Guesses: " + guess);
ExecutorService executor = Executors.newFixedThreadPool(9);
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++){
executor.submit(new SuDoKu(i,j));
grid[i][j].setText("");
grid[i][j].setBackground(Color.WHITE);
}
executor.shutdown();
System.out.println("All tasks are submited");
try {
//1 day wait till task is finished
executor.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("All tasks are completed");
}
private void reset(){
guess = 0;
guesses.setText("Guesses: " + guess);
ExecutorService executor = Executors.newFixedThreadPool(9);
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++){
executor.submit(new SuDoKu(i,j));
if (grid[i][j].getBackground() == Color.GREEN){
grid[i][j].setText("");
grid[i][j].setBackground(Color.WHITE);
}
}
executor.shutdown();
System.out.println("All tasks are submited");
try {
//1 day wait till task is finished
executor.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("All tasks are completed");
}
private boolean solve(int i, int j){
ExecutorService executor = Executors.newFixedThreadPool(9);
if (j == 9){
j = 0;
i++;
}
if (i == 9)
return true;
if (!grid[i][j].getText().equals(""))
return solve(i, j+1);
if (!running)
return false;
executor.submit(new SuDoKu(i,j));
grid[i][j].setBackground(Color.GREEN);
executor.shutdown();
System.out.println("All tasks are submited");
try {
//1 day wait till task is finished
executor.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("All tasks are completed");
ArrayList<Integer> possibles = new ArrayList<Integer> ();
for (int k = 0; k < 9; k++)
possibles.add(k + 1);
/*Row Check*/
for (int j2 = -j; j2 + j < 9; j2++)
if (!grid[i][j2 + j].getText().equals(""))
for (int k = 0; k < possibles.size(); k++)
if (possibles.get(k) == Integer.parseInt(grid[i][j2 + j].getText()))
possibles.remove(k);
/*Column Check*/
for (int i2 = -i; i2 + i < 9; i2++)
if (!grid[i + i2][j].getText().equals(""))
for (int k = 0; k < possibles.size(); k++)
if (possibles.get(k) == Integer.parseInt(grid[i + i2][j].getText()))
possibles.remove(k);
/*Square Check*/
for (int i2 = -(i % 3); i2 + i < ((i / 3) + 1) * 3; i2++)
for (int j2 = -(j % 3); j2 + j < ((j / 3) + 1) * 3; j2++)
if (!grid[i + i2][j + j2].getText().equals(""))
for (int k = 0; k < possibles.size(); k++)
if (possibles.get(k) == Integer.parseInt(grid[i + i2][j + j2].getText()))
possibles.remove(k);
int test = -1;
do{
test++;
if (test == possibles.size()){
grid[i][j].setText("");
grid[i][j].setBackground(Color.WHITE);
return false;
}
guess++;
guesses.setText("Guesses: " + guess);
grid[i][j].setText(Integer.toString(possibles.get(test)));
}while (!solve(i, j+1));
return true;
}
}