| 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 | } |