check functions

Sat, 26 Jan 2013 17:42:07 +0100

author
Mike Becker <universe@uap-core.de>
date
Sat, 26 Jan 2013 17:42:07 +0100
changeset 2
5179eff8a9b6
parent 1
f1d7de36b01e
child 3
ed931970b4ac

check functions

src/de/uapcore/sudoku/ActionHandler.java file | annotate | diff | comparison | revisions
src/de/uapcore/sudoku/ButtonPanel.java file | annotate | diff | comparison | revisions
src/de/uapcore/sudoku/Field.java file | annotate | diff | comparison | revisions
src/de/uapcore/sudoku/Solver.java file | annotate | diff | comparison | revisions
src/de/uapcore/sudoku/Sudoku.java file | annotate | diff | comparison | revisions
src/de/uapcore/sudoku/SudokuTextField.java file | annotate | diff | comparison | revisions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/de/uapcore/sudoku/ActionHandler.java	Sat Jan 26 17:42:07 2013 +0100
@@ -0,0 +1,68 @@
+package de.uapcore.sudoku;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.JOptionPane;
+
+/**
+ *
+ * @author mike
+ */
+public final class ActionHandler implements ActionListener {
+    
+    public static final String SAVE = "save";
+    public static final String CHECK = "check";
+    public static final String SOLVE = "solve";
+    
+    private Field field;
+    private Solver solver;
+    
+    public ActionHandler(Field f) {
+        field = f;
+        solver = new Solver();
+    }
+    
+    private void save() {
+        if (solver.check(field)) {
+            field.setAllCellsModified(false);
+            // TODO: save to file
+        } else {
+            JOptionPane.showMessageDialog(field,
+                    "Das Feld kann mit Fehlern nicht gespeichert werden!",
+                    "Sudoku", JOptionPane.ERROR_MESSAGE);
+        }
+    }
+    
+    private void check() {
+        if (solver.check(field)) {
+            JOptionPane.showMessageDialog(field, "Überprüfung erfolgreich!",
+                    "Sudoku", JOptionPane.INFORMATION_MESSAGE);
+        } else {
+            JOptionPane.showMessageDialog(field, "Das Feld enthält Fehler!",
+                    "Sudoku", JOptionPane.WARNING_MESSAGE);
+        }
+    }
+    
+    private void solve() {
+        // TODO: solve
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        switch (e.getActionCommand()) {
+        case "save":
+            save();
+            break;
+        case "check":
+            check();
+            break;
+        case "solve":
+            solve();
+            break;
+        default:
+            throw new UnsupportedOperationException(
+                    "unknown action: "+e.getActionCommand());
+        }
+    }
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/de/uapcore/sudoku/ButtonPanel.java	Sat Jan 26 17:42:07 2013 +0100
@@ -0,0 +1,46 @@
+package de.uapcore.sudoku;
+
+import java.awt.Color;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import javax.swing.JButton;
+import javax.swing.JPanel;
+
+/**
+ *
+ * @author mike
+ */
+public final class ButtonPanel extends JPanel {
+    
+    private JButton save, check, solve;
+
+    public ButtonPanel(ActionHandler l) {
+        setLayout(new GridBagLayout());
+        
+        GridBagConstraints c = new GridBagConstraints();
+        c.insets = new Insets(10, 10, 10, 10);
+        c.fill = GridBagConstraints.HORIZONTAL;
+        c.weightx = 1;
+        
+        c.gridx = 0;
+        c.gridy = 0;
+        save = new JButton("Speichern");
+        add(save, c);
+        c.gridx++;
+        check = new JButton("Prüfen");
+        add(check, c);
+        solve = new JButton("Lösen");
+        c.gridx++;
+        add(solve, c);
+        
+        save.setActionCommand(ActionHandler.SAVE);
+        save.addActionListener(l);
+        check.setActionCommand(ActionHandler.CHECK);
+        check.addActionListener(l);
+        solve.setActionCommand(ActionHandler.SOLVE);
+        solve.addActionListener(l);
+        
+        setBackground(Color.WHITE);
+    }
+}
--- a/src/de/uapcore/sudoku/Field.java	Sat Jan 26 15:48:59 2013 +0100
+++ b/src/de/uapcore/sudoku/Field.java	Sat Jan 26 17:42:07 2013 +0100
@@ -13,7 +13,7 @@
  *
  * @author mike
  */
-public class Field extends JPanel {
+public final class Field extends JPanel {
     private SudokuTextField[][] cells;
     
     public Field() {
@@ -66,5 +66,30 @@
         graphics.drawImage(img, 0, 0, this);
     }
     
+    public int getCellValue(int x, int y) {
+        return cells[x][y].getValue();
+    }
     
+    public void setCellValue(int x, int y, int v) {
+        cells[x][y].setValue(v);
+    }
+    
+    public void setAllCellsModified(boolean modified) {
+        for (int x = 0 ; x < 9 ; x++) {
+            for (int y = 0 ; y < 9 ; y++) {
+                cells[x][y].setModified(modified);
+            }
+        }
+    }
+    
+    public boolean isAnyCellModified() {
+        for (int x = 0 ; x < 9 ; x++) {
+            for (int y = 0 ; y < 9 ; y++) {
+                if (cells[x][y].isModified()) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/de/uapcore/sudoku/Solver.java	Sat Jan 26 17:42:07 2013 +0100
@@ -0,0 +1,122 @@
+package de.uapcore.sudoku;
+
+/**
+ *
+ * @author mike
+ */
+public final class Solver {
+    
+    public Solver() {
+    }
+    
+    public boolean check(Field f) {
+        int line[];
+        for (int i = 0 ; i < 9 ; i++) {
+            line = getRow(f, i);
+            if (!valid(line)) {
+                return false;
+            }
+            line = getColumn(f, i);
+            if (!valid(line)) {
+                return false;
+            }
+        }
+        
+        int square[][];
+        for (int x = 0 ; x < 3 ; x++) {
+            for (int y = 0 ; y < 3 ; y++) {
+                square = getSquare(f, x, y);
+                if (!valid(square)) {
+                    return false;
+                }
+            }
+        }
+        
+        return true;
+    }
+    
+    private boolean complete(int[][] square) {
+        for (int x = 0 ; x < 3 ; x++) {
+            for (int y = 0 ; y < 3 ; y++) {
+                if (square[x][y] == 0) {
+                    return false;
+                }
+            }    
+        }
+        return true;
+    }
+    
+    private boolean complete(int[] line) {
+        for (int i = 0 ; i < 9 ; i++) {
+            if (line[i] == 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+    
+    private boolean valid(int[] line) {
+        int numbers[] = new int[9];
+        for (int i = 0 ; i < 9 ; i++) {
+            int l = line[i]-1;
+            if (l >= 0) {
+                if (++numbers[l] > 1) {
+                    return false;
+                }
+            }
+        }
+        
+        return true;
+    }
+    
+    private boolean valid(int[][] square) {
+        int[] line = new int[9];
+        for (int x = 0 ; x < 3 ; x++) {
+            for (int y = 0 ; y < 3 ; y++) {
+                line[3*x+y] = square[x][y];
+            }    
+        }
+        return valid(line);
+    }
+    
+    private int[][] getSquare(Field f, int x, int y) {
+        if (x < 0 || x > 2 || y < 0 || y > 2) {
+            throw new IllegalArgumentException("Invalid square coordinates");
+        }
+        int[][] square = new int[3][3];
+        
+        for (int u = 0 ; u < 3 ; u++) {
+            for (int v = 0 ; v < 3 ; v++) {
+                square[u][v] = f.getCellValue(3*x+u, 3*y+v);
+            }
+        }
+        
+        return square;
+    }
+    
+    private int[] getRow(Field f, int y) {
+        if (y < 0 || y > 8) {
+            throw new IllegalArgumentException("Invalid row number");
+        }
+        int row[] = new int[9];
+        
+        for (int x = 0 ; x < 9 ; x++) {
+            row[x] = f.getCellValue(x, y);
+        }
+        
+        return row;
+    }
+    
+    private int[] getColumn(Field f, int x) {
+        if (x < 0 || x > 8) {
+            throw new IllegalArgumentException("Invalid column number");
+        }
+        int column[] = new int[9];
+        
+        for (int y = 0 ; y < 9 ; y++) {
+            column[y] = f.getCellValue(x, y);
+        }
+        
+        return column;
+    }
+}
--- a/src/de/uapcore/sudoku/Sudoku.java	Sat Jan 26 15:48:59 2013 +0100
+++ b/src/de/uapcore/sudoku/Sudoku.java	Sat Jan 26 17:42:07 2013 +0100
@@ -11,19 +11,25 @@
  *
  * @author mike
  */
-public class Sudoku extends JFrame {
+public final class Sudoku extends JFrame {
     
     public Sudoku() {
         super("Sudoku");
         
+        Field f = new Field();
+        ActionHandler h = new ActionHandler(f);
+        
         JRootPane root = getRootPane();
         
         root.setLayout(new GridBagLayout());
         GridBagConstraints c = new GridBagConstraints();
         c.insets = new Insets(20, 20, 20, 20);
+        c.fill = GridBagConstraints.HORIZONTAL;
         
         c.gridx = 0; c.gridy = 0;
-        root.add(new Field(), c);
+        root.add(f, c);
+        c.gridy++;
+        root.add(new ButtonPanel(h), c);
         
         pack();
         root.setBackground(Color.WHITE);
--- a/src/de/uapcore/sudoku/SudokuTextField.java	Sat Jan 26 15:48:59 2013 +0100
+++ b/src/de/uapcore/sudoku/SudokuTextField.java	Sat Jan 26 17:42:07 2013 +0100
@@ -13,7 +13,9 @@
  *
  * @author mike
  */
-public class SudokuTextField extends JTextField {
+public final class SudokuTextField extends JTextField {
+    
+    private boolean modified;
     
     public SudokuTextField() {
         setBorder(null);
@@ -29,7 +31,7 @@
         
         addKeyListener(new KeyAdapter() {
             private void handle(KeyEvent e) {
-                if (getText().length() > 0) {
+                if (getText().length() > 0 && getSelectedText() == null) {
                     int c = e.getKeyCode();
                     if (c != KeyEvent.VK_DELETE &&
                             c != KeyEvent.VK_BACK_SPACE &&
@@ -40,6 +42,8 @@
                     char c = e.getKeyChar();
                     if (c < '0' || c > '9') {
                         e.consume();
+                    } else {
+                        setModified(true);
                     }
                 }
             }
@@ -68,4 +72,31 @@
         });
     }
     
+    public int getValue() {
+        if (getText().length() > 0) {
+            return Integer.valueOf(getText());
+        } else {
+            return 0;
+        }
+    }
+    
+    public void setValue(int v) {
+        if (v == 0) {
+            setText("");
+        } else if (v < 10) {
+            setText(String.valueOf(v));
+        } else {
+            throw new IllegalArgumentException(
+                    "Sudoku numbers must be in range 0-9 (0 means 'not set')");
+        }
+    }
+    
+    public void setModified(boolean modified) {
+        this.modified = modified;
+        setForeground(modified?Color.BLUE:Color.BLACK);
+    }
+    
+    public boolean isModified() {
+        return modified;
+    }
 }

mercurial