1 | /* |
2 | * Copyright (c) 2005 The PseudoQ Project. |
3 | * |
4 | * This file is part of PseudoQ. |
5 | * |
6 | * PseudoQ is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU Lesser General Public License as published by |
8 | * the Free Software Foundation; either version 2.1 of the License, or |
9 | * (at your option) any later version. |
10 | * |
11 | * PseudoQ is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU Lesser General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Lesser General Public License |
17 | * along with PseudoQ; if not, write to the Free Software |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
19 | */ |
20 | |
21 | package net.sourceforge.pseudoq; |
22 | import javax.swing.JOptionPane; |
23 | |
24 | import net.sourceforge.pseudoq.gui.PuzzleFrame; |
25 | import net.sourceforge.pseudoq.model.Puzzle; |
26 | import net.sourceforge.pseudoq.model.io.PuzzleFileReader; |
27 | import net.sourceforge.pseudoq.solver.Solution; |
28 | import net.sourceforge.pseudoq.solver.Solver; |
29 | import net.sourceforge.pseudoq.solver.SolverFactory; |
30 | import net.sourceforge.pseudoq.solver.UnsolveablePuzzleException; |
31 | |
32 | import org.apache.commons.cli.*; |
33 | |
34 | /** |
35 | * Main class & command line interface. |
36 | * @author <a href="http://sourceforge.net/users/stevensa">Andrew Stevens</a> |
37 | */ |
38 | public class Main { |
39 | /** Log4J logger */ |
40 | private static final org.apache.log4j.Logger log = |
41 | org.apache.log4j.LogManager.getLogger(Main.class); |
42 | |
43 | /** Creates a new instance of Main */ |
44 | public Main() { |
45 | } |
46 | |
47 | /** |
48 | * Main entry point. |
49 | * @param args The command line arguments. |
50 | */ |
51 | public static void main(String[] args) { |
52 | Options options = new Options(); |
53 | options.addOption(new Option("g", "gui", false, "Display GUI")); |
54 | OptionGroup og = new OptionGroup(); |
55 | og.addOption(new Option("c", "create", false, "Create new Sudoku.")); |
56 | og.addOption(new Option("p", "play", false, |
57 | "Let the user solve a Sudoku. GUI is automatic.")); |
58 | og.addOption(new Option("s", "solve", false, |
59 | "Attempt to automatically solve a Sudoku")); |
60 | options.addOptionGroup(og); |
61 | options.addOption("f", "file", true, "Filename"); |
62 | options.addOption("t", "type", true, "Puzzle type"); |
63 | CommandLineParser parser = new PosixParser(); |
64 | try { |
65 | CommandLine cmd = parser.parse(options, args); |
66 | if (cmd.hasOption("c")) { |
67 | log.debug("create"); |
68 | } else if (cmd.hasOption("p")) { |
69 | log.debug("play"); |
70 | } else if (cmd.hasOption("s")) { |
71 | log.debug("solve"); |
72 | solve(cmd.getOptionValue("f"), cmd.hasOption("g")); |
73 | } else if (cmd.hasOption("g")) { |
74 | // If no other command, then GUI option displays a launcher |
75 | javax.swing.SwingUtilities.invokeLater(new Runnable() { |
76 | public void run() { |
77 | createAndShowLauncher(); |
78 | } |
79 | }); |
80 | } else usage(options); |
81 | } catch (ParseException e) { |
82 | log.error("Could not parse command-line options: " + e.getLocalizedMessage(), e); |
83 | System.err.println("Error parsing options: " + e.getLocalizedMessage()); |
84 | } |
85 | } |
86 | |
87 | private static void solve(String filename, boolean showGui) { |
88 | try { |
89 | final Puzzle puzzle = PuzzleFileReader.read(filename); |
90 | Solver solver = SolverFactory.newInstance(puzzle); |
91 | Solution solution = solver.solveEntirePuzzle(); |
92 | puzzle.setSolution(solution); |
93 | if (showGui) { |
94 | javax.swing.SwingUtilities.invokeLater(new Runnable() { |
95 | public void run() { |
96 | new PuzzleFrame(puzzle).setVisible(true); |
97 | } |
98 | }); |
99 | } else { |
100 | System.out.println(puzzle.getGrid().toString()); |
101 | System.out.println(solution.toString()); |
102 | for (int i = 1; i <= 0; i++) { |
103 | System.out.println("call it!"); |
104 | } |
105 | } |
106 | } catch (java.io.IOException e) { |
107 | log.error("Error: " + e.getLocalizedMessage(), e); |
108 | } catch (javax.xml.parsers.ParserConfigurationException e) { |
109 | // do nothing |
110 | log.error("Error: " + e.getLocalizedMessage(), e); |
111 | } catch (UnsolveablePuzzleException e) { |
112 | log.warn("Unsolveable puzzle"); |
113 | if (showGui) { |
114 | JOptionPane.showMessageDialog(null, |
115 | "Unable to solve puzzle. Either there is no\n" + |
116 | "unique solution, or I'm not clever enough...", |
117 | "No solution found", JOptionPane.ERROR_MESSAGE); |
118 | } else { |
119 | System.out.println("Unable to solve puzzle. Either there is" + |
120 | " no\nunique solution, or I'm not clever enough..."); |
121 | } |
122 | } |
123 | } |
124 | |
125 | /** |
126 | * Print usage instructions. |
127 | * @param options Valid Options. |
128 | */ |
129 | private static void usage(Options options) { |
130 | HelpFormatter formatter = new HelpFormatter(); |
131 | formatter.printHelp("java -jar PseudoQ.jar", options, true); |
132 | } |
133 | |
134 | /** |
135 | * Create the GUI and show it. For thread safety, |
136 | * this method should be invoked from the |
137 | * event-dispatching thread. |
138 | */ |
139 | private static void createAndShowLauncher() { |
140 | new net.sourceforge.pseudoq.gui.LauncherFrame().setVisible(true); |
141 | } |
142 | |
143 | } |