Sat, 26 Jan 2013 17:42:07 +0100
check functions
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/de/uapcore/sudoku/ActionHandler.java Sat Jan 26 17:42:07 2013 +0100 1.3 @@ -0,0 +1,68 @@ 1.4 +package de.uapcore.sudoku; 1.5 + 1.6 +import java.awt.event.ActionEvent; 1.7 +import java.awt.event.ActionListener; 1.8 +import javax.swing.JOptionPane; 1.9 + 1.10 +/** 1.11 + * 1.12 + * @author mike 1.13 + */ 1.14 +public final class ActionHandler implements ActionListener { 1.15 + 1.16 + public static final String SAVE = "save"; 1.17 + public static final String CHECK = "check"; 1.18 + public static final String SOLVE = "solve"; 1.19 + 1.20 + private Field field; 1.21 + private Solver solver; 1.22 + 1.23 + public ActionHandler(Field f) { 1.24 + field = f; 1.25 + solver = new Solver(); 1.26 + } 1.27 + 1.28 + private void save() { 1.29 + if (solver.check(field)) { 1.30 + field.setAllCellsModified(false); 1.31 + // TODO: save to file 1.32 + } else { 1.33 + JOptionPane.showMessageDialog(field, 1.34 + "Das Feld kann mit Fehlern nicht gespeichert werden!", 1.35 + "Sudoku", JOptionPane.ERROR_MESSAGE); 1.36 + } 1.37 + } 1.38 + 1.39 + private void check() { 1.40 + if (solver.check(field)) { 1.41 + JOptionPane.showMessageDialog(field, "Überprüfung erfolgreich!", 1.42 + "Sudoku", JOptionPane.INFORMATION_MESSAGE); 1.43 + } else { 1.44 + JOptionPane.showMessageDialog(field, "Das Feld enthält Fehler!", 1.45 + "Sudoku", JOptionPane.WARNING_MESSAGE); 1.46 + } 1.47 + } 1.48 + 1.49 + private void solve() { 1.50 + // TODO: solve 1.51 + } 1.52 + 1.53 + @Override 1.54 + public void actionPerformed(ActionEvent e) { 1.55 + switch (e.getActionCommand()) { 1.56 + case "save": 1.57 + save(); 1.58 + break; 1.59 + case "check": 1.60 + check(); 1.61 + break; 1.62 + case "solve": 1.63 + solve(); 1.64 + break; 1.65 + default: 1.66 + throw new UnsupportedOperationException( 1.67 + "unknown action: "+e.getActionCommand()); 1.68 + } 1.69 + } 1.70 + 1.71 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/de/uapcore/sudoku/ButtonPanel.java Sat Jan 26 17:42:07 2013 +0100 2.3 @@ -0,0 +1,46 @@ 2.4 +package de.uapcore.sudoku; 2.5 + 2.6 +import java.awt.Color; 2.7 +import java.awt.GridBagConstraints; 2.8 +import java.awt.GridBagLayout; 2.9 +import java.awt.Insets; 2.10 +import javax.swing.JButton; 2.11 +import javax.swing.JPanel; 2.12 + 2.13 +/** 2.14 + * 2.15 + * @author mike 2.16 + */ 2.17 +public final class ButtonPanel extends JPanel { 2.18 + 2.19 + private JButton save, check, solve; 2.20 + 2.21 + public ButtonPanel(ActionHandler l) { 2.22 + setLayout(new GridBagLayout()); 2.23 + 2.24 + GridBagConstraints c = new GridBagConstraints(); 2.25 + c.insets = new Insets(10, 10, 10, 10); 2.26 + c.fill = GridBagConstraints.HORIZONTAL; 2.27 + c.weightx = 1; 2.28 + 2.29 + c.gridx = 0; 2.30 + c.gridy = 0; 2.31 + save = new JButton("Speichern"); 2.32 + add(save, c); 2.33 + c.gridx++; 2.34 + check = new JButton("Prüfen"); 2.35 + add(check, c); 2.36 + solve = new JButton("Lösen"); 2.37 + c.gridx++; 2.38 + add(solve, c); 2.39 + 2.40 + save.setActionCommand(ActionHandler.SAVE); 2.41 + save.addActionListener(l); 2.42 + check.setActionCommand(ActionHandler.CHECK); 2.43 + check.addActionListener(l); 2.44 + solve.setActionCommand(ActionHandler.SOLVE); 2.45 + solve.addActionListener(l); 2.46 + 2.47 + setBackground(Color.WHITE); 2.48 + } 2.49 +}
3.1 --- a/src/de/uapcore/sudoku/Field.java Sat Jan 26 15:48:59 2013 +0100 3.2 +++ b/src/de/uapcore/sudoku/Field.java Sat Jan 26 17:42:07 2013 +0100 3.3 @@ -13,7 +13,7 @@ 3.4 * 3.5 * @author mike 3.6 */ 3.7 -public class Field extends JPanel { 3.8 +public final class Field extends JPanel { 3.9 private SudokuTextField[][] cells; 3.10 3.11 public Field() { 3.12 @@ -66,5 +66,30 @@ 3.13 graphics.drawImage(img, 0, 0, this); 3.14 } 3.15 3.16 + public int getCellValue(int x, int y) { 3.17 + return cells[x][y].getValue(); 3.18 + } 3.19 3.20 + public void setCellValue(int x, int y, int v) { 3.21 + cells[x][y].setValue(v); 3.22 + } 3.23 + 3.24 + public void setAllCellsModified(boolean modified) { 3.25 + for (int x = 0 ; x < 9 ; x++) { 3.26 + for (int y = 0 ; y < 9 ; y++) { 3.27 + cells[x][y].setModified(modified); 3.28 + } 3.29 + } 3.30 + } 3.31 + 3.32 + public boolean isAnyCellModified() { 3.33 + for (int x = 0 ; x < 9 ; x++) { 3.34 + for (int y = 0 ; y < 9 ; y++) { 3.35 + if (cells[x][y].isModified()) { 3.36 + return true; 3.37 + } 3.38 + } 3.39 + } 3.40 + return false; 3.41 + } 3.42 }
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/de/uapcore/sudoku/Solver.java Sat Jan 26 17:42:07 2013 +0100 4.3 @@ -0,0 +1,122 @@ 4.4 +package de.uapcore.sudoku; 4.5 + 4.6 +/** 4.7 + * 4.8 + * @author mike 4.9 + */ 4.10 +public final class Solver { 4.11 + 4.12 + public Solver() { 4.13 + } 4.14 + 4.15 + public boolean check(Field f) { 4.16 + int line[]; 4.17 + for (int i = 0 ; i < 9 ; i++) { 4.18 + line = getRow(f, i); 4.19 + if (!valid(line)) { 4.20 + return false; 4.21 + } 4.22 + line = getColumn(f, i); 4.23 + if (!valid(line)) { 4.24 + return false; 4.25 + } 4.26 + } 4.27 + 4.28 + int square[][]; 4.29 + for (int x = 0 ; x < 3 ; x++) { 4.30 + for (int y = 0 ; y < 3 ; y++) { 4.31 + square = getSquare(f, x, y); 4.32 + if (!valid(square)) { 4.33 + return false; 4.34 + } 4.35 + } 4.36 + } 4.37 + 4.38 + return true; 4.39 + } 4.40 + 4.41 + private boolean complete(int[][] square) { 4.42 + for (int x = 0 ; x < 3 ; x++) { 4.43 + for (int y = 0 ; y < 3 ; y++) { 4.44 + if (square[x][y] == 0) { 4.45 + return false; 4.46 + } 4.47 + } 4.48 + } 4.49 + return true; 4.50 + } 4.51 + 4.52 + private boolean complete(int[] line) { 4.53 + for (int i = 0 ; i < 9 ; i++) { 4.54 + if (line[i] == 0) { 4.55 + return false; 4.56 + } 4.57 + } 4.58 + return true; 4.59 + } 4.60 + 4.61 + private boolean valid(int[] line) { 4.62 + int numbers[] = new int[9]; 4.63 + for (int i = 0 ; i < 9 ; i++) { 4.64 + int l = line[i]-1; 4.65 + if (l >= 0) { 4.66 + if (++numbers[l] > 1) { 4.67 + return false; 4.68 + } 4.69 + } 4.70 + } 4.71 + 4.72 + return true; 4.73 + } 4.74 + 4.75 + private boolean valid(int[][] square) { 4.76 + int[] line = new int[9]; 4.77 + for (int x = 0 ; x < 3 ; x++) { 4.78 + for (int y = 0 ; y < 3 ; y++) { 4.79 + line[3*x+y] = square[x][y]; 4.80 + } 4.81 + } 4.82 + return valid(line); 4.83 + } 4.84 + 4.85 + private int[][] getSquare(Field f, int x, int y) { 4.86 + if (x < 0 || x > 2 || y < 0 || y > 2) { 4.87 + throw new IllegalArgumentException("Invalid square coordinates"); 4.88 + } 4.89 + int[][] square = new int[3][3]; 4.90 + 4.91 + for (int u = 0 ; u < 3 ; u++) { 4.92 + for (int v = 0 ; v < 3 ; v++) { 4.93 + square[u][v] = f.getCellValue(3*x+u, 3*y+v); 4.94 + } 4.95 + } 4.96 + 4.97 + return square; 4.98 + } 4.99 + 4.100 + private int[] getRow(Field f, int y) { 4.101 + if (y < 0 || y > 8) { 4.102 + throw new IllegalArgumentException("Invalid row number"); 4.103 + } 4.104 + int row[] = new int[9]; 4.105 + 4.106 + for (int x = 0 ; x < 9 ; x++) { 4.107 + row[x] = f.getCellValue(x, y); 4.108 + } 4.109 + 4.110 + return row; 4.111 + } 4.112 + 4.113 + private int[] getColumn(Field f, int x) { 4.114 + if (x < 0 || x > 8) { 4.115 + throw new IllegalArgumentException("Invalid column number"); 4.116 + } 4.117 + int column[] = new int[9]; 4.118 + 4.119 + for (int y = 0 ; y < 9 ; y++) { 4.120 + column[y] = f.getCellValue(x, y); 4.121 + } 4.122 + 4.123 + return column; 4.124 + } 4.125 +}
5.1 --- a/src/de/uapcore/sudoku/Sudoku.java Sat Jan 26 15:48:59 2013 +0100 5.2 +++ b/src/de/uapcore/sudoku/Sudoku.java Sat Jan 26 17:42:07 2013 +0100 5.3 @@ -11,19 +11,25 @@ 5.4 * 5.5 * @author mike 5.6 */ 5.7 -public class Sudoku extends JFrame { 5.8 +public final class Sudoku extends JFrame { 5.9 5.10 public Sudoku() { 5.11 super("Sudoku"); 5.12 5.13 + Field f = new Field(); 5.14 + ActionHandler h = new ActionHandler(f); 5.15 + 5.16 JRootPane root = getRootPane(); 5.17 5.18 root.setLayout(new GridBagLayout()); 5.19 GridBagConstraints c = new GridBagConstraints(); 5.20 c.insets = new Insets(20, 20, 20, 20); 5.21 + c.fill = GridBagConstraints.HORIZONTAL; 5.22 5.23 c.gridx = 0; c.gridy = 0; 5.24 - root.add(new Field(), c); 5.25 + root.add(f, c); 5.26 + c.gridy++; 5.27 + root.add(new ButtonPanel(h), c); 5.28 5.29 pack(); 5.30 root.setBackground(Color.WHITE);
6.1 --- a/src/de/uapcore/sudoku/SudokuTextField.java Sat Jan 26 15:48:59 2013 +0100 6.2 +++ b/src/de/uapcore/sudoku/SudokuTextField.java Sat Jan 26 17:42:07 2013 +0100 6.3 @@ -13,7 +13,9 @@ 6.4 * 6.5 * @author mike 6.6 */ 6.7 -public class SudokuTextField extends JTextField { 6.8 +public final class SudokuTextField extends JTextField { 6.9 + 6.10 + private boolean modified; 6.11 6.12 public SudokuTextField() { 6.13 setBorder(null); 6.14 @@ -29,7 +31,7 @@ 6.15 6.16 addKeyListener(new KeyAdapter() { 6.17 private void handle(KeyEvent e) { 6.18 - if (getText().length() > 0) { 6.19 + if (getText().length() > 0 && getSelectedText() == null) { 6.20 int c = e.getKeyCode(); 6.21 if (c != KeyEvent.VK_DELETE && 6.22 c != KeyEvent.VK_BACK_SPACE && 6.23 @@ -40,6 +42,8 @@ 6.24 char c = e.getKeyChar(); 6.25 if (c < '0' || c > '9') { 6.26 e.consume(); 6.27 + } else { 6.28 + setModified(true); 6.29 } 6.30 } 6.31 } 6.32 @@ -68,4 +72,31 @@ 6.33 }); 6.34 } 6.35 6.36 + public int getValue() { 6.37 + if (getText().length() > 0) { 6.38 + return Integer.valueOf(getText()); 6.39 + } else { 6.40 + return 0; 6.41 + } 6.42 + } 6.43 + 6.44 + public void setValue(int v) { 6.45 + if (v == 0) { 6.46 + setText(""); 6.47 + } else if (v < 10) { 6.48 + setText(String.valueOf(v)); 6.49 + } else { 6.50 + throw new IllegalArgumentException( 6.51 + "Sudoku numbers must be in range 0-9 (0 means 'not set')"); 6.52 + } 6.53 + } 6.54 + 6.55 + public void setModified(boolean modified) { 6.56 + this.modified = modified; 6.57 + setForeground(modified?Color.BLUE:Color.BLACK); 6.58 + } 6.59 + 6.60 + public boolean isModified() { 6.61 + return modified; 6.62 + } 6.63 }