Skip to content
This repository has been archived by the owner on Jul 2, 2023. It is now read-only.

Commit

Permalink
Merge pull request #2 from LongCTygo/beta-1.1.0
Browse files Browse the repository at this point in the history
Make 1.1.0 the main release
  • Loading branch information
LongCTygo authored Mar 13, 2023
2 parents 2e4b72b + 2e461fe commit b00eaf8
Show file tree
Hide file tree
Showing 13 changed files with 320 additions and 120 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ bin/
### Mac OS ###
.DS_Store
/solutions/
/src/test/
/src/net/longct/pistonsolver/test/
124 changes: 124 additions & 0 deletions .idea/uiDesigner.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions PistonPuzzleSolver.iml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/src/net/longct/pistonsolver/test" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="google.code.gson" level="project" />
</component>
</module>
41 changes: 22 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

# Sands Of Time's Piston Puzzle Solver
A java program that can solve MCC's Sands Of Time's Piston Puzzle.
What is the puzzle? Check out this [detailed document](https://docs.google.com/document/d/1ZbfKo57hn-H5eb_VkiYvJ5Ib-VdNfRtCjPyNy1HkyK8) made by edihau.
Expand All @@ -7,41 +6,42 @@ What is the puzzle? Check out this [detailed document](https://docs.google.com/d
Clone this project into your IDE of choice (I use IntelliJ for this project), then do what you want with it.
Alternatively, you can download the .jar file in the releases page. Once downloaded:

- Open your console on your OS, then change your directory to the folder containing the downloaded jar.
- Run `java -jar PistonPuzzleSolver.jar (args)`
- For the arguments, supply an integer seed (range from 0 to 2^23 - 1, or 8388607), or multiple of them. The program will go through all the provided seeds and either solve them or provide an Exception and skip it.
- Read below to see how seeds work.
- Alternatively, have your first argument be '-loop', and the program will instead wait for you to supply the seeds whilst running. It will end once you give it an empty input.
- Open your console on your OS, then change your directory to the folder containing the downloaded jar.
- Run `java -jar PistonPuzzleSolver.jar (args)`
- For the arguments, supply an integer seed (range from 0 to 2^23 - 1, or 8388607), or multiple of them. The program will go through all of the provided seeds and either solve them or provide an Exception and skip it.
- Read below to see how seeds work.
- Alternatively, have your first argument be '-loop', and the program will instead wait for you to supply the seeds whilst running. It will end once you give it an empty input.

**Common Exceptions:**
**Common Exceptions:**

- java.lang.NumberFormatException: if you provided a seed that is not an integer. The code provides a way to use a 6-character hexadecimal seed for this, but it is not supported in the .jar file.
- java.lang.IllegalArgumentException: if you provided a seed that is out of the range given above.
- java.lang.RuntimeException: Should usually come with a message that said that you did not provide an argument. Happens when you run the jar file without any arguments.
- java.lang.NumberFormatException: if you provided a seed that is not an integer.
- java.lang.IllegalArgumentException: if you provided a seed that is out of the range given above. This should not happen in the latest release, as the program now accept full 32-bit integer as a valid seed. The program will still only use the 23 bits it needs.
- java.lang.RuntimeException: Should usually come with a message that said that you did not provide an argument. Happens when you run the jar file without any arguments.
## What does the program print out after solving the puzzle?
- If a valid solution is found, the program will print out an in depth step-by-step instruction on how to solve it, with what move to do, and what the board looks like after that move.
- If none is found, the program will print out the provided board, with the message "No solutions"
- The '@' represents the player, 'o' represents a box, 'x' represents an empty goal, or it will be '#' instead if something is occupying that spot. (Either a box, or the player, the latter means it is solved).
- Additionally, its runtime in miliseconds is also provided.
- Additionally, its runtime in milliseconds is also provided.
## How does the seed system work?
**WARNING: JANKY EXPLAINATIONS AND BROKEN ENGLISH DOWN BELOW**
#### **WARNING: INCOMPLETE EXPLANATIONS AND BROKEN ENGLISH DOWN BELOW**

The seed is a 24-bit unsigned integer (0 - 2^23 - 1). Out of the 24 bits, only 23 are used, the first (left-most) bit is ignored. The seed can be either stored as just an integer, or a 6-characters hexadecimal seed.
**For example:**

03BB34 in hex

244532 in decimal

In binary they should look like this
The seed 244532 in binary is:

0000 0011 1011 1011 0011 0100

Let's go through all of the bits one by one. Remember, the first bit is ignored.
Let's go through all the bits one by one. Remember, the first bit is ignored.

0**00**0 0011 1011 1011 0011 0100 **Bit 2 & 3**

The 2nd and 3rd left-most bit are used to store the *rotation value* of the board. If the value of these 2 bits are both 0, then the position of the player is always inside the III quarter of the board (the bottom-left quarter). These 2 bits represent how many time the board should be rotated *counter-clockwise* to reach the position where the player is in that quarter.
The 2nd and 3rd left-most bit are used to store the *rotation value* of the board. If the value of these 2 bits are both 0, then the position of the player is always inside the III quarter of the board (the bottom-left quarter). These 2 bits represent how many times the board should be rotated *counter-clockwise* to reach the position where the player is in that quarter.
When generating the board, the board will generate a board with the player in the bottom-left quarter, then rotate it clockwise that many times to get the board of that seed.

000**0 0**011 1011 1011 0011 0100 **Bit 4 & 5**
Expand All @@ -54,12 +54,12 @@ These two bits represent the position of the player. As the player is always lo
0000 0**011 1011 1011 0011** 0100 **Bit 6 - 20**

These 15 bits represent the remaining 15 slots on the board. A 0 represents that that slot is empty, while a 1 represents that a *box* is inside that slot.
Similar to the player, it starts at the top left corner of the **board**, going to the right of the row, then to the next row. It skips the slot the player is in.
Similar to the player, it starts in the top left corner of the **board**, going to the right of the row, then to the next row. It skips the slot the player is in.


0000 0011 1011 1011 0011 **0100** **Bit 21 - 24**

The last 4 bits are the location of the goal. It starts at the top left corner of the **board**, going to the right of the row, then to the next row, like the two above.
The last 4 bits are the location of the goal. It starts in the top left corner of the **board**, going to the right of the row, then to the next row, like the two above.

As an example, this is the board with the seed 100000. Try to convert the seed into a board.
| x | . | o | o |
Expand All @@ -68,13 +68,16 @@ As an example, this is the board with the seed 100000. Try to convert the seed i
| **@** | **o** | **o** | **.** |
| **o** | **.** | **o** | **.** |
## The Algorithm (WIP)
## Additional Infos (WIP)
The algorithm aims to solve the puzzle with a breadth-first search approach. Starting from the root, it generates all possible board states, then decide whether the board is 'on the right track' and add it to the queue, or else it will ignore that board.

From a board, it will try out all 16 different moves, ignoring moves that does not advance the board state. From there, it determines if a move is advantageous or not, and continue from there.
## Additional Info (WIP)
## To-do List (WIP)
- Make a mod that does all of these. It can go with a map for practicing purposes. Ideally just a map, but I don't think mcfunctions alone can achieve randomly generated levels (that are solvable, at least). One way to achieve this is likely to load all levels template into that map, then use /clone and some random scoreboard functions to pick one, but there are A LOT of puzzles, and I'm not sure how viable that is.
- Alternatively, a web-based game/app for practicing could be achieved.
- A simple board-to-seed converter GUI for easier use.
- Improving the algorithms. And there are a lot to be improved.
## Note
This program is designed as a way to study and do research. Through the use of this, you can learn how to tackle a puzzle like this as a human, find potential strategy and common patterns. This is **NOT** a program made to be used as a mean of cheating inside an enviroment like the Minecraft Championship, or to be expanded into programs that enable such acts. Please do not use this for those purposes.
This program is designed as a way to study and do research. Through the use of this, you can learn how to tackle a puzzle like this as a human, find potential strategy and common patterns. This is **NOT** a program made to be used as a mean of cheating inside an environment like the Minecraft Championship, or to be expanded into programs that enable such acts. Please do not use this for those purposes.
## License
Read [LICENSE](https://github.com/LongCTygo/sot-piston-puzzle/blob/master/LICENSE).
Read [LICENSE](https://github.com/LongCTygo/sot-piston-puzzle/blob/master/LICENSE).
2 changes: 1 addition & 1 deletion src/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Manifest-Version: 1.0
Main-Class: Main
Main-Class: net.longct.pistonsolver.Main

19 changes: 14 additions & 5 deletions src/Main.java → src/net/longct/pistonsolver/Main.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package net.longct.pistonsolver;

import puzzle.Board;
import solver.Node;
import solver.SolutionTree;
import net.longct.pistonsolver.puzzle.Board;
import net.longct.pistonsolver.solver.Node;
import net.longct.pistonsolver.solver.SolutionTree;

import java.util.Scanner;

Expand Down Expand Up @@ -38,8 +39,16 @@ public static void solve(String seed){
System.out.printf("------------------- Seed '%s' -------------------\n", seed);
try {
int s = Integer.parseInt(seed);
SolutionTree st = new SolutionTree(new Node(new Board(s)));
st.solveBFS(20,10000000,true,true);
Board board = new Board(s);
SolutionTree st = new SolutionTree(new Node(board));
// st.solveBFS(20,10000000,true,true);
Node node = st.solveBFS(20, 10000000, true);
if (node != null){
node.printSolutions();
} else {
System.out.println(board);
System.out.println("No solutions");
}
System.out.println();
} catch (Exception ex){
System.err.printf("Exception Caught for argument %s: %s\n",seed, ex.getClass().getName());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package iterate;
package net.longct.pistonsolver.iterate;

import puzzle.Board;
import solver.Node;
import solver.SolutionTree;
import net.longct.pistonsolver.puzzle.Board;
import net.longct.pistonsolver.solver.Node;
import net.longct.pistonsolver.solver.SolutionTree;

import java.io.BufferedWriter;
import java.io.File;
Expand Down
Loading

0 comments on commit b00eaf8

Please sign in to comment.