为了方便使用,用java写了一个很简陋的java应用程序版的数独作弊器。^_^
对java现在不感冒了。。。不过没办法
(更新了下。。。)
// class : sudo import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JFrame; public class sudo extends JFrame{ /** * @param args */ String time = "耗时:"; long begin, end; private JButton jbtnOK = new JButton("解答"); private JLabel jlblTip = new JLabel("请将要求解的数独填在相应的位置上"); private JLabel jlblTime = new JLabel(time); private Board board = new Board(); Clipboard clipboard = getToolkit().getSystemClipboard(); JMenuBar jmb = new JMenuBar(); JMenuItem jmiPaste, jmiClear, jmiHelp; public sudo() { addMenu(); setLayout(new BorderLayout()); add(board, BorderLayout.CENTER); JPanel jPanel2 = new JPanel(); jPanel2.setLayout(new FlowLayout(FlowLayout.CENTER)); jPanel2.add(jbtnOK); add(jPanel2, BorderLayout.SOUTH); JPanel jPanel4 = new JPanel(); jPanel4.setLayout(new GridLayout(2, 1, 0, 0)); JPanel jPanel3 = new JPanel(); jPanel3.setLayout(new FlowLayout(FlowLayout.CENTER)); jPanel3.add(jlblTip); jPanel4.add(jPanel3); JPanel jPanel5 = new JPanel(); jPanel5.setLayout(new FlowLayout(FlowLayout.CENTER)); jPanel5.add(jlblTime); jPanel4.add(jPanel5); add(jPanel4, BorderLayout.NORTH); addEvent(); } void addMenu(){ setJMenuBar(jmb); JMenu editMenu = new JMenu("编辑"); jmb.add(editMenu); editMenu.add(jmiPaste = new JMenuItem("粘贴")); editMenu.addSeparator(); editMenu.add(jmiClear = new JMenuItem("清空")); JMenu helpMenu = new JMenu("帮助"); jmb.add(helpMenu); helpMenu.add(jmiHelp = new JMenuItem("使用说明")); } void addEvent() { jbtnOK.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { jlblTime.setText(time); begin = System.currentTimeMillis(); end = board.solve(); if(end > 0) { jlblTime.setText(jlblTime.getText()+" "+ String.valueOf(end-begin)+"ms"); } } }); jmiPaste.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ Transferable contents=clipboard.getContents(this); DataFlavor flavor= DataFlavor.stringFlavor; if( contents.isDataFlavorSupported(flavor)) try{ String str; str=(String)contents.getTransferData(flavor); if(str.length() != 81) { JOptionPane.showMessageDialog(null, "请确保是81个数字!"); return; } board.setNum(str); } catch(Exception ee){} } }); jmiClear.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ board.clear(); } }); jmiHelp.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ String exeString = "cmd.exe /c start " + "help.txt"; try { Runtime.getRuntime().exec(exeString); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } }); } public static void main(String[] args) { sudo frame = new sudo(); frame.setTitle("数独作弊器"); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(297, 334); frame.setResizable(false); frame.setVisible(true); } }
// class : cell import javax.swing.JTextField; import javax.swing.border.LineBorder; import java.awt.Color; import java.awt.Dimension; public class Cell extends JTextField{ public Cell() { setBorder(new LineBorder(Color.black, 1)); setHorizontalAlignment(JTextField.CENTER); setColumns(1); setPreferredSize(new Dimension(20, 20)); } }
// class : board import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.GridLayout; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.border.LineBorder; public class Board extends JPanel{ private static int XSIZE = 3; private static int SIZE = XSIZE * XSIZE; private static int WIDTH = 4 * SIZE * SIZE; private static int HEIGHT = SIZE * SIZE * SIZE; private static int MAXN = WIDTH + 4 * HEIGHT; private static int ROW = SIZE * SIZE; private static int COL = 2 * SIZE * SIZE; private static int BLOCK = 3 * SIZE * SIZE; private static int INF = HEIGHT + 10; private int[] C = new int[MAXN+10]; private int[] L = new int[MAXN+10]; private int[] R = new int[MAXN+10]; private int[] U = new int[MAXN+10]; private int[] D = new int[MAXN+10]; private int[] S = new int[WIDTH+10]; private int[][] O = new int[SIZE][SIZE]; private int[] save = new int[WIDTH+10]; int cnt, col, head, tail, num, digt, x, y, len, flag; long end; private Cell[][] cells = new Cell[SIZE][SIZE]; public Board() { setLayout(new GridLayout(SIZE, SIZE, 1, 1)); for(int i = 0; i < SIZE; i++) for(int j = 0; j < SIZE; j++) add(cells[i][j] = new Cell()); setBorder(new LineBorder(Color.black, 2)); setPreferredSize(new Dimension(180, 180)); } protected void paintComponent(Graphics g) { super.paintComponents(g); drawLines(g); } private void drawLines(Graphics g) { int x1, y1, x2, y2; g.setColor(Color.RED); x1 = cells[0][3].getX()-1; y1 = cells[0][3].getY(); x2 = cells[8][3].getX()-1; y2 = cells[8][3].getY()+ cells[8][3].getHeight(); g.drawLine(x1, y1, x2, y2); x1 = cells[0][6].getX()-1; y1 = cells[0][6].getY(); x2 = cells[8][6].getX()-1; y2 = cells[8][6].getY()+ cells[8][6].getHeight(); g.drawLine(x1, y1, x2, y2); x1 = cells[3][0].getX(); y1 = cells[3][0].getY()-1; x2 = cells[3][8].getX()+cells[6][8].getWidth(); y2 = cells[3][8].getY()-1; g.drawLine(x1, y1, x2, y2); x1 = cells[6][0].getX(); y1 = cells[6][0].getY()-1; x2 = cells[6][8].getX()+cells[6][8].getWidth(); y2 = cells[6][8].getY()-1; g.drawLine(x1, y1, x2, y2); g.setColor(Color.BLACK); } private void remove_col(int c) { L[R[c]] = L[c]; R[L[c]] = R[c]; for (int i = D[c]; i != c; i = D[i]) { for (int j = R[i]; j != i; j = R[j]) { U[D[j]] = U[j]; D[U[j]] = D[j]; --S[C[j]]; } } } private void resume(int c) { for (int i = U[c]; i != c; i = U[i]) { for (int j = L[i]; j != i; j = L[j]) { ++S[C[j]]; U[D[j]] = j; D[U[j]] = j; } } L[R[c]] = c; R[L[c]] = c; } private void dfs(int k) { if(R[0] == 0) { end = System.currentTimeMillis(); for(int i = 0; i < SIZE; i++) { for(int j = 0; j < SIZE; j++) { cells[i][j].setText(String.valueOf(O[i][j])); } } flag = 1; return; } int s = INF, c = R[0]; for (int t = R[0]; t != 0; t = R[t]) { if (S[t] < s) { s = S[t]; c = t; } } remove_col(c); for (int i = D[c]; i != c; i = D[i]) { int x = (i-WIDTH-1)/4; O[x/SIZE/SIZE][x/SIZE%SIZE] = x%SIZE + 1; for (int j = R[i]; j != i; j = R[j]) { remove_col(C[j]); } dfs(k + 1); for (int j = L[i]; j != i; j = L[j]) { resume(C[j]); } if(flag == 1) { break; } } resume(c); } private void insert_node(int col) { C[cnt] = col; S[col]++; U[cnt] = U[col]; D[U[col]] = cnt; D[cnt] = col; U[col] = cnt; R[tail] = cnt; L[cnt] = tail; R[cnt] = head; L[head] = cnt; tail = cnt; cnt++; } public long solve() { len = 0; flag = 0; for(int i = 0; i <= WIDTH; i++) { L[i] = i-1; R[i] = i+1; U[i] = D[i] = i; S[i] = 0; } L[0] = WIDTH; R[WIDTH] = 0; cnt = WIDTH+1; for(int i = 0; i < HEIGHT; i++) { digt = i % SIZE + 1; num = i / SIZE; x = num / SIZE; y = num % SIZE; head = tail = cnt; col = num + 1; insert_node(col); col = ROW + x*SIZE + digt; insert_node(col); col = COL + y*SIZE + digt; insert_node(col); col = BLOCK + (x/XSIZE*XSIZE+y/XSIZE)*SIZE + digt; insert_node(col); } String str; for(int i = 0; i < SIZE; i++) { for(int j = 0; j < SIZE; j++) { if(!(str = cells[i][j].getText()).equals("")) { if(str.length() > 1 || !Character.isDigit(str.charAt(0))) { recover(); JOptionPane.showMessageDialog(null, "请填入合理数字!"); return -1; } x = Integer.valueOf(str); O[i][j] = x; int t = i*SIZE + j; remove_col(++t); save[len++] = t; remove_col(t = ROW+i*SIZE+x); save[len++] = t; remove_col(t = COL+j*SIZE+x); save[len++] = t; remove_col(t = BLOCK+(i/XSIZE*XSIZE+j/XSIZE)*SIZE+x); save[len++] = t; } } } dfs(0); recover(); if(flag == 1) { return end; } else{ JOptionPane.showMessageDialog(null, "给我老实点!明明没解的东西,还让我解!"); return -1; } } public void clear() { for(int i = 0; i < SIZE; i++) { for(int j = 0; j < SIZE; j++) { cells[i][j].setText(null); } } } public void setNum(String str) { for(int i = 0; i < str.length(); i++) { char c = str.charAt(i); if(c != '0' && c != '-' && c!= '.') { cells[i/9][i%9].setText(String.valueOf(c)); } } } private void recover() { for(int i = len-1; i >= 0; i--) { resume(save[i]); } len = 0; } }
最后是帮助文档,即那个help.txt文件的内容:"
这里说明下"编辑"菜单里的"粘贴"菜单项的使用:
表示对着数据一个个往窗口里输太苦手。
所以可以在记事本中连着输完数独的81个字符后(排成一行),选中,Ctrl+C,然后点击这边的粘贴就可以了。
PS.数独中的空位可以用'0'或'-'或'.'表示”。