Sat, 26 Jan 2013 17:42:07 +0100
check functions
--- /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; + } }