diff options
author | syeyoung <42869671+cyoung06@users.noreply.github.com> | 2020-11-29 22:27:11 +0900 |
---|---|---|
committer | syeyoung <42869671+cyoung06@users.noreply.github.com> | 2020-11-29 22:27:11 +0900 |
commit | 7150a38e9562395afefafa2adb4c7152a09a9928 (patch) | |
tree | 59a07472b8b8361148faa55998b43cbb21bd8293 /src/main/java/kr/syeyoung/dungeonsguide/roomprocessor | |
parent | 8cd3bed0597cd6c452371630d93f4d58b0602bd3 (diff) | |
download | Skyblock-Dungeons-Guide-7150a38e9562395afefafa2adb4c7152a09a9928.tar.gz Skyblock-Dungeons-Guide-7150a38e9562395afefafa2adb4c7152a09a9928.tar.bz2 Skyblock-Dungeons-Guide-7150a38e9562395afefafa2adb4c7152a09a9928.zip |
box puzzle
Diffstat (limited to 'src/main/java/kr/syeyoung/dungeonsguide/roomprocessor')
10 files changed, 269 insertions, 14 deletions
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/ProcessorFactory.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/ProcessorFactory.java index a73e542b..df8f6cbc 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/ProcessorFactory.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/ProcessorFactory.java @@ -34,8 +34,7 @@ public class ProcessorFactory { registerRoomProcessor("puzzle_silverfish", new RoomProcessorIcePath.Generator()); // done - - registerRoomProcessor("puzzle_icefill", new RoomProcessorIcePath2.Generator()); + registerRoomProcessor("puzzle_box", new RoomProcessorBoxSolver.Generator()); } } diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorBoxSolver.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorBoxSolver.java new file mode 100644 index 00000000..7287c8b2 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorBoxSolver.java @@ -0,0 +1,230 @@ +package kr.syeyoung.dungeonsguide.roomprocessor; + +import kr.syeyoung.dungeonsguide.dungeon.data.OffsetPointSet; +import kr.syeyoung.dungeonsguide.dungeon.roomfinder.DungeonRoom; +import kr.syeyoung.dungeonsguide.utils.RenderUtils; +import lombok.AllArgsConstructor; +import lombok.Data; +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.init.Blocks; +import net.minecraft.util.BlockPos; +import net.minecraft.world.World; + +import java.awt.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +public class RoomProcessorBoxSolver extends GeneralRoomProcessor { + + + private BlockPos[][] poses = new BlockPos[6][7]; + private boolean bugged= true; + public RoomProcessorBoxSolver(DungeonRoom dungeonRoom) { + super(dungeonRoom); + + OffsetPointSet ops = (OffsetPointSet) dungeonRoom.getDungeonRoomInfo().getProperties().get("board"); + try { + if (ops != null) { + for (int y = 0; y < 6; y++) { + for (int x = 0; x < 7; x++) { + poses[y][x] = ops.getOffsetPointList().get(y * 7 + x).getBlockPos(dungeonRoom); + } + } + bugged = false; + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private byte[][] buildCurrentState() { + World w = getDungeonRoom().getContext().getWorld(); + byte[][] board = new byte[poses.length][poses[0].length]; + for (int y = 0; y < poses.length; y++) { + for (int x = 0; x < poses[0].length; x++) { + BlockPos pos = poses[y][x]; + Block b = w.getChunkFromBlockCoords(pos).getBlock(pos); + if (b == Blocks.air) + board[y][x] = 0; + else + board[y][x] = 1; + } + } + return board; + } + + private byte[][] lastboard; + + private static final List<Point> directions = Arrays.asList(new Point(0,-1), new Point(-1,0), new Point(1,0), new Point(0,1)); + private LinkedList<Action> solve(byte[][] board, int playerX, int playerY) { // result:: playerY == 0 + if (playerY == 0) { + LinkedList<Action> moves = new LinkedList<Action>(); + return moves; + } + for (Point dir:directions) { + int resX = playerX + dir.x; + int resY = playerY + dir.y; + if (resX < 0 || resY < 0 || resX >= board[0].length|| resY>=board.length || board[resY][resX] == 2) continue; + + byte[][] copied = new byte[board.length][]; + for (int y = 0; y < copied.length; y++) + copied[y] = board[y].clone(); + + LinkedList<Action> solved; + boolean pushed = false; + copied[playerY][playerX] = 2; + if (board[resY][resX] == 1) { + if (!push(copied, resX, resY, dir.x, dir.y)) { + continue; + } + pushed = true; + solved = solve(copied, playerX, playerY); + } else { + solved = solve(copied, resX, resY); + } + if (solved != null) { + if (pushed) { + solved.addFirst(new Push(dir.x, dir.y)); + } else { + solved.addFirst(new Move(resX, resY)); + } + return solved; + } + } + return null; + } + + public static interface Action { } + @Data + @AllArgsConstructor + public static class Move implements Action { + private int x; + private int y; + } + @Data + @AllArgsConstructor + public static class Push implements Action { + private int dx; + private int dy; + } + + private boolean push(byte[][] board, int x,int y,int dx,int dy) { + if (board[y][x] != 1) return false; + int resultingX= x + dx; + int resultingY = y +dy; + if (resultingX < 0 || resultingY < 0 || resultingX >= board[0].length || resultingY >= board.length) return false; + if (board[resultingY][resultingX] != 0) return false; + + board[resultingY][resultingX] = 1; + board[y][x] = 0; + return true; + } + + @Override + public void tick() { + super.tick(); + if (bugged) return; +// boolean calculate = lastboard == null; + byte[][] currboard = buildCurrentState(); +// if (!calculate) { +// label: +// for (int y = 0; y < 6; y ++) { +// for (int x = 0; x < 7; x++) +// if (currboard[y][x] != lastboard[y][x]) { +// calculate = true; +// break label; +// } +// } +// } +// + if (Minecraft.getMinecraft().thePlayer.getPosition().getY() < 68) { + Point playerPos = getPlayerPos(); + try { + solution = solve(currboard, playerPos.x, playerPos.y); + if (solution != null) + solution.addFirst(new Move(playerPos.x, playerPos.y)); + } catch (Error e) { + e.printStackTrace(); + } + } else { + for (int i = 0; i < 7; i++) { + if (currboard[5][i] == 0) { + try { + solution = solve(currboard, i, 5); + if (solution != null) { + solution.addFirst(new Move(i, 5)); + break; + } + } catch (Error e) { + e.printStackTrace(); + } + } + } + } + } + + private LinkedList<Action> solution; + + public Point getPlayerPos() { + BlockPos playerPos = Minecraft.getMinecraft().thePlayer.getPosition(); + int minDir = Integer.MAX_VALUE; + Point pt = null; + for (int y = 0; y < poses.length; y++) { + for (int x = 0; x < poses[0].length; x++) { + int dir = (int) poses[y][x].distanceSq(playerPos); + if (dir < minDir) { + minDir = dir; + pt = new Point(x,y); + } + } + } + return pt; + } + + @Override + public void drawWorld(float partialTicks) { + super.drawWorld(partialTicks); + if (bugged) return; + if (solution == null) return; + try { + List<BlockPos> line = new ArrayList<BlockPos>(); + List<BlockPos> push = new ArrayList<BlockPos>(); + BlockPos lastLoc2 = null; + Move lastLoc = null; + for (Action action : solution) { + if (action instanceof Move) { + BlockPos pos = poses[((Move) action).getY()][((Move) action).getX()]; + line.add(pos.add(0, -1, 0)); + lastLoc = (Move) action; + lastLoc2 = pos; + } else if (action instanceof Push) { + int y = lastLoc.getY() + ((Push) action).getDy(); + int x = lastLoc.getX() + ((Push) action).getDx(); + + BlockPos vec = poses[y][x].subtract(lastLoc2); + if (vec.getZ() > 1 || vec.getZ() < -1) vec = new BlockPos(vec.getX(),0,vec.getZ() >1 ? 1:-1); + if (vec.getX() > 1 || vec.getX() < -1) vec = new BlockPos(vec.getX() >1 ? 1:-1,0,vec.getZ()); + push.add(lastLoc2.add(vec)); + } + } + boolean depth = Minecraft.getMinecraft().thePlayer.getPosition().getY() < 68; + + RenderUtils.drawLines(line, new Color(0, 255, 0, 255), partialTicks, depth); + for (BlockPos b2:push) + RenderUtils.highlightBlock(b2, new Color(0, 255, 0, 50), partialTicks, depth); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static class Generator implements RoomProcessorGenerator<RoomProcessorBoxSolver> { + @Override + public RoomProcessorBoxSolver createNew(DungeonRoom dungeonRoom) { + RoomProcessorBoxSolver defaultRoomProcessor = new RoomProcessorBoxSolver(dungeonRoom); + return defaultRoomProcessor; + } + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorCreeperSolver.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorCreeperSolver.java index 0b49fcf2..93f5e4e8 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorCreeperSolver.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorCreeperSolver.java @@ -108,7 +108,7 @@ public class RoomProcessorCreeperSolver extends GeneralRoomProcessor { continue; } RenderUtils.drawLine(new Vec3(poset[0].getX() +0.5, poset[0].getY() +0.5, poset[0].getZ()+0.5), - new Vec3(poset[1].getX() +0.5, poset[1].getY() +0.5, poset[1].getZ()+0.5), new Color(index * 10,255,255,255), partialTicks); + new Vec3(poset[1].getX() +0.5, poset[1].getY() +0.5, poset[1].getZ()+0.5), new Color(index * 10,255,255,255), partialTicks, true); //Re // RenderUtils.highlightBlock(poset[0], new Color(0,255,255,50), partialTicks); // RenderUtils.highlightBlock(poset[1], new Color(255,0,0,50), partialTicks); diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorIcePath.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorIcePath.java index d2962b31..efb0f98c 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorIcePath.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorIcePath.java @@ -110,7 +110,7 @@ public class RoomProcessorIcePath extends GeneralRoomProcessor { public void drawWorld(float partialTicks) { super.drawWorld(partialTicks); if (!err) - RenderUtils.drawLines(solution, new Color(0,255,0, 255), partialTicks); + RenderUtils.drawLines(solution, new Color(0,255,0, 255), partialTicks, false); } public Point getPointOfSilverFishOnMap(BlockPos blockPos) { diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorIcePath2.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorIcePath2.java index 6e0553a7..bfaae64b 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorIcePath2.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorIcePath2.java @@ -73,7 +73,7 @@ public class RoomProcessorIcePath2 extends GeneralRoomProcessor { @Override public void drawWorld(float partialTicks) { for (List<BlockPos> solution:this.solution) - RenderUtils.drawLines(solution, new Color(0,255,0, 255), partialTicks); + RenderUtils.drawLines(solution, new Color(0,255,0, 255), partialTicks, false); } public static class Generator implements RoomProcessorGenerator<RoomProcessorIcePath2> { diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/RoomProcessorWaterPuzzle.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/RoomProcessorWaterPuzzle.java index 0eaadf43..a64525a8 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/RoomProcessorWaterPuzzle.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/RoomProcessorWaterPuzzle.java @@ -78,7 +78,7 @@ public class RoomProcessorWaterPuzzle extends GeneralRoomProcessor { for (WaterCondition condition : route.getConditionList()) { if (condition == null) continue; SwitchData switchData = waterBoard.getValidSwitches().get(condition.getBlockId()); - if (switchData.getCurrentState() != condition.isRequiredState()) { + if (switchData.getCurrentState(getDungeonRoom().getContext().getWorld()) != condition.isRequiredState()) { RenderUtils.highlightBlock(switchData.getSwitchLoc(), new Color(0,255,0,50), partialTicks); RenderUtils.drawTextAtWorld(condition.isRequiredState() ? "on":"off",switchData.getSwitchLoc().getX(), switchData.getSwitchLoc().getY(), switchData.getSwitchLoc().getZ(), 0xFF000000,0.1f, false, false, partialTicks); } diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/SwitchData.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/SwitchData.java index 79d0060b..79c25f52 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/SwitchData.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/SwitchData.java @@ -3,6 +3,8 @@ package kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle; import kr.syeyoung.dungeonsguide.DungeonsGuide; import kr.syeyoung.dungeonsguide.SkyblockStatus; import kr.syeyoung.dungeonsguide.dungeon.roomfinder.DungeonRoom; +import kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle.nodes.WaterNodeStart; +import kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle.nodes.WaterNodeToggleable; import lombok.AllArgsConstructor; import lombok.Data; import net.minecraft.block.BlockLever; @@ -12,14 +14,19 @@ import net.minecraft.world.World; @Data @AllArgsConstructor public class SwitchData { + private WaterBoard waterBoard; + private BlockPos switchLoc; private BlockPos blockLoc; private String blockId; - public boolean getCurrentState() { - BlockPos switch2 = getSwitchLoc(); - World w= DungeonsGuide.getDungeonsGuide().getSkyblockStatus().getContext().getWorld(); - return w.getBlockState(switch2).getValue(BlockLever.POWERED); + public boolean getCurrentState(World w) { + WaterNode waterNode = waterBoard.getToggleableMap().get(blockId); + if (waterNode instanceof WaterNodeStart) + return ((WaterNodeStart) waterNode).isTriggered(w); + else if (waterNode instanceof WaterNodeToggleable) + return ((WaterNodeToggleable) waterNode).isTriggered(w); + return false; } } diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/WaterBoard.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/WaterBoard.java index a2da9b23..56564070 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/WaterBoard.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/WaterBoard.java @@ -38,6 +38,9 @@ public class WaterBoard { private Map<String, WaterNodeEnd> waterNodeEndMap = new HashMap<String, WaterNodeEnd>(); @Getter + private Map<String, WaterNode> toggleableMap = new HashMap<String, WaterNode>(); + + @Getter private Set<String> reqOpen = new HashSet<String>(); @Getter @@ -72,12 +75,12 @@ public class WaterBoard { int data = w.getChunkFromBlockCoords(newPos).getBlockMetadata(newPos); SwitchData sw; - switchData.add(sw = new SwitchData(pos,newPos,id+":"+data)); + switchData.add(sw = new SwitchData(this, pos,newPos,id+":"+data)); validSwitches.put(id+":"+data, sw); } } SwitchData sw; - switchData.add(sw = new SwitchData(lever.getBlockPos(waterPuzzle.getDungeonRoom()),lever.getBlockPos(waterPuzzle.getDungeonRoom()).add(0,-1,0),"mainStream")); + switchData.add(sw = new SwitchData(this, lever.getBlockPos(waterPuzzle.getDungeonRoom()),lever.getBlockPos(waterPuzzle.getDungeonRoom()).add(0,-1,0),"mainStream")); validSwitches.put("mainStream", sw); } @@ -239,9 +242,13 @@ public class WaterBoard { if (validSwitches.containsKey(backId +":"+backData)) { String resId = backId + ":"+backData; node = new WaterNodeToggleable(resId, isSwitchActive(validSwitches.get(resId)), front.getBlockPos(waterPuzzle.getDungeonRoom()),x,y); + + toggleableMap.put(resId, node); } else if (validSwitches.containsKey(frontId +":"+frontData)) { String resId = frontId +":"+frontData; node = new WaterNodeToggleable(resId, !isSwitchActive(validSwitches.get(resId)), front.getBlockPos(waterPuzzle.getDungeonRoom()),x,y); + + toggleableMap.put(resId, node); } else if (frontId == 0 || frontId == 8 || frontId == 9) { if (y == 24) { OffsetPoint pos; @@ -255,9 +262,9 @@ public class WaterBoard { int data= pos.getData(waterPuzzle.getDungeonRoom()); node = new WaterNodeEnd(id+":"+data, front.getBlockPos(waterPuzzle.getDungeonRoom()),x,y); waterNodeEndMap.put(id+":"+data, (WaterNodeEnd) node); - } else if (y == 1) { + } else if (y == 2) { waterNodeStart = (WaterNodeStart) (node = new WaterNodeStart(front.getBlockPos(waterPuzzle.getDungeonRoom()), - frontId != 0 ^ validSwitches.get("mainStream").getCurrentState(),x,y)); + frontId != 0 ^ isSwitchActive(validSwitches.get("mainStream")),x,y)); } else { node = new WaterNodeAir(front.getBlockPos(waterPuzzle.getDungeonRoom()),x,y); } @@ -267,6 +274,7 @@ public class WaterBoard { board[y][x] =node; } } + toggleableMap.put("mainStream", waterNodeStart); } // true if contradiction diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeStart.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeStart.java index 8ea7ca6c..c8197919 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeStart.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeStart.java @@ -32,6 +32,11 @@ public class WaterNodeStart implements WaterNode { return b == Blocks.water || b == Blocks.flowing_water; } + public boolean isTriggered(World w) { + System.out.println("water filled called"); + return isWaterFilled(w); + } + public BlockPos getBlockPos() { return blockPos; diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeToggleable.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeToggleable.java index 6870f3c4..aeddde9a 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeToggleable.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeToggleable.java @@ -35,6 +35,12 @@ public class WaterNodeToggleable implements WaterNode { } private int x,y; + public boolean isTriggered(World w) { + Block b= w.getChunkFromBlockCoords(blockPos).getBlock(blockPos); + + return !(b == Blocks.air || b == Blocks.water || b == Blocks.flowing_water) ^ invert; + } + public BlockPos getBlockPos() { return blockPos; |