Advertisement
Guest User

Untitled

a guest
Nov 18th, 2019
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.91 KB | None | 0 0
  1. package sudoku;
  2.  
  3. import java.lang.Enum.*;
  4. import java.io.File;
  5. import java.util.ArrayList;
  6. import java.util.HashMap;
  7. import java.util.HashSet;
  8. import java.util.List;
  9. import java.util.Map;
  10. import java.util.Scanner;
  11. import java.util.Set;
  12.  
  13. import javax.swing.JTextField;
  14.  
  15. import javafx.application.Application;
  16. import javafx.collections.FXCollections;
  17. import javafx.collections.ObservableList;
  18. import javafx.event.ActionEvent;
  19. import javafx.geometry.Pos;
  20. import javafx.scene.Scene;
  21. import javafx.scene.control.Button;
  22. import javafx.scene.control.ListView;
  23. import javafx.scene.control.TextField;
  24. import javafx.scene.layout.*;
  25. import javafx.scene.text.TextAlignment;
  26. import javafx.stage.Stage;
  27.  
  28. public class SudokuMain extends Application {
  29.  
  30. @Override
  31. public void start(Stage primaryStage) throws Exception {
  32. BorderPane root = new BorderPane();
  33.  
  34. Scene scene = new Scene(root, 500, 525);
  35.  
  36. primaryStage.setTitle("Sudoku");
  37. primaryStage.setScene(scene);
  38.  
  39. ObservableList<Sudoku> obsSud = FXCollections.observableArrayList(new Sudoku());
  40.  
  41. TilePane tp = new TilePane();
  42. tp.setPrefColumns(9);
  43. tp.setMaxWidth(500);
  44. tp.setMaxHeight(500);
  45.  
  46. tp.setHgap(5);
  47. tp.setVgap(5);
  48. HashMap<String, Integer> check = new HashMap<String, Integer>();
  49.  
  50. for (int i = 1; i < 10; i++) {
  51. String iVal = ((Integer) i).toString();
  52. check.put(iVal, i);
  53. }
  54. for (int i = 0; i < 81; i++) {
  55.  
  56. TextField tf = new TextField();
  57. tf.setMaxWidth(50);
  58. tf.setPrefHeight(50);
  59. tf.setAlignment(Pos.CENTER);
  60.  
  61. tp.getChildren().add(tf);
  62.  
  63. int row = (i - i % 9) / 9;
  64. int col = i % 9;
  65. int regR = (int) Math.floor(row / 3);
  66. int regC = (int) Math.floor(col / 3);
  67. int sum = regR + regC;
  68.  
  69. if (sum % 2 == 0) {
  70. ((TextField) tp.getChildren().get(i))
  71. .setStyle("-fx-background-radius:0; -fx-background-color:#9CD777;");
  72. } else {
  73. ((TextField) tp.getChildren().get(i))
  74. .setStyle("-fx-background-radius:0; -fx-background-color:#FFFFFF;");
  75. }
  76. }
  77.  
  78. root.setCenter(tp);
  79.  
  80. HBox hbox = new HBox();
  81. TextField txtF = new TextField();
  82. Button solve = new Button("Solve");
  83. Button clear = new Button("Clear");
  84.  
  85. clear.setOnAction((event) -> {
  86. txtF.setText("");
  87. for (int i = 0; i < 81; i++) {
  88. ((TextField) tp.getChildren().get(i)).setText("");
  89. int row = (i - i % 9) / 9;
  90. int col = i % 9;
  91. int regR = (int) Math.floor(row / 3);
  92. int regC = (int) Math.floor(col / 3);
  93. int sum = regR + regC;
  94.  
  95. if (sum % 2 == 0) {
  96. ((TextField) tp.getChildren().get(i))
  97. .setStyle("-fx-background-radius:0; -fx-background-color:#9CD777;");
  98. } else {
  99. ((TextField) tp.getChildren().get(i))
  100. .setStyle("-fx-background-radius:0; -fx-background-color:#FFFFFF;");
  101. }
  102. }
  103. });
  104.  
  105. solve.setOnAction((event) -> {
  106.  
  107. for (int i = 0; i < 81; i++) {
  108. String valTxt = ((TextField) tp.getChildren().get(i)).getText();
  109. if (valTxt.isEmpty() == false) {
  110.  
  111. int row = (i - i % 9) / 9;
  112. int col = i % 9;
  113. if (check.containsKey(valTxt)) {
  114. int val = check.get(valTxt);
  115. obsSud.get(0).setValue(row, col, val);
  116. } else {
  117. ((TextField) tp.getChildren().get(i))
  118. .setStyle("-fx-background-radius:0; -fx-background-color:#DF5151;");
  119. try {
  120. int val = Integer.parseInt(valTxt);
  121. obsSud.get(0).setValue(row, col, val);
  122. } catch (NumberFormatException e) {
  123. obsSud.get(0).setValue(row, col, 10);
  124. }
  125. }
  126. }
  127. }
  128.  
  129. if (obsSud.get(0).sudokuSolver()) {
  130. for (int i = 0; i < 81; i++) {
  131. int row = (i - i % 9) / 9;
  132. int col = i % 9;
  133. String s = ((Integer) obsSud.get(0).getValue(row, col)).toString();
  134. ((TextField) tp.getChildren().get(i)).setText(s);
  135. }
  136. txtF.setText("Här är lösningen");
  137. } else {
  138. txtF.setText("Finns ej lösning");
  139. }
  140. obsSud.set(0, new Sudoku());
  141.  
  142. });
  143.  
  144. hbox.getChildren().addAll(solve, clear, txtF);
  145. root.setBottom(hbox);
  146.  
  147. primaryStage.show();
  148. }
  149.  
  150. public static void main(String[] args) {
  151. Application.launch(args);
  152. }
  153. }
  154.  
  155.  
  156. package sudoku;
  157.  
  158. import java.util.HashMap;
  159. import java.util.HashSet;
  160. import java.util.Set;
  161. import java.util.ArrayList;
  162.  
  163. public class Sudoku {
  164. HashMap<Integer, ArrayList<Integer>> rows;
  165. HashMap<Integer, ArrayList<Integer>> cols;
  166. HashMap<String, ArrayList<Integer>> reg;
  167. int[][] matrix;
  168.  
  169. /**
  170. * Creates an empty 9x9 matrix to be used as an sudoku. Instantiate the
  171. * attribute HashMaps which are corresponding to the Sudokus rows, columns and
  172. * regions.
  173. */
  174. public Sudoku() {
  175. matrix = new int[9][9];
  176.  
  177. rows = new HashMap<Integer, ArrayList<Integer>>();
  178. cols = new HashMap<Integer, ArrayList<Integer>>();
  179. reg = new HashMap<String, ArrayList<Integer>>();
  180.  
  181. }
  182.  
  183. /**
  184. * Sets the value at the square specified by the paramaters, and inserts the
  185. * value in the attribute HashMaps. Index: 0 -> 8.
  186. *
  187. * @param row corresponding to the row where the value is to be set.
  188. * @param col corresponding to the column where the value is to be set.
  189. * @param val, the value to be inserted.
  190. */
  191. public void setValue(int row, int col, int val) {
  192.  
  193. matrix[row][col] = val;
  194. int regR = (int) Math.floor(row / 3);
  195. int regC = (int) Math.floor(col / 3);
  196. String regName = regR + ", " + regC;
  197.  
  198. if (rows.containsKey(row)) {
  199. rows.get(row).add(val);
  200. } else {
  201. rows.put(row, new ArrayList<Integer>());
  202. rows.get(row).add(val);
  203. }
  204.  
  205. if (cols.containsKey(col)) {
  206. cols.get(col).add(val);
  207. } else {
  208. cols.put(col, new ArrayList<Integer>());
  209. cols.get(col).add(val);
  210. }
  211.  
  212. if (reg.containsKey(regName)) {
  213. reg.get(regName).add(val);
  214. } else {
  215. reg.put(regName, new ArrayList<Integer>());
  216. reg.get(regName).add(val);
  217. }
  218. }
  219.  
  220. /**
  221. * Removes an existing value at the specified square, and removes the value from
  222. * the attribute HashMaps. Index: 0 -> 8.
  223. *
  224. * @param row corresponding to the row where the value is to be removed.
  225. * @param col corresponding to the column where the value is to be removed.
  226. */
  227.  
  228. public void removeValue(int row, int col) {
  229. Integer val = matrix[row][col];
  230. int regR = (int) Math.floor(row / 3);
  231. int regC = (int) Math.floor(col / 3);
  232. String regName = regR + ", " + regC;
  233.  
  234. matrix[row][col] = 0;
  235. rows.get(row).remove(val);
  236. cols.get(col).remove(val);
  237. reg.get(regName).remove(val);
  238. }
  239.  
  240. /**
  241. * Checks if the values in the HashMaps is an integer between 1-9, also checks
  242. * if there exists no duplicate values in these HashMaps.
  243. *
  244. * @return true if all checks pass, otherwise false.
  245. */
  246. private boolean check() {
  247. Set<Integer> set = new HashSet<Integer>();
  248. for (int i = 1; i < 10; i++) {
  249. set.add(i);
  250. }
  251.  
  252. for (Integer row : rows.keySet()) {
  253. Set<Integer> rowSet = new HashSet<Integer>(rows.get(row));
  254. if (rowSet.size() != rows.get(row).size() || !set.containsAll(rows.get(row))) {
  255. return false;
  256. }
  257. for (Integer col : cols.keySet()) {
  258. Set<Integer> colSet = new HashSet<Integer>(cols.get(col));
  259. if (colSet.size() != cols.get(col).size()) {
  260. return false;
  261. }
  262. int regR = (int) Math.floor(row / 3);
  263. int regC = (int) Math.floor(col / 3);
  264. String regName = regR + ", " + regC;
  265. Set<Integer> regSet = new HashSet<Integer>(reg.get(regName));
  266. if (regSet.size() != reg.get(regName).size()) {
  267. return false;
  268. }
  269. }
  270. }
  271. return true;
  272. }
  273.  
  274. /** Evaluates which the next position in the Sudoku is, and returns it as an array.
  275. * If the parameter indices corresponds to the end of a row, the row increments by 1 and the column is reset to 0.
  276. * Otherwise the row value is unchanged while the column value is incremented by 1.
  277. * @param row corresponding to the position in the Sudoku, from which the next position is to be evaluated.
  278. * @param col corresponding to the position in the Sudoku, from which the next position is to be evaluated.
  279. * @return the next position in the Sudoku, if the position is at the end return [-1, -1].
  280. */
  281. private int[] nextPos(int row, int col) {
  282. int[] pos = new int[2];
  283. if (col == 8 && row == 8) {
  284. pos[0] = -1;
  285. pos[1] = -1;
  286. } else if (col == 8 && row != 8) {
  287. pos[0] = row + 1;
  288. pos[1] = 0;
  289. } else {
  290. pos[0] = row;
  291. pos[1] = col + 1;
  292. }
  293. return pos;
  294. }
  295.  
  296. /**
  297. * Checks if the value already exists in given row/column/region.
  298. * @param row corresponding to the row in the Sudoku.
  299. * @param col corresponding to the column in the Sudoku.
  300. * @param val, the value to check if it already exists.
  301. * @return true if the value exists, false otherwise.
  302. */
  303. private boolean contains(int row, int col, int val) {
  304. int regR = (int) Math.floor(row / 3);
  305. int regC = (int) Math.floor(col / 3);
  306. String regName = regR + ", " + regC;
  307.  
  308. if (rows.containsKey(row) && rows.get(row).contains(val)) {
  309. return true;
  310. } else if (cols.containsKey(col) && cols.get(col).contains(val)) {
  311. return true;
  312. } else if (reg.containsKey(regName) && reg.get(regR + ", " + regC).contains(val)) {
  313. return true;
  314. } else {
  315. return false;
  316. }
  317. }
  318. /**
  319. * Gets the value at the specified row/column.
  320. * @param row, row corresponding to the specified square.
  321. * @param col, column corresponding to the specified square.
  322. * @return The value at the square.
  323. */
  324. public int getValue(int row, int col) {
  325. return matrix[row][col];
  326. }
  327.  
  328. /**
  329. * Checks if the method check returns true, if it does the method solve is called from the starting position.
  330. * @return the value of solve if the method check returns true, otherwise false.
  331. */
  332. public boolean sudokuSolver() {
  333. if (check()) {
  334. return solve(0, 0);
  335. }
  336. return false;
  337. }
  338. /**
  339. * Evaluates if there exists a solution from the specified square and forward using recursion.
  340. * @param row, row from which to check if a solution exists.
  341. * @param col, column from which to check if a solution exists.
  342. * @return true if a solution to the rest Sudoku exists, false otherwise.
  343. */
  344.  
  345. private boolean solve(int row, int col) {
  346.  
  347. int nextRowPos = nextPos(row, col)[0];
  348. int nextColPos = nextPos(row, col)[1];
  349.  
  350. if (getValue(row, col) != 0) {
  351. if (row == 8 && col == 8) {
  352. return true;
  353. }
  354. return solve(nextRowPos, nextColPos);
  355. } else {
  356. for (int val = 1; val < 10; val++) {
  357. if (contains(row, col, val) == false) {
  358. setValue(row, col, val);
  359. if (row == 8 && col == 8) {
  360. return true;
  361. } else {
  362. if (solve(nextRowPos, nextColPos)) {
  363. return true;
  364. } else {
  365. removeValue(row, col);
  366.  
  367. }
  368. }
  369. }
  370. }
  371. }
  372. return false;
  373. }
  374.  
  375.  
  376.  
  377. }
  378.  
  379.  
  380.  
  381. package sudoku;
  382.  
  383. import static org.junit.Assert.*;
  384. import org.junit.After;
  385. import org.junit.Before;
  386. import org.junit.Test;
  387.  
  388. //import queue_delegate.FifoQueue;
  389.  
  390. import java.util.NoSuchElementException;
  391. import java.util.Queue;
  392. import java.util.Iterator;
  393.  
  394. public class SudokuTest {
  395. Sudoku sud;
  396.  
  397. @Before
  398. public void setUp() throws Exception {
  399. sud = new Sudoku();
  400. }
  401.  
  402. @After
  403. public void tearDown() throws Exception {
  404. sud = null;
  405. }
  406.  
  407. /* lösning till tomt sudoku */
  408.  
  409. @Test
  410. public final void testSudokuEmp() {
  411. assertTrue(sud.sudokuSolver());
  412. }
  413.  
  414. /* lösning till sudoku i figur 1 */
  415. @Test
  416. public final void testSudokuFig1() {
  417. sud.setValue(0, 2, 8);
  418. sud.setValue(0, 5, 9);
  419. sud.setValue(0, 7, 6);
  420. sud.setValue(0, 8, 2);
  421. sud.setValue(1, 8, 5);
  422. sud.setValue(2, 0, 1);
  423. sud.setValue(2, 2, 2);
  424. sud.setValue(2, 3, 5);
  425. sud.setValue(3, 3, 2);
  426. sud.setValue(3, 4, 1);
  427. sud.setValue(3, 7, 9);
  428. sud.setValue(4, 1, 5);
  429. sud.setValue(4, 6, 6);
  430. sud.setValue(5, 0, 6);
  431. sud.setValue(5, 7, 2);
  432. sud.setValue(5, 8, 8);
  433. sud.setValue(6, 0, 4);
  434. sud.setValue(6, 1, 1);
  435. sud.setValue(6, 3, 6);
  436. sud.setValue(6, 5, 8);
  437. sud.setValue(7, 0, 8);
  438. sud.setValue(7, 1, 6);
  439. sud.setValue(7, 4, 3);
  440. sud.setValue(7, 6, 1);
  441. sud.setValue(8, 6, 4);
  442. assertTrue(sud.sudokuSolver());
  443. }
  444.  
  445. @Test
  446. public final void hardestSudokuTest() {
  447. sud.setValue(0, 0, 8);
  448. sud.setValue(1, 2, 3);
  449. sud.setValue(1, 3, 6);
  450. sud.setValue(2, 1, 7);
  451. sud.setValue(2, 4, 9);
  452. sud.setValue(2, 6, 2);
  453. sud.setValue(3, 1, 5);
  454. sud.setValue(3, 5, 7);
  455. sud.setValue(4, 4, 4);
  456. sud.setValue(4, 5, 5);
  457. sud.setValue(4, 6, 7);
  458. sud.setValue(5, 3, 1);
  459. sud.setValue(5, 7, 3);
  460. sud.setValue(6, 2, 1);
  461. sud.setValue(6, 7, 6);
  462. sud.setValue(6, 8, 8);
  463. sud.setValue(7, 3, 5);
  464. sud.setValue(7, 7, 1);
  465. sud.setValue(7, 2, 8);
  466. sud.setValue(8, 1, 9);
  467. sud.setValue(8, 6, 4);
  468. assertTrue(sud.sudokuSolver());
  469. }
  470. /* "lösning" av olösliga sudoku */
  471. @Test
  472. public final void unsolvableTest() {
  473.  
  474. sud.setValue(0, 0, 1);
  475. sud.setValue(0, 5, 1);
  476. assertFalse(sud.sudokuSolver());
  477.  
  478. sud = new Sudoku();
  479.  
  480. sud.setValue(0, 0, 1);
  481. sud.setValue(5, 0, 1);
  482. assertFalse(sud.sudokuSolver());
  483.  
  484. sud = new Sudoku();
  485.  
  486. sud.setValue(0, 0, 1);
  487. sud.setValue(2, 2, 1);
  488. assertFalse(sud.sudokuSolver());
  489.  
  490. }
  491. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement