();
- for (SCell cell : cells) {
- candidates.clear();
- known = "";
- if (cell.getText().isEmpty() || cell.status.equals(CStatus.ERROR)) {
- int row = Character.getNumericValue(cell.getId().charAt(4));
- int column = Character.getNumericValue(cell.getId().charAt(5));
- int block = sudoku.getBlock(row, column);
- for (SCell cell2 : cells) {
- String cell2Text = cell2.getText();
- int row2 = Character.getNumericValue(cell2.getId().charAt(4));
- int column2 = Character.getNumericValue(cell2.getId().charAt(5));
- int block2 = sudoku.getBlock(row2, column2);
- if (cell2Text.length() == 1 && !cell.status.equals(CStatus.ERROR) && !known.contains(cell2Text)) {
- if (row2 == row || column2 == column || block2 == block) {
- known += cell2Text;
- }
- }
- }
- for (int i = 1; i < 10; i++) {
- if (!known.contains(String.valueOf(i))) {
- candidates.add(String.valueOf(i));
- }
- }
- Collections.sort(candidates);
- String cellText = String.join("", candidates);
- cell.setNoteStatus(sudokuService.getFontSize(cellText));
- cell.wrapTextProperty().setValue(true);
- cell.setText(cellText);
- }
- }
- } else {
- for (SCell cell : cells) {
- if (cell.status.equals(CStatus.NOTE)) {
- cell.setText("");
- }
- }
- }
- }
-
- @FXML
- private void hideAllHighLightCells() {
- for (SCell cell : cells) {
- cell.isHighLight = false;
- if (cell.status.equals(CStatus.INIT) && !cell.isHighLight) {
- cell.setInitStatus();
- } else if (cell.status.equals(CStatus.NOTE)) {
- cell.setNoteStatus(sudokuService.getFontSize(cell.getText()));
- cell.setEffect(null);
- } else if (cell.status.equals(CStatus.ERROR)) {
- cell.setErrorStatus();
- cell.setEffect(null);
- }
- }
- }
-
- @FXML
- private void showNoteIcon() {
- if (noteItem.isSelected()) {
- noteIcon.setVisible(true);
- } else {
- noteIcon.setVisible(false);
- }
- }
-
- @FXML
- private void showHelp() {
- AlertUtil.showInfoAlert("Help", "Operation:\n - Move: direction key (↑↓←→) or mouse.\n - Input: numeric key.\n\nFunction:\n - Open: open a local sudoku file.\n - Save: save as sudoku file.\n - Solve: show the answer of sudoku.\n - Highlight: highlight cells.\n - Note mode: input but not verify.\n - Show candidates: show all candidates.\n - Show selected row/column/block.");
- }
-
- @FXML
- private void showAbout() {
- AlertUtil.showInfoAlert("About", "Sudoku v0.1\n2017-07-14");
- }
-
- /**
- * 父控件被移除前调用
- */
- public void onCloseRequest(Event event) {
- stop = true;
- }
-}
diff --git a/games/x-Sudoku/src/main/java/com/xwintop/xJavaFxTool/controller/games/sudoku/CStatus.java b/games/x-Sudoku/src/main/java/com/xwintop/xJavaFxTool/controller/games/sudoku/CStatus.java
deleted file mode 100644
index ab241ac..0000000
--- a/games/x-Sudoku/src/main/java/com/xwintop/xJavaFxTool/controller/games/sudoku/CStatus.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.xwintop.xJavaFxTool.controller.games.sudoku;
-
-public enum CStatus {
- INIT, NOTE, ERROR;
-}
\ No newline at end of file
diff --git a/games/x-Sudoku/src/main/java/com/xwintop/xJavaFxTool/controller/games/sudoku/DLX.java b/games/x-Sudoku/src/main/java/com/xwintop/xJavaFxTool/controller/games/sudoku/DLX.java
deleted file mode 100644
index fec88d3..0000000
--- a/games/x-Sudoku/src/main/java/com/xwintop/xJavaFxTool/controller/games/sudoku/DLX.java
+++ /dev/null
@@ -1,203 +0,0 @@
-package com.xwintop.xJavaFxTool.controller.games.sudoku;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * 利用 Dancing links X 算法解决精确度覆盖问题。
- *
- * 接收一个仅包含0和1的稀疏矩阵,从中选择某些行使每列有且仅有一个“1”覆盖。
- */
-public class DLX {
-
- public int maxAnsNumber;
- public Matrix sparseMatrix;
- private Node root;
- private List nodes;
- private List ans;
-
- public DLX() {
- this.maxAnsNumber = 2;
- this.nodes = new ArrayList();
- this.ans = new ArrayList();
- }
-
- public DLX(Matrix sparseMatrix) {
- this();
- this.sparseMatrix = sparseMatrix;
- }
-
- /**
- * 通过稀疏矩阵建立交叉十字循环双向链,并搜索精确度覆盖解。
- *
- * @param maxAnsNumber
- * Max ans number, default all
- */
- public void solve(int maxAnsNumber) {
- this.maxAnsNumber = maxAnsNumber;
- solve();
- }
-
- public void solve() {
- ans.clear();
- createDancingLinks(sparseMatrix);
- search(0);
- }
-
- private void createDancingLinks(Matrix sparseMatrix) {
- // root && header
- root = new Node(0, 0);
- Node header = root;
- for (int i = 0; i < sparseMatrix.get(0).length; i++) {
- header.right = new Node(0, i + 1);
- header.right.left = header;
- header.header = header;
- header = header.right;
- }
- header.right = root;
- header.right.left = header;
-
- // sparse matrix
- for (int row = 0; row < sparseMatrix.length; row++) {
- header = root.right;
- Node first = null;
- Node last = null;
- for (int col = 0; col < sparseMatrix.get(0).length; col++) {
- if (sparseMatrix.get(row, col) == 1) {
- Node node = header;
- while (node.down != null) {
- node = node.down;
- }
- node.down = new Node(header, row + 1, col + 1);
- node.down.up = node;
- if (first == null) {
- first = node.down;
- }
- node.down.left = last;
- if (last != null) {
- node.down.left.right = node.down;
- }
- last = node.down;
- header.size++;
- }
- header = header.right;
- }
- if (last != null) {
- first.left = last;
- first.left.right = first;
- }
- }
-
- header = root.right;
- for (int col = 0; col < sparseMatrix.get(0).length; col++) {
- Node node = header;
- while (node.down != null) {
- node = node.down;
- }
- node.down = header;
- node.down.up = node;
- header = header.right;
- }
- }
-
- private void search(int k) {
- if (root.right == root) {
- ans.add(nodesToMatrix(sparseMatrix, nodes));
- return;
- }
-
- Node c = choose();
- cover(c);
-
- for (Node x = c.down; x != c; x = x.down) {
- if (nodes.size() > k) {
- nodes.remove(k);
- }
- nodes.add(k, x);
- for (Node y = x.right; y != x; y = y.right) {
- cover(y.header);
- }
-
- search(k + 1);
-
- if (ans.size() >= maxAnsNumber) return;
-
- // uncover
- Node xr = nodes.get(k);
- for (Node yr = xr.left; yr != xr; yr = yr.left) {
- uncover(yr.header);
- }
- }
- uncover(c);
- }
-
- // choose column with least 1
- private Node choose() {
- Node min = root.right;
- for (Node header = min.right; header != root; header = header.right) {
- if (min.size > header.size) {
- min = header;
- }
- }
- return min;
- }
-
- private void cover(Node c) {
- c.left.right = c.right;
- c.right.left = c.left;
- for (Node x = c.down; x != c; x = x.down) {
- for (Node y = x.right; y != x; y = y.right) {
- y.up.down = y.down;
- y.down.up = y.up;
- y.header.size--;
- }
- }
- }
-
- private void uncover(Node c) {
- c.left.right = c;
- c.right.left = c;
- for (Node x = c.up; x != c; x = x.up) {
- for (Node y = x.left; y != x; y = y.left) {
- y.up.down = y;
- y.down.up = y;
- y.header.size++;
- }
- }
- }
-
- private Matrix nodesToMatrix(Matrix sparseMatrix, List nodes) {
- Matrix matrix = new Matrix(nodes.size());
- for (int i = 0; i < nodes.size(); i++) {
- int line = nodes.get(i).row - 1;
- matrix.set(i, sparseMatrix.get(line));
- }
- return matrix;
- }
-
- public List getAns() {
- return ans;
- }
-}
-
-/**
- * Node类。辅助DLX算法解决精确度覆盖问题。
- *
- * Node类一般包含上下左右行列及header七个属性,第一行辅助元素为特殊Node,即ColumnNode(可用继承实现),另包含size属性,
- * 表示所在列中1的个数。每个Node的header属性指向所在列的第一行辅助元素ColumnNode,ColumnNode指向自身。
- */
-class Node {
- int size = 0;
- int row, col; // col for debug
- Node up, down, left, right, header;
-
- Node(int row, int col) {
- this.row = row;
- this.col = col;
- }
-
- Node(Node header, int row, int col) {
- this(row, col);
- this.header = header;
- }
-}
\ No newline at end of file
diff --git a/games/x-Sudoku/src/main/java/com/xwintop/xJavaFxTool/controller/games/sudoku/Matrix.java b/games/x-Sudoku/src/main/java/com/xwintop/xJavaFxTool/controller/games/sudoku/Matrix.java
deleted file mode 100644
index cda622f..0000000
--- a/games/x-Sudoku/src/main/java/com/xwintop/xJavaFxTool/controller/games/sudoku/Matrix.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package com.xwintop.xJavaFxTool.controller.games.sudoku;
-
-public class Matrix {
-
- public int length;
- private int[][] array;
-
- Matrix(int row) {
- this.length = row;
- this.array = new int[row][];
- }
-
- Matrix(int row, int col) {
- this.length = row;
- this.array = new int[row][col];
- }
-
- Matrix(int[][] array) {
- this.length = array.length;
- this.array = new int[length][array[0].length];
- for (int i = 0; i < length; i++) {
- System.arraycopy(array[i], 0, this.array[i], 0, array[i].length);
- }
- }
-
- public void put(int row, int col, int value) {
- set(row, col, value);
- }
-
- public void set(int row, int[] array) {
- this.array[row] = new int[array.length];
- System.arraycopy(array, 0, this.array[row], 0, array.length);
- }
-
- public void set(int row, int col, int value) {
- array[row][col] = value;
- }
-
- public int[] get(int row) {
- return array[row];
- }
-
- public int get(int row, int col) {
- return array[row][col];
- }
-
- public int[][] toArray() {
- return array;
- }
-
- public void print() {
- print(" ");
- }
-
- public void print(String seprator) {
- for (int i = 0; i < length; i++) {
- for (int j = 0; j < array[0].length; j++) {
- System.out.print(array[i][j] + seprator);
- }
- System.out.println();
- }
- }
-
-}
diff --git a/games/x-Sudoku/src/main/java/com/xwintop/xJavaFxTool/controller/games/sudoku/SCell.java b/games/x-Sudoku/src/main/java/com/xwintop/xJavaFxTool/controller/games/sudoku/SCell.java
deleted file mode 100644
index c5eb123..0000000
--- a/games/x-Sudoku/src/main/java/com/xwintop/xJavaFxTool/controller/games/sudoku/SCell.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package com.xwintop.xJavaFxTool.controller.games.sudoku;
-
-import javafx.scene.control.Button;
-import javafx.scene.effect.InnerShadow;
-import javafx.scene.paint.Color;
-
-public class SCell extends Button {
-
- public CStatus status;
- public Boolean isHighLight;
-
- public SCell() {
- isHighLight = false;
- setInitStatus();
- }
-
- public void setInitStatus() {
- setEffect(null);
- setStyle("-fx-text-fill: rgb(132, 117, 225)");
- status = CStatus.INIT;
- isHighLight = false;
- }
-
- public void setErrorStatus() {
- setStyle("-fx-text-fill: red");
- setText("X");
- status = CStatus.ERROR;
- }
-
- public void setHighLightStatus() {
- InnerShadow innerShadow = new InnerShadow();
- innerShadow.setRadius(50);
- innerShadow.setWidth(30);
- innerShadow.setColor(Color.DEEPSKYBLUE);
- setEffect(innerShadow);
- isHighLight = true;
- }
-
- /**
- * set note mode button and candidates button Status
- */
- public void setNoteStatus(int fontSize) {
- setStyle(String.format("-fx-text-fill: black; -fx-font-weight: normal; -fx-font-size: %d", fontSize));
- status = CStatus.NOTE;
- }
-
- public void setNoteText(String input) {
- if (input.isEmpty() || !"123456789".contains(input)) return;
- int fontSize = 20;
- String cellText = getText();
- if (status.equals(CStatus.ERROR)) {
- cellText = "";
- }
- if (!status.equals(CStatus.INIT) || cellText.isEmpty()) {
- if (cellText.contains(input)) cellText = String.join("", cellText.split(input));
- else cellText += input;
- if (cellText.length() <= 2) fontSize = 24 - cellText.length() * 4;
- else fontSize = 12;
- setNoteStatus(fontSize);
- wrapTextProperty().setValue(true);
- setText(cellText);
- }
- }
-}
\ No newline at end of file
diff --git a/games/x-Sudoku/src/main/java/com/xwintop/xJavaFxTool/controller/games/sudoku/Sudoku.java b/games/x-Sudoku/src/main/java/com/xwintop/xJavaFxTool/controller/games/sudoku/Sudoku.java
deleted file mode 100644
index 5c9c07f..0000000
--- a/games/x-Sudoku/src/main/java/com/xwintop/xJavaFxTool/controller/games/sudoku/Sudoku.java
+++ /dev/null
@@ -1,231 +0,0 @@
-package com.xwintop.xJavaFxTool.controller.games.sudoku;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-
-/**
- * 生成唯一解数独,并且提供解数独方法。
- */
-public class Sudoku {
-
- private Matrix puzzle;
- private Matrix ans;
-
- /**
- * 初始化数独,生成数独问题及答案。
- *
随机生成数独第一行,其余补0,将此打乱转为稀疏矩阵求解并返回其中一个全覆盖矩阵作为数独答案,随机取其稀疏矩阵并验证作为数独问题。
- *
- * @param level 默认值为1
- * @return 以List类型返回数独的问题和答案
- */
- public List init() {
- return init(1);
- }
-
- public List init(int level) {
- int clue = getClue(level);
- // 随机数独第一行
- puzzle = new Matrix(9, 9);
- List firstRow = new ArrayList(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9));
- Collections.shuffle(firstRow);
- for (int i = 0; i < 9; i++) {
- puzzle.set(0, i, firstRow.get(i));
- }
- // 返回乱序精确度覆盖矩阵
- // DLX dlx = new DLX(createSparseMatrix(puzzle));
- List tmpList = Arrays.asList(createSparseMatrix(puzzle).toArray());
- Collections.shuffle(tmpList);
- DLX dlx = new DLX(new Matrix(tmpList.toArray(new int[tmpList.size()][])));
- dlx.solve();
- Matrix coverMatrix = dlx.getAns().get(0);
-
- ans = coverMatrixToSudoku(coverMatrix);
-
- // 选取子矩阵并转为数独问题
- List coverList = Arrays.asList(coverMatrix.toArray());
- do {
- Collections.shuffle(coverList);
- Matrix puzzleCoverMatrix = new Matrix(coverList.subList(0, clue).toArray(new int[clue][]));
- puzzle = coverMatrixToSudoku(puzzleCoverMatrix);
- } while (!testPuzzle(puzzle, level));
-
- // 以List类型返回puzzle和ans
- List ret = new ArrayList();
- ret.add(puzzle);
- ret.add(ans);
- return ret;
- }
-
- /**
- * 解数独问题,以List类型返回数独的所有解,并将数独问题及其中一个解保存于成员变量puzzle和ans中。
- */
- public List solve(Matrix puzzle) {
- this.puzzle = puzzle;
- List ansList = new ArrayList();
- Matrix sparseMatrix = createSparseMatrix(puzzle);
- DLX dlx = new DLX(sparseMatrix);
- dlx.solve();
- for (Matrix x : dlx.getAns()) {
- ansList.add(coverMatrixToSudoku(x));
- }
- this.ans = ansList.get(0);
- return ansList;
- }
-
- /**
- * 根据数独问题,创建稀疏矩阵,将数独问题转为精确度覆盖问题。四个约束条件:
- *
- * - 每格有且只有一个数字 (0-80) index = i * 9 + j
- *
- 每行九个数字不重复 (81-161) index = i * 9 + x - 1 + 81
- *
- 每列九个数字不重复 (162-242) index = j * 9 + x - 1 + 162
- *
- 每块九个数字不重复 (243-323) index = n * 9 + x - 1 + 243
- *
- * 转换后,每行有 4 * 9 * 9 = 324 个元素 行数最多有 9 * 9 * 9 = 729,理论上有 9 + 72 × 9 = 657 行
- *
- * @param puzzle Sudoku puzzle
- * @return Sparse matrix
- */
- public Matrix createSparseMatrix(Matrix puzzle) {
- List lines = new ArrayList();
- for (int i = 0; i < 9; i++) {
- for (int j = 0; j < 9; j++) {
- if (puzzle.get(i, j) != 0) {
- int[] line = new int[9 * 9 * 4];
- line[9 * i + j] = 1;
- line[9 * i + puzzle.get(i, j) - 1 + 9 * 9] = 1;
- line[9 * j + puzzle.get(i, j) - 1 + 9 * 9 * 2] = 1;
- line[9 * getBlock(i, j) + puzzle.get(i, j) - 1 + 9 * 9 * 3] = 1;
- lines.add(line);
- } else {
- for (int k = 1; k <= 9; k++) {
- int[] line = new int[9 * 9 * 4];
- line[9 * i + j] = 1;
- line[9 * i + k - 1 + 9 * 9] = 1;
- line[9 * j + k - 1 + 9 * 9 * 2] = 1;
- line[9 * getBlock(i, j) + k - 1 + 9 * 9 * 3] = 1;
- lines.add(line);
- }
- }
- }
- }
- Matrix sparseMatrix = new Matrix(lines.toArray(new int[lines.size()][]));
- return sparseMatrix;
- }
-
- public Matrix coverMatrixToSudoku(Matrix coverMatrix) {
- Matrix sudoku = new Matrix(9, 9);
- for (int i = 0; i < coverMatrix.length; i++) {
- int row = 0, col = 0, num = 0;
- for (int j = 0; j < coverMatrix.get(0).length; j++) {
- if (coverMatrix.get(i, j) == 1) {
- if (j >= 81 && j < 162) {
- row = (j - 81) / 9;
- num = j % 9 + 1;
- } else if (j >= 162 && j < 243) {
- col = (j - 162) / 9;
- }
- }
- }
- sudoku.set(row, col, num);
- }
- return sudoku;
- }
-
- /**
- * 数独分布检验及唯一解检验。
- */
- private boolean testPuzzle(Matrix puzzle, int level) {
- // 数独分布检验
- if (!testBlankNumber(puzzle, level)) return false;
- // 唯一解检验
- if (!testOnlyAns(puzzle)) return false;
-
- return true;
- }
-
- private boolean testBlankNumber(Matrix puzzle, int level) {
- int minBlankNumber = 0;
- int maxBlankNumber = 9;
- if (level == 1) {
- minBlankNumber = 3;
- maxBlankNumber = 7;
- } else if (level == 2) {
- minBlankNumber = 4;
- maxBlankNumber = 8;
- } else if (level == 3) {
- minBlankNumber = 4;
- maxBlankNumber = 9;
- } else if (level == 4) {
- minBlankNumber = 5;
- maxBlankNumber = 9;
- }
-
- int rowBlankNumber;
- for (int[] row : puzzle.toArray()) {
- rowBlankNumber = 0;
- for (int x : row) {
- if (x == 0) rowBlankNumber++;
- }
- if (rowBlankNumber < minBlankNumber || rowBlankNumber > maxBlankNumber) return false;
- }
- int colsBlankNumber[] = new int[9];
- int blocksBlankNumber[] = new int[9];
- for (int i = 0; i < 9; i++) {
- for (int j = 0; j < 9; j++) {
- if (puzzle.get(i, j) == 0) {
- colsBlankNumber[j]++;
- blocksBlankNumber[getBlock(i, j)]++;
- }
- }
- }
- for (int k = 0; k < 9; k++) {
- if (colsBlankNumber[k] < minBlankNumber || colsBlankNumber[k] > maxBlankNumber) return false;
- if (blocksBlankNumber[k] < minBlankNumber || blocksBlankNumber[k] > maxBlankNumber) return false;
- }
- return true;
- }
-
- private boolean testOnlyAns(Matrix puzzle) {
- DLX dlx = new DLX(new Sudoku().createSparseMatrix(puzzle));
- dlx.solve(2);
- if (dlx.getAns().size() > 1) return false;
- return true;
- }
-
- // TODO
- private int getClue(int level) {
- if (level == 1) return 42;
- else if (level == 2) return 36;
- else if (level == 3) return 30;
- else if (level == 4) return 26;
- else System.err.println("Level must be one of 1, 2, 3, 4.");
- return 0;
- }
-
- /**
- * 给定行列索引,返回所在区块索引。
- */
- public int getBlock(int i, int j) {
- if (i < 3) {
- if (j < 3) return 0;
- else if (j < 6) return 1;
- else return 2;
- } else if (i < 6) {
- if (j < 3) return 3;
- else if (j < 6) return 4;
- else return 5;
-
- } else {
- if (j < 3) return 6;
- else if (j < 6) return 7;
- else return 8;
- }
- }
-
- public Matrix getAns() {
- return ans;
- }
-}
diff --git a/games/x-Sudoku/src/main/java/com/xwintop/xJavaFxTool/services/games/SudokuService.java b/games/x-Sudoku/src/main/java/com/xwintop/xJavaFxTool/services/games/SudokuService.java
deleted file mode 100644
index 5ce50c1..0000000
--- a/games/x-Sudoku/src/main/java/com/xwintop/xJavaFxTool/services/games/SudokuService.java
+++ /dev/null
@@ -1,200 +0,0 @@
-package com.xwintop.xJavaFxTool.services.games;
-
-import com.xwintop.xJavaFxTool.controller.games.SudokuController;
-import com.xwintop.xJavaFxTool.controller.games.sudoku.CStatus;
-import com.xwintop.xJavaFxTool.controller.games.sudoku.Matrix;
-import com.xwintop.xJavaFxTool.controller.games.sudoku.SCell;
-import com.xwintop.xJavaFxTool.controller.games.sudoku.Sudoku;
-import com.xwintop.xcore.util.javafx.AlertUtil;
-import javafx.scene.paint.Color;
-import lombok.Getter;
-import lombok.Setter;
-import lombok.extern.slf4j.Slf4j;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @ClassName: SudokuService
- * @Description: 数独游戏
- * @author: xufeng
- * @date: 2020/1/6 16:08
- */
-
-@Getter
-@Setter
-@Slf4j
-public class SudokuService {
- private SudokuController sudokuController;
-
- Sudoku sudoku = new Sudoku();
-
- private Matrix puzzle;
- private Matrix ans;
- private Map ansMap;
-
- private boolean stop;
- private long startTime;
- private long curTime;
- private Thread thread;
-
- public void setCellNums(Matrix puzzle) {
- for (int i = 0; i < 9; i++) {
- for (int j = 0; j < 9; j++) {
- sudokuController.getCells().get(i * 9 + j).setInitStatus();
- if (puzzle.get(i, j) != 0) {
- sudokuController.getCells().get(i * 9 + j).setText(Integer.toString(puzzle.get(i, j)));
- } else {
- sudokuController.getCells().get(i * 9 + j).setText("");
- }
- }
- }
- }
-
- public void initTimer() {
- stop = false;
- startTime = System.currentTimeMillis();
- thread = new Thread() {
- public void run() {
- while (!stop) {
- curTime = System.currentTimeMillis();
- int interval = (int) ((curTime - startTime) / 1000);
- int hour = interval / 3600;
- int minute = (interval / 60) % 60;
- int second = interval % 60;
- sudokuController.getTimer().setText(String.format("%02d:%02d:%02d", hour, minute, second));
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
-
- }
- };
- thread.setDaemon(true);
- thread.start();
- }
-
- /**
- * 将二维数组类型的数独ANS转为Map类型。
- */
- public Map ansParse(Matrix ans) {
- Map ansMap = new HashMap();
- for (int i = 0; i < 9; i++) {
- for (int j = 0; j < 9; j++) {
- ansMap.put("cell" + i + j, String.valueOf(ans.get(i, j)));
- }
- }
- return ansMap;
- }
-
- public boolean checkSucess() {
- for (SCell cell : sudokuController.getCells()) {
- if (cell.getText().isEmpty() || cell.status.equals(CStatus.NOTE)) {
- return false;
- }
- }
- return true;
- }
-
- public void setInputText(SCell cell, String input) {
- if (!(cell.getText().isEmpty() || cell.status.equals(CStatus.NOTE) || cell.status.equals(CStatus.ERROR)))
- return;
- if (!input.isEmpty() && "123456789".contains(input)) {
- if (ansMap.get(cell.getId()).equals(input)) {
- cell.setInitStatus();
- ;
- cell.setText(input);
- if (checkSucess()) {
- stop = true;
- AlertUtil.showInfoAlert("Sucessful", "Sucessful!\nTime: " + sudokuController.getTimer().getText());
- }
- } else {
- cell.setErrorStatus();
- int leftTimes = Integer.parseInt(sudokuController.getTimes().getText()) - 1;
- if (leftTimes < 0) {
- AlertUtil.showInfoAlert("Fail", "Fail!\nTime: " + sudokuController.getTimer().getText());
- sudokuController.getTimes().setFill(Color.RED);
- }
- sudokuController.getTimes().setText(String.valueOf(leftTimes));
- }
- } else if (input.equals("0")) {
- cell.setText("");
- }
- }
-
- public void highLight(SCell cell) {
- // cell空或ERROR或已经高亮,取消所有高亮
- if (cell.getText().isEmpty() || cell.status.equals(CStatus.ERROR) || cell.status.equals(CStatus.NOTE) || cell.isHighLight) {
- for (SCell cell2 : sudokuController.getCells()) {
- if (cell2.status.equals(CStatus.INIT)) {
- cell2.setInitStatus();
- }
- }
- // cell未高亮,则执行高亮
- } else {
- for (SCell cell2 : sudokuController.getCells()) {
- if (cell2.getText().equals(cell.getText()) && !cell2.status.equals(CStatus.NOTE)) {
- cell2.setHighLightStatus();
- } else if (cell2.status.equals(CStatus.INIT)) {
- cell2.setInitStatus();
- } else if (cell2.status.equals(CStatus.ERROR)) {
- cell2.setEffect(null);
- cell2.isHighLight = false;
- cell2.setErrorStatus();
- } else if (cell2.status.equals(CStatus.NOTE)) {
- cell2.setEffect(null);
- cell2.isHighLight = false;
- cell2.setNoteStatus(getFontSize(cell2.getText()));
- }
- }
- }
- }
-
- public void showSelectedCells(SCell focusCells) {
- if (!sudokuController.getShowSelectedRC().isSelected() && !sudokuController.getShowSelectedBlock().isSelected())
- return;
- List showCells = new ArrayList();
- for (SCell cell : sudokuController.getCells()) {
- if (sudokuController.getShowSelectedRC().isSelected() && (cell.getId().charAt(4) == focusCells.getId().charAt(4) || cell.getId().charAt(5) == focusCells.getId().charAt(5))) {
- showCells.add(cell);
- }
- if (sudokuController.getShowSelectedBlock().isSelected() && sudoku.getBlock(Character.getNumericValue(cell.getId().charAt(4)), Character.getNumericValue(cell.getId().charAt(5))) == sudoku.getBlock(Character.getNumericValue(focusCells.getId().charAt(4)), Character.getNumericValue(focusCells.getId().charAt(5)))) {
- showCells.add(cell);
- }
- }
- if (sudokuController.getShowSelectedRC().isSelected() || sudokuController.getShowSelectedBlock().isSelected()) {
- for (SCell cell : sudokuController.getCells()) {
- if (cell.equals(focusCells)) {
- cell.setEffect(null);
- cell.isHighLight = false;
- } else if (showCells.contains(cell)) {
- cell.setHighLightStatus();
- } else {
- cell.isHighLight = false;
- if (cell.status.equals(CStatus.INIT) && !cell.isHighLight) {
- cell.setInitStatus();
- } else if (cell.status.equals(CStatus.NOTE)) {
- cell.setNoteStatus(getFontSize(cell.getText()));
- cell.setEffect(null);
- } else if (cell.status.equals(CStatus.ERROR)) {
- cell.setErrorStatus();
- cell.setEffect(null);
- }
- }
- }
- }
- }
-
- public int getFontSize(String cellText) {
- if (cellText.length() <= 2) return 24 - cellText.length() * 4;
- else return 12;
- }
-
- public SudokuService(SudokuController sudokuController) {
- this.sudokuController = sudokuController;
- }
-}
diff --git a/games/x-Sudoku/src/main/java/com/xwintop/xJavaFxTool/view/games/SudokuView.java b/games/x-Sudoku/src/main/java/com/xwintop/xJavaFxTool/view/games/SudokuView.java
deleted file mode 100644
index 204d9ac..0000000
--- a/games/x-Sudoku/src/main/java/com/xwintop/xJavaFxTool/view/games/SudokuView.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.xwintop.xJavaFxTool.view.games;
-
-import com.xwintop.xJavaFxTool.controller.games.sudoku.SCell;
-import javafx.fxml.FXML;
-import javafx.fxml.Initializable;
-import javafx.scene.control.CheckMenuItem;
-import javafx.scene.control.ChoiceBox;
-import javafx.scene.image.ImageView;
-import javafx.scene.text.Text;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.util.List;
-
-/**
- * @ClassName: SudokuView
- * @Description: 数独游戏
- * @author: xufeng
- * @date: 2020/1/6 16:08
- */
-
-@Getter
-@Setter
-public abstract class SudokuView implements Initializable {
- @FXML
- protected CheckMenuItem noteItem;
- @FXML
- protected CheckMenuItem showCandidates;
- @FXML
- protected CheckMenuItem showSelectedRC;
- @FXML
- protected CheckMenuItem showSelectedBlock;
- @FXML
- protected ImageView noteIcon;
- @FXML
- protected Text times;
- @FXML
- protected Text timer;
- @FXML
- protected ChoiceBox levelChoiceBox;
- @FXML
- protected List cells;
-}
diff --git a/games/x-Sudoku/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/games/Sudoku.css b/games/x-Sudoku/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/games/Sudoku.css
deleted file mode 100644
index f949a4f..0000000
--- a/games/x-Sudoku/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/games/Sudoku.css
+++ /dev/null
@@ -1,30 +0,0 @@
-.root {
- -fx-font-size: 16.0px;
- -fx-font-family: "Microsoft Yahei", "Segoe UI", Arial, sans-serif;
-}
-
-.background {
- -fx-background-color: white;
-}
-
-.button {
- -fx-pref-width: 48.0px;
- -fx-pref-height: 48.0px;
- -fx-text-fill: rgb(132.0,117.0,225.0);
- -fx-font-size: 20.0;
- -fx-font-weight: bold;
- -fx-background-radius: 0.0;
- -fx-background-color: rgb(175.0, 230.0, 230.0);
-}
-
-.button:hover {
- -fx-background-color: lightskyblue;
-}
-
-.button:focused {
- -fx-background-color: darkturquoise;
-}
-
-.custom {
- -fx-background-color: rgb(175.0, 230.0, 230.0);
-}
\ No newline at end of file
diff --git a/games/x-Sudoku/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/games/Sudoku.fxml b/games/x-Sudoku/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/games/Sudoku.fxml
deleted file mode 100644
index 7450957..0000000
--- a/games/x-Sudoku/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/games/Sudoku.fxml
+++ /dev/null
@@ -1,421 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/games/x-Sudoku/src/main/resources/config/toolFxmlLoaderConfiguration.xml b/games/x-Sudoku/src/main/resources/config/toolFxmlLoaderConfiguration.xml
deleted file mode 100644
index e9ccd3d..0000000
--- a/games/x-Sudoku/src/main/resources/config/toolFxmlLoaderConfiguration.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
- /com/xwintop/xJavaFxTool/fxmlView/games/Sudoku.fxml
- locale.Sudoku
-
- Title
-
-
- p-games
- Node
-
-
\ No newline at end of file
diff --git a/games/x-Sudoku/src/main/resources/locale/Sudoku.properties b/games/x-Sudoku/src/main/resources/locale/Sudoku.properties
deleted file mode 100644
index bfcc713..0000000
--- a/games/x-Sudoku/src/main/resources/locale/Sudoku.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-# Dorian.properties\u662F\u9ED8\u8BA4\u7684"Dorian"\u8D44\u6E90\u675F\u6587\u4EF6\u3002
-# \u4F5C\u4E3A\u4E2D\u56FD\u4EBA,\u6211\u7528\u81EA\u5DF1\u7684\u5730\u533A\u4F5C\u4E3A\u9ED8\u8BA4
-Title=\u6570\u72EC
\ No newline at end of file
diff --git a/games/x-Sudoku/src/main/resources/locale/Sudoku_en_US.properties b/games/x-Sudoku/src/main/resources/locale/Sudoku_en_US.properties
deleted file mode 100644
index 67c066f..0000000
--- a/games/x-Sudoku/src/main/resources/locale/Sudoku_en_US.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-# 文件Dorian_en_US.properties,是美国地区的资源束
-# 它覆盖了默认资源束
-Title=Sudoku
\ No newline at end of file
diff --git a/games/x-X2048/.gitignore b/games/x-X2048/.gitignore
deleted file mode 100644
index 653afb9..0000000
--- a/games/x-X2048/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-# Default ignored files
-#/.gitignore
-/x-X2048.iml
-/log/
-/target/
\ No newline at end of file
diff --git a/games/x-X2048/README.md b/games/x-X2048/README.md
deleted file mode 100644
index 7c300d6..0000000
--- a/games/x-X2048/README.md
+++ /dev/null
@@ -1 +0,0 @@
-X2048
\ No newline at end of file
diff --git a/games/x-X2048/README_EN.md b/games/x-X2048/README_EN.md
deleted file mode 100644
index 7c300d6..0000000
--- a/games/x-X2048/README_EN.md
+++ /dev/null
@@ -1 +0,0 @@
-X2048
\ No newline at end of file
diff --git a/games/x-X2048/pom.xml b/games/x-X2048/pom.xml
deleted file mode 100644
index 0001e62..0000000
--- a/games/x-X2048/pom.xml
+++ /dev/null
@@ -1,91 +0,0 @@
-
- 4.0.0
-
- com.xwintop
- x-X2048
- 0.0.1
- jar
- x-X2048
-
-
- 1.8
- 1.8
- UTF-8
-
-
-
-
- aliyunmaven
- http://maven.aliyun.com/nexus/content/groups/public/
-
-
- xwintop-maven
- https://864381832.github.io/maven/repository
-
-
- spring-snapshots
- http://repo.spring.io/snapshot
-
- true
-
-
-
- spring-milestones
- http://repo.spring.io/milestone
-
-
-
-
-
- junit
- junit
- 4.12
- test
-
-
- com.xwintop
- xcore
- 0.0.6
-
-
-
- org.projectlombok
- lombok
- 1.18.12
- provided
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-assembly-plugin
- 2.5.5
-
- false
- utf-8
-
-
-
-
-
-
- jar-with-dependencies
-
-
-
-
- make-assembly
- package
-
- single
-
-
-
-
-
-
-
diff --git a/games/x-X2048/src/main/java/com/xwintop/xJavaFxTool/Main.java b/games/x-X2048/src/main/java/com/xwintop/xJavaFxTool/Main.java
deleted file mode 100644
index 068eec9..0000000
--- a/games/x-X2048/src/main/java/com/xwintop/xJavaFxTool/Main.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.xwintop.xJavaFxTool;
-
-import com.xwintop.xcore.util.javafx.JavaFxSystemUtil;
-import javafx.application.Application;
-import javafx.event.EventHandler;
-import javafx.fxml.FXMLLoader;
-import javafx.scene.Parent;
-import javafx.scene.Scene;
-import javafx.stage.Stage;
-import javafx.stage.WindowEvent;
-import lombok.extern.slf4j.Slf4j;
-
-import java.net.URL;
-import java.util.ResourceBundle;
-
-@Slf4j
-public class Main extends Application {
- public static void main(String[] args) {
- try {
- launch(args);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- @Override
- public void start(Stage primaryStage) throws Exception {
- FXMLLoader fXMLLoader = Main.getFXMLLoader();
- ResourceBundle resourceBundle = fXMLLoader.getResources();
- Parent root = fXMLLoader.load();
- primaryStage.setResizable(true);
- primaryStage.setTitle(resourceBundle.getString("Title"));
-// primaryStage.getIcons().add(new Image("/images/icon.jpg"));
- double[] screenSize = JavaFxSystemUtil.getScreenSizeByScale(0.74D, 0.8D);
- primaryStage.setScene(new Scene(root, screenSize[0], screenSize[1]));
- primaryStage.show();
- primaryStage.setOnCloseRequest(new EventHandler() {
- @Override
- public void handle(WindowEvent event) {
- System.exit(0);
- }
- });
- }
-
- public static FXMLLoader getFXMLLoader() {
- ResourceBundle resourceBundle = ResourceBundle.getBundle("locale.X2048");
- URL url = Object.class.getResource("/com/xwintop/xJavaFxTool/fxmlView/games/X2048.fxml");
- FXMLLoader fXMLLoader = new FXMLLoader(url, resourceBundle);
- return fXMLLoader;
- }
-}
\ No newline at end of file
diff --git a/games/x-X2048/src/main/java/com/xwintop/xJavaFxTool/controller/games/X2048Controller.java b/games/x-X2048/src/main/java/com/xwintop/xJavaFxTool/controller/games/X2048Controller.java
deleted file mode 100644
index e9d7026..0000000
--- a/games/x-X2048/src/main/java/com/xwintop/xJavaFxTool/controller/games/X2048Controller.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package com.xwintop.xJavaFxTool.controller.games;
-
-import com.xwintop.xJavaFxTool.services.games.X2048Service;
-import com.xwintop.xJavaFxTool.view.games.X2048View;
-import javafx.application.Platform;
-import javafx.event.ActionEvent;
-import javafx.event.EventHandler;
-import javafx.scene.input.*;
-import lombok.Getter;
-import lombok.Setter;
-import lombok.extern.slf4j.Slf4j;
-
-import java.net.URL;
-import java.util.ResourceBundle;
-
-/**
- * @ClassName: X2048Controller
- * @Description: 2048游戏
- * @author: xufeng
- * @date: 2019/4/25 0025 23:24
- */
-
-@Getter
-@Setter
-@Slf4j
-public class X2048Controller extends X2048View implements EventHandler {
- private X2048Service x2048Service = new X2048Service(this);
-
- @Override
- public void initialize(URL location, ResourceBundle resources) {
- initView();
- initEvent();
- initService();
- }
-
- private void initView() {
- }
-
- private void initEvent() {
- }
-
- private void initService() {
- x2048Service.Init();
- Platform.runLater(()->{
- x2048Service.ImplInit(4);
- });
- }
-
- @Override
- public void handle(KeyEvent event) {
- if (event.getEventType() == KeyEvent.KEY_PRESSED) {
- x2048Service.OnKeyPressed(event);
- } else if (event.getEventType() == KeyEvent.KEY_RELEASED) {
- x2048Service.OnKeyReleased(event);
- }
- }
-
- public void OnReset(ActionEvent actionEvent) {
- x2048Service.ImplInit(x2048Service.getSize());
- }
-
- public void OnSwipeDown(SwipeEvent swipeEvent) {
- x2048Service.ProcessCode(KeyCode.DOWN);
- }
-
- public void OnSwipeLeft(SwipeEvent swipeEvent) {
- x2048Service.ProcessCode(KeyCode.LEFT);
- }
-
- public void OnSwipeRight(SwipeEvent swipeEvent) {
- x2048Service.ProcessCode(KeyCode.RIGHT);
- }
-
- public void OnSwipeUp(SwipeEvent swipeEvent) {
- x2048Service.ProcessCode(KeyCode.UP);
- }
-
- public void OnMousePressed(MouseEvent mouseEvent) {
- if (mouseEvent.getButton() == MouseButton.PRIMARY) {
- if (!x2048Service.isMMousePressed()) {
- x2048Service.setMMousePressed(true);
- x2048Service.setMPressedPoint(new X2048Service.Point((int) mouseEvent.getX(), (int) mouseEvent.getY()));
- }
- }
- }
-
- public void OnMouseReleased(MouseEvent mouseEvent) {
- if (mouseEvent.getButton() == MouseButton.PRIMARY) {
- if (x2048Service.isMMousePressed()) {
- x2048Service.setMMousePressed(false);
- x2048Service.setMReleasedPoint(new X2048Service.Point((int) mouseEvent.getX(), (int) mouseEvent.getY()));
- x2048Service.MouseManipulation();
- }
- }
-
- }
-}
\ No newline at end of file
diff --git a/games/x-X2048/src/main/java/com/xwintop/xJavaFxTool/services/games/X2048Service.java b/games/x-X2048/src/main/java/com/xwintop/xJavaFxTool/services/games/X2048Service.java
deleted file mode 100644
index 6fc10c0..0000000
--- a/games/x-X2048/src/main/java/com/xwintop/xJavaFxTool/services/games/X2048Service.java
+++ /dev/null
@@ -1,693 +0,0 @@
-package com.xwintop.xJavaFxTool.services.games;
-
-import com.xwintop.xJavaFxTool.controller.games.X2048Controller;
-import javafx.animation.*;
-import javafx.beans.property.SimpleStringProperty;
-import javafx.beans.value.ChangeListener;
-import javafx.beans.value.ObservableValue;
-import javafx.event.ActionEvent;
-import javafx.event.EventHandler;
-import javafx.scene.control.Alert;
-import javafx.scene.input.KeyCode;
-import javafx.scene.input.KeyEvent;
-import javafx.scene.input.MouseEvent;
-import javafx.scene.layout.Pane;
-import javafx.scene.layout.StackPane;
-import javafx.scene.paint.Color;
-import javafx.scene.shape.Rectangle;
-import javafx.scene.text.Font;
-import javafx.scene.text.Text;
-import javafx.util.Duration;
-import lombok.Getter;
-import lombok.Setter;
-import lombok.extern.slf4j.Slf4j;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @ClassName: X2048Service
- * @Description: 2048游戏
- * @author: xufeng
- * @date: 2019/4/25 0025 23:33
- */
-
-@Getter
-@Setter
-@Slf4j
-public class X2048Service {
- private X2048Controller x2048Controller;
- public int size;
- private int[][] table;
- private int[][] tableold;
- private Point[][] tableFlight;
- private int[][] tableAfter;
- private Point[] tableAdd = new Point[2];
- private State state;
- private boolean keyPressed;
- private boolean startFlag = false;
- private KeyCode code;
- private List paneList = new ArrayList<>();
- public double width;
- public double height;
- public int margin = 0;
- public int scoreInt = 0;
- public long mLastSize = 0;
- private boolean mMousePressed;
- private final String fontName = "System";
- SimpleStringProperty score = new SimpleStringProperty("0");
- private Color[] color = new Color[]{
- Color.TRANSPARENT,
- Color.rgb(255, 236, 158),
- Color.rgb(255, 193, 0),
- Color.rgb(255, 81, 0),
- Color.rgb(255, 0, 92),
- Color.rgb(185, 0, 255),
- Color.rgb(122, 0, 255),
- Color.rgb(0, 60, 255),
- Color.rgb(0, 207, 255),
- Color.rgb(0, 255, 99),
- Color.rgb(126, 255, 0),
- Color.rgb(190, 255, 0),
- };
- public Transition m2048ColorTransition;
- private Point mPressedPoint;
- private Point mReleasedPoint;
-
- public void Init() {
- mLastSize = 4;
- x2048Controller.getTbScore().textProperty().bind(score);
- x2048Controller.getSliderSize().setOnMouseReleased(new EventHandler() {
- @Override
- public void handle(MouseEvent event) {
- long n = Math.round(x2048Controller.getSliderSize().getValue());
- x2048Controller.getSliderSize().setValue(n);
- if (n != mLastSize) {
- mLastSize = n;
- ImplInit((int) n);
- }
- x2048Controller.getPlayArea().requestFocus();
- }
- });
- x2048Controller.getSliderSize().valueProperty().addListener(new ChangeListener() {
- @Override
- public void changed(ObservableValue extends Number> observable, Number oldValue, Number newValue) {
- long o = Math.round(oldValue.doubleValue());
- long n = Math.round(newValue.doubleValue());
- }
- });
- x2048Controller.getBtnReset().focusedProperty().addListener(new ChangeListener() {
- @Override
- public void changed(ObservableValue extends Boolean> observable, Boolean oldValue, Boolean newValue) {
- if (newValue) {
- x2048Controller.getPlayArea().requestFocus();
- }
- }
- });
- }
-
- public void ImplInit(int size) {
- this.size = size;
- startFlag = true;
- scoreInt = 0;
- score.setValue("0");
- state = State.RUNNING;
- table = new int[size][size];
- tableFlight = new Point[size][size];
- tableAfter = new int[size][size];
- for (int i = 0; i < size; i++) {
- for (int j = 0; j < size; j++) {
- tableFlight[i][j] = new Point(0, 0);
- }
- }
- x2048Controller.getPlayArea().getChildren().clear();
- paneList.clear();
- width = x2048Controller.getPlayArea().getWidth();
- height = x2048Controller.getPlayArea().getHeight();
- if (width > height) {
- width = height;
- } else {
- height = width;
- }
- Rectangle bk = new Rectangle();
- if (size == 3) {
- margin = 20;
- }
- if (size == 4) {
- margin = 15;
- }
- if (size == 5) {
- margin = 10;
- }
- if (size == 6) {
- margin = 6;
- }
- bk.setWidth(width - margin / 2);
- bk.setHeight(height - margin / 2);
- bk.setFill(Color.grayRgb(195));
- bk.setArcWidth(10);
- bk.setArcHeight(10);
- x2048Controller.getPlayArea().getChildren().add(bk);
-
- for (int i = 0; i < size; i++) {
- for (int j = 0; j < size; j++) {
- StackPane pane = new StackPane();
- Rectangle r = new Rectangle();
- r.setFill(Color.grayRgb(225));
- r.setStroke(Color.TRANSPARENT);
- pane.setLayoutX(j * (width - margin) / size + margin / 2 - 1);
- pane.setLayoutY(i * (height - margin) / size + margin / 2 - 1);
- pane.setPrefWidth((width - margin) / size - margin / 2 + 2);
- pane.setPrefHeight((height - margin) / size - margin / 2 + 2);
- r.setWidth((width - margin) / size - margin / 2 + 2);
- r.setHeight((height - margin) / size - margin / 2 + 2);
- pane.getChildren().add(r);
- x2048Controller.getPlayArea().getChildren().add(pane);
- }
- }
- for (int i = 0; i < size; i++) {
- for (int j = 0; j < size; j++) {
- StackPane pane = new StackPane();
- Rectangle r = new Rectangle();
- r.setFill(color[0]);
- r.setStroke(Color.TRANSPARENT);
- r.setArcHeight(30);
- r.setArcWidth(30);
- Text text = new Text("");
- text.setFill(Color.BLACK);
- if (size == 3) {
- text.setFont(new Font(fontName, 45));
- r.setArcHeight(40);
- r.setArcWidth(40);
- }
- if (size == 4) {
- text.setFont(new Font(fontName, 40));
- r.setArcHeight(30);
- r.setArcWidth(30);
- }
- if (size == 5) {
- text.setFont(new Font(fontName, 35));
- r.setArcHeight(20);
- r.setArcWidth(20);
- }
- if (size == 6) {
- text.setFont(new Font(fontName, 25));
- r.setArcHeight(10);
- r.setArcWidth(10);
- }
-
- pane.setLayoutX(j * (width - margin) / size + margin / 2);
- pane.setLayoutY(i * (height - margin) / size + margin / 2);
- pane.setPrefWidth((width - margin) / size - margin / 2);
- pane.setPrefHeight((height - margin) / size - margin / 2);
- r.setWidth((width - margin) / size - margin / 2);
- r.setHeight((height - margin) / size - margin / 2);
- pane.getChildren().add(r);
- pane.getChildren().add(text);
- paneList.add(pane);
- x2048Controller.getPlayArea().getChildren().add(pane);
-
- }
- }
- AfterMove();
- }
-
- private void Render() {
- int add = 1;
- if (startFlag) {
- add = 2;
- startFlag = false;
- }
- ParallelTransition parallelTransition2 = new ParallelTransition();
- List list = new ArrayList<>();
- for (int i = 0; i < size; i++) {
- for (int j = 0; j < size; j++) {
- StackPane pane = (StackPane) paneList.get(i * size + j);
- if (tableFlight != null) {
- if (tableFlight[i][j].my != 0 || tableFlight[i][j].mx != 0) {
- list.add(new MoveAnime(this, pane, tableFlight[i][j].mx, tableFlight[i][j].my));
- }
- }
- if (tableAfter != null && tableAfter[i][j] != 0) {
- ScaleTransition scaleTransition = new ScaleTransition(Duration.millis(100), pane);
- scaleTransition.setFromX(1.15);
- scaleTransition.setFromY(1.15);
- scaleTransition.setToX(1);
- scaleTransition.setToY(1);
- parallelTransition2.getChildren().add(scaleTransition);
- }
-
- for (int k = 0; k < add; k++) {
- if (i == tableAdd[k].mx && j == tableAdd[k].my) {
- ScaleTransition scaleTransition = new ScaleTransition(Duration.millis(100), pane);
- scaleTransition.setFromX(0.85);
- scaleTransition.setFromY(0.85);
- scaleTransition.setToX(1);
- scaleTransition.setToY(1);
- parallelTransition2.getChildren().add(scaleTransition);
- }
- }
- }
- }
- StartMoveAnime(list);
- SequentialTransition s = new SequentialTransition();
- PauseTransition pauseTransition = new PauseTransition(Duration.millis(100));
- s.getChildren().addAll(pauseTransition, parallelTransition2);
- s.play();
- }
-
- private void StartMoveAnime(List list) {
- Animation animation = new Transition() {
- {
- setCycleDuration(Duration.millis(100));
- }
-
- @Override
- protected void interpolate(double frac) {
- for (MoveAnime item : list) {
- item.mPane.setLayoutX(item.mFromX + frac * item.mMoveX);
- item.mPane.setLayoutY(item.mFromY + frac * item.mMoveY);
- }
- }
- };
- animation.setOnFinished(new EventHandler() {
- @Override
- public void handle(ActionEvent event) {
- for (int i = 0; i < size; i++) {
- for (int j = 0; j < size; j++) {
- StackPane pane = (StackPane) paneList.get(i * size + j);
- pane.setLayoutX(j * (width - margin) / size + margin / 2);
- pane.setLayoutY(i * (height - margin) / size + margin / 2);
- Rectangle r = (Rectangle) pane.getChildren().get(0);
- Text t = (Text) pane.getChildren().get(1);
- r.setFill(color[table[i][j]]);
- if (table[i][j] != 0) {
- t.setText(String.format("%d", (int) Math.pow(2, table[i][j])));
- } else {
- t.setText("");
- }
- }
- }
- }
- });
- animation.play();
- }
-
- private void AddRandomBlock() {
- int add = 1;
- if (startFlag) {
- add = 2;
- }
- List list = CheckEmptyArea();
- if (list.size() != 0) {
- for (int j = 0; j < add; j++) {
- int i = (int) (Math.random() * list.size());
- int k = list.get(i);
- table[k / size][k % size] = 1;
- list.remove(i);
- tableAdd[j] = new Point(k / size, k % size);
-
- }
- }
- }
-
- private List CheckEmptyArea() {
- List list = new ArrayList<>();
- for (int i = 0; i < size; i++) {
- for (int j = 0; j < size; j++) {
- if (table[i][j] == 0) {
- list.add(i * size + j);
- }
- }
- }
- return list;
- }
-
- public void OnKeyPressed(KeyEvent keyEvent) {
- if (!keyPressed) {
- keyPressed = true;
- code = keyEvent.getCode();
- }
- }
-
- public void OnKeyReleased(KeyEvent event) {
- if (keyPressed) {
- keyPressed = false;
- if (event.getCode() == code) {
- ProcessCode(code);
- }
- }
- }
-
- private boolean OnChange() {
- if (state == State.RUNNING) {
- for (int i = 0; i < size; i++) {
- for (int j = 0; j < size; j++) {
- if (table[i][j] != tableold[i][j]) {
- return true;
- }
- }
- }
- }
- return false;
- }
-
- public void ProcessCode(KeyCode code) {
- tableold = new int[size][size];
- tableAfter = new int[size][size];
- tableFlight = new Point[size][size];
- for (int i = 0; i < size; i++) {
- System.arraycopy(table[i], 0, tableold[i], 0, size);
- }
- for (int i = 0; i < size; i++) {
- for (int j = 0; j < size; j++) {
- tableFlight[i][j] = new Point(0, 0);
- tableAfter[i][j] = 0;
- }
- }
- int[] l;
- switch (code) {
- case UP:
- l = new int[size];
- for (int i = 0; i < size; i++) {
- l[i] = 0;
- }
- for (int i = 1; i < size; i++) {
- for (int j = 0; j < size; j++) {
- if (table[i][j] != 0) {
- int k = i - 1;
- for (; k >= l[j]; k--) {
- if (table[k + 1][j] == table[k][j]) {
- table[k + 1][j] = 0;
- table[k][j]++;
- l[j] = k + 1;
- tableFlight[i][j].my--;
- tableAfter[k][j] = 1;
- } else if (table[k + 1][j] != 0 && table[k][j] == 0) {
- table[k][j] = table[k + 1][j];
- table[k + 1][j] = 0;
- tableFlight[i][j].my--;
- }
- }
-
- }
- }
- }
- if (OnChange()) {
- AfterMove();
- }
- break;
- case DOWN:
- l = new int[size];
- for (int i = 0; i < size; i++) {
- l[i] = size - 1;
- }
- for (int i = size - 2; i >= 0; i--) {
- for (int j = 0; j < size; j++) {
- if (table[i][j] != 0) {
- int k = i + 1;
- for (; k <= l[j]; k++) {
- if (table[k - 1][j] == table[k][j]) {
- table[k - 1][j] = 0;
- table[k][j]++;
- l[j] = k - 1;
- tableFlight[i][j].my++;
- tableAfter[k][j] = 1;
- } else if (table[k - 1][j] != 0 && table[k][j] == 0) {
- table[k][j] = table[k - 1][j];
- table[k - 1][j] = 0;
- tableFlight[i][j].my++;
- }
- }
- }
- }
- }
- if (OnChange()) {
- AfterMove();
- }
- break;
- case LEFT:
- l = new int[size];
- for (int i = 0; i < size; i++) {
- l[i] = 0;
- }
- for (int j = 1; j < size; j++) {
- for (int i = 0; i < size; i++) {
- if (table[i][j] != 0) {
- int k = j - 1;
- for (; k >= l[i]; k--) {
- if (table[i][k] == table[i][k + 1]) {
- table[i][k + 1] = 0;
- table[i][k]++;
- l[i] = k + 1;
- tableFlight[i][j].mx--;
- tableAfter[i][k] = 1;
- } else if (table[i][k + 1] != 0 && table[i][k] == 0) {
- table[i][k] = table[i][k + 1];
- table[i][k + 1] = 0;
- tableFlight[i][j].mx--;
- }
- }
-
- }
- }
- }
- if (OnChange()) {
- AfterMove();
- }
- break;
- case RIGHT:
- l = new int[size];
- for (int i = 0; i < size; i++) {
- l[i] = size - 1;
- }
- for (int j = size - 2; j >= 0; j--) {
- for (int i = 0; i < size; i++) {
- if (table[i][j] != 0) {
- int k = j + 1;
- for (; k <= l[i]; k++) {
- if (table[i][k] == table[i][k - 1]) {
- table[i][k - 1] = 0;
- table[i][k]++;
- l[i] = k - 1;
- tableFlight[i][j].mx++;
- tableAfter[i][k] = 1;
- } else if (table[i][k - 1] != 0 && table[i][k] == 0) {
- table[i][k] = table[i][k - 1];
- table[i][k - 1] = 0;
- tableFlight[i][j].mx++;
- }
- }
-
- }
- }
- }
- if (OnChange()) {
- AfterMove();
- }
- break;
- }
-
- }
-
- private void AfterMove() {
- AddRandomBlock();
- AddScore();
- if (CheckLose()) {
- state = State.GAMEOVER;
- }
- if (Check2048()) {
- state = State.GAMESUCCESS;
- }
-
- Render();
- if (state == State.GAMEOVER) {
- Alert alert = new Alert(Alert.AlertType.INFORMATION);
- alert.setTitle("抱歉");
- alert.setHeaderText("游戏结束");
- alert.setContentText("xwintop,欢迎支持!\n请点击按钮重置游戏!");
- alert.show();
- } else if (state == State.GAMESUCCESS) {
- Alert alert = new Alert(Alert.AlertType.INFORMATION);
- alert.setTitle("666");
- alert.setHeaderText("大吉大利,晚上吃鸡");
- alert.setContentText("你赢了?--xwintop。\n请点击按钮重置游戏!");
- alert.show();
- }
- }
-
- private boolean Check2048() {
- for (int i = 0; i < size; i++) {
- for (int j = 0; j < size; j++) {
- if (table[i][j] == 11) {
- StackPane pane = (StackPane) paneList.get(i * size + j);
- Rectangle rectangle = (Rectangle) pane.getChildren().get(0);
- Timeline timeline = new Timeline();
- KeyValue[] values = new KeyValue[]{
- new KeyValue(rectangle.fillProperty(), Color.rgb(255, 0, 0)),
- new KeyValue(rectangle.fillProperty(), Color.rgb(255, 125, 0)),
- new KeyValue(rectangle.fillProperty(), Color.rgb(255, 255, 0)),
- new KeyValue(rectangle.fillProperty(), Color.rgb(0, 255, 0)),
- new KeyValue(rectangle.fillProperty(), Color.rgb(0, 255, 255)),
- new KeyValue(rectangle.fillProperty(), Color.rgb(0, 0, 255)),
- new KeyValue(rectangle.fillProperty(), Color.rgb(255, 0, 255)),
- new KeyValue(rectangle.fillProperty(), Color.rgb(255, 0, 0))
- };
- KeyFrame[] frames = new KeyFrame[]{
- new KeyFrame(Duration.millis(0), values[0]),
- new KeyFrame(Duration.millis(200), values[1]),
- new KeyFrame(Duration.millis(400), values[2]),
- new KeyFrame(Duration.millis(600), values[3]),
- new KeyFrame(Duration.millis(800), values[4]),
- new KeyFrame(Duration.millis(1000), values[5]),
- new KeyFrame(Duration.millis(1200), values[6]),
- new KeyFrame(Duration.millis(1400), values[7]),
- };
- timeline.getKeyFrames().addAll(frames);
- timeline.setCycleCount(Timeline.INDEFINITE);
- return true;
- }
- }
- }
- return false;
- }
-
- private void AddScore() {
- int temp = 0;
- for (int i = 0; i < size; i++) {
- for (int j = 0; j < size; j++) {
- if (tableAfter[i][j] != 0) {
- temp += (int) (Math.pow(2, table[i][j]));
- }
- }
- }
- scoreInt += temp;
- score.setValue(String.format("%d", scoreInt));
-
- }
-
- private boolean CheckLose() {
- int s = CheckEmptyArea().size();
- if (s == 0) {
- if (table[0][0] != 0) {
- if (table[0][0] == table[0][1] || table[0][0] == table[1][0]) {
- return false;
- }
- }
- if (table[0][size - 1] != 0) {
- if (table[0][size - 1] == table[0][size - 2] || table[0][size - 1] == table[1][size - 1]) {
- return false;
- }
- }
- if (table[size - 1][size - 1] != 0) {
- if (table[size - 1][size - 1] == table[size - 1][size - 2] || table[size - 1][size - 1] == table[size - 2][size - 1]) {
- return false;
- }
- }
- if (table[size - 1][0] != 0) {
- if (table[size - 1][0] == table[size - 2][0] || table[size - 1][0] == table[size - 1][1]) {
- return false;
- }
- }
- for (int i = 1; i < size - 1; i++) {
- if (table[i][0] != 0) {
- if (table[i][0] == table[i - 1][0]
- || table[i][0] == table[i + 1][0]
- || table[i][0] == table[i][1]) {
- return false;
- }
- }
- if (table[i][size - 1] != 0) {
- if (table[i][size - 1] == table[i - 1][size - 1]
- || table[i][size - 1] == table[i + 1][size - 1]
- || table[i][size - 1] == table[i][size - 2]) {
- return false;
- }
- }
- if (table[0][i] != 0) {
- if (table[0][i] == table[0][i - 1]
- || table[0][i] == table[0][i + 1]
- || table[0][i] == table[1][i]) {
- return false;
- }
- }
- if (table[size - 1][i] != 0) {
- if (table[size - 1][i] == table[size - 1][i - 1]
- || table[size - 1][i] == table[size - 1][i + 1]
- || table[size - 1][i] == table[size - 2][i]) {
- return false;
- }
- }
- }
- for (int i = 1; i < size - 1; i++) {
- for (int j = 1; j < size - 1; j++) {
- if (table[i][j] != 0) {
- if (table[i][j] == table[i - 1][j]
- || table[i][j] == table[i + 1][j]
- || table[i][j] == table[i][j + 1]
- || table[i][j] == table[i][j - 1]) {
- return false;
- }
- }
- }
- }
- return true;
- }
- return false;
- }
-
- public void MouseManipulation() {
- if (Math.abs(mPressedPoint.mx - mReleasedPoint.mx) < 50) {
- if (mReleasedPoint.my - mPressedPoint.my > 50) {
- ProcessCode(KeyCode.DOWN);
- } else if (mReleasedPoint.my - mPressedPoint.my < -50) {
- ProcessCode(KeyCode.UP);
- }
- }
- if (Math.abs(mPressedPoint.my - mReleasedPoint.my) < 50) {
- if (mReleasedPoint.mx - mPressedPoint.mx > 50) {
- ProcessCode(KeyCode.RIGHT);
- } else if (mReleasedPoint.mx - mPressedPoint.mx < -50) {
- ProcessCode(KeyCode.LEFT);
- }
- }
- }
-
- public X2048Service(X2048Controller x2048Controller) {
- this.x2048Controller = x2048Controller;
- }
-
- public static class Point {
- int mx;
- int my;
-
- public Point(int x, int y) {
- mx = x;
- my = y;
- }
- }
-
-}
-
-enum State {
- RUNNING,
- GAMEOVER,
- GAMESUCCESS,
-}
-
-class MoveAnime {
- StackPane mPane;
- double mFromX;
- double mFromY;
- double mMoveX;
- double mMoveY;
-
- MoveAnime(X2048Service ctrl, StackPane pane, int dx, int dy) {
- mPane = pane;
- mFromX = pane.getLayoutX();
- mFromY = pane.getLayoutY();
- mMoveX = ctrl.width / ctrl.size * dx;
- mMoveY = ctrl.height / ctrl.size * dy;
- }
-}
-
diff --git a/games/x-X2048/src/main/java/com/xwintop/xJavaFxTool/view/games/X2048View.java b/games/x-X2048/src/main/java/com/xwintop/xJavaFxTool/view/games/X2048View.java
deleted file mode 100644
index fc0be23..0000000
--- a/games/x-X2048/src/main/java/com/xwintop/xJavaFxTool/view/games/X2048View.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.xwintop.xJavaFxTool.view.games;
-
-import lombok.Getter;
-import lombok.Setter;
-import javafx.fxml.Initializable;
-import javafx.fxml.FXML;
-import javafx.geometry.Insets;
-import javafx.scene.control.Button;
-import javafx.scene.control.Label;
-import javafx.scene.control.Slider;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.Pane;
-import javafx.scene.layout.VBox;
-import javafx.scene.text.Font;
-
-@Getter
-@Setter
-public abstract class X2048View implements Initializable {
- @FXML
- protected Label tbScore;
- @FXML
- protected Slider sliderSize;
- @FXML
- protected Button btnReset;
- @FXML
- protected Pane playArea;
-}
\ No newline at end of file
diff --git a/games/x-X2048/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/games/X2048.fxml b/games/x-X2048/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/games/X2048.fxml
deleted file mode 100644
index f59a353..0000000
--- a/games/x-X2048/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/games/X2048.fxml
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/games/x-X2048/src/main/resources/config/toolFxmlLoaderConfiguration.xml b/games/x-X2048/src/main/resources/config/toolFxmlLoaderConfiguration.xml
deleted file mode 100644
index 35b1b11..0000000
--- a/games/x-X2048/src/main/resources/config/toolFxmlLoaderConfiguration.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
- /com/xwintop/xJavaFxTool/fxmlView/games/X2048.fxml
- locale.X2048
-
- Title
-
-
- p-games
- Node
-
-
\ No newline at end of file
diff --git a/games/x-X2048/src/main/resources/locale/X2048.properties b/games/x-X2048/src/main/resources/locale/X2048.properties
deleted file mode 100644
index 0f20155..0000000
--- a/games/x-X2048/src/main/resources/locale/X2048.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-# Dorian.properties\u662F\u9ED8\u8BA4\u7684"Dorian"\u8D44\u6E90\u675F\u6587\u4EF6\u3002
-# \u4F5C\u4E3A\u4E2D\u56FD\u4EBA,\u6211\u7528\u81EA\u5DF1\u7684\u5730\u533A\u4F5C\u4E3A\u9ED8\u8BA4
-Title=2048
\ No newline at end of file
diff --git a/games/x-X2048/src/main/resources/locale/X2048_en_US.properties b/games/x-X2048/src/main/resources/locale/X2048_en_US.properties
deleted file mode 100644
index 0ba7d88..0000000
--- a/games/x-X2048/src/main/resources/locale/X2048_en_US.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-# \u6587\u4EF6Dorian_en_US.properties\uFF0C\u662F\u7F8E\u56FD\u5730\u533A\u7684\u8D44\u6E90\u675F
-# \u5B83\u8986\u76D6\u4E86\u9ED8\u8BA4\u8D44\u6E90\u675F
-Title=2048
\ No newline at end of file
--
Gitee
From c482cdb678387062c7b1fa46361c0cefe452f757 Mon Sep 17 00:00:00 2001
From: "XUFENG-PC\\xufeng" <1277032935@qq.com>
Date: Tue, 11 Aug 2020 09:41:09 +0800
Subject: [PATCH 16/17] =?UTF-8?q?=E6=9B=B4=E6=96=B0Readme=E8=AF=B4?=
=?UTF-8?q?=E6=98=8E?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
debugTools/x-FtpClientTool/README.md | 1 +
debugTools/x-SocketTool/README.md | 2 +-
debugTools/x-SocketTool/pom.xml | 2 +-
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/debugTools/x-FtpClientTool/README.md b/debugTools/x-FtpClientTool/README.md
index 56a4e36..b07638c 100644
--- a/debugTools/x-FtpClientTool/README.md
+++ b/debugTools/x-FtpClientTool/README.md
@@ -1,6 +1,7 @@
FtpClientTool
Ftp(s)/Sftp客户端调试工具(批量上传、下载、删除文件及文件夹)(implicit/explicit SSL/TLS)(使用jsch、commons-io等工具)
+- V0.0.2
- 20200804
1. 添加commons-net包引用
2. 添加ftp连接时passive参数
\ No newline at end of file
diff --git a/debugTools/x-SocketTool/README.md b/debugTools/x-SocketTool/README.md
index 3fedbb3..60f8a95 100644
--- a/debugTools/x-SocketTool/README.md
+++ b/debugTools/x-SocketTool/README.md
@@ -1,7 +1,7 @@
SocketTool
Socket调试工具(使用[Apache Mina](http://mina.apache.org)实现Tcp、Udp服务端和Client端)
-
+- V0.0.2
- 20200802
添加服务端自动回复功能
- 20200803
diff --git a/debugTools/x-SocketTool/pom.xml b/debugTools/x-SocketTool/pom.xml
index 2f38bdf..d5c7011 100644
--- a/debugTools/x-SocketTool/pom.xml
+++ b/debugTools/x-SocketTool/pom.xml
@@ -4,7 +4,7 @@
com.xwintop
x-SocketTool
- 0.0.1
+ 0.0.2
jar
x-SocketTool
--
Gitee
From f84ba0585d57468217f6e546f9e3fc95ec5c3b9f Mon Sep 17 00:00:00 2001
From: "XUFENG-PC\\xufeng" <1277032935@qq.com>
Date: Tue, 11 Aug 2020 09:47:43 +0800
Subject: [PATCH 17/17] =?UTF-8?q?=E6=9B=B4=E6=96=B0Readme=E8=AF=B4?=
=?UTF-8?q?=E6=98=8E?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 3 ---
1 file changed, 3 deletions(-)
diff --git a/README.md b/README.md
index b66e018..b54bdb8 100644
--- a/README.md
+++ b/README.md
@@ -75,7 +75,6 @@ controllerType = "Node";// 内容类型
33. JsonConvertTool:Json转换工具(目前支持Json转Xml、Json转Java实体类、Json转C#实体类、Json转Excel、Json转Yaml、Properties转Yaml、Yaml转Properties)(使用[fastjson](https://github.com/alibaba/fastjson)、[snakeyaml](https://bitbucket.org/asomov/snakeyaml)、[dom4j](https://dom4j.github.io)等工具)
34. WechatJumpGameTool:微信跳一跳助手
35. TextToSpeechTool:语音转换工具(调用[百度语音](https://ai.baidu.com/tech/speech/tts)转换api)
-36. 2048:小游戏2048
37. SocketTool:Socket调试工具(使用[Apache Mina](http://mina.apache.org)实现Tcp、Udp服务端和Client端)
38. ImageAnalysisTool:图片解析工具(1、.atlas文件反解析2、图片快速拆分工具)
39. DecompilerWxApkgTool:微信小程序反编译工具(一键反编译微信小程序包)
@@ -92,11 +91,9 @@ controllerType = "Node";// 内容类型
50. FileSearchTool:文件搜索工具(使用[lucene](https://lucene.apache.org/)搜索引擎)
51. Mp3ConvertTool:Mp3转换工具(目前支持网易云音乐.ncm、QQ音乐.qmc转换为mp3格式)(使用[jaudiotagger](http://www.jthink.net/jaudiotagger/)工具)
52. SealBuilderTool:印章生成工具
-53. BullsAndCowsGame:猜数字小游戏
54. FileUnicodeTransformationTool:文件编码转换工具
55. FileCompressTool:文件解压缩工具(目前支持ar、zip、tar、jar、cpio、7z、gz、bzip2、xz、lzma、pack200、deflate、snappy-framed、lz4-block、lz4-framed、zstd等格式解压缩)
56. IdiomDataTool:成语字典工具(使用[h2](http://www.h2database.com)数据库存储数据字典)
-57. Sudoku:数独游戏
#### 项目结构
--
Gitee