From 0d570f2afb4b82603101807297209992df0146dd Mon Sep 17 00:00:00 2001 From: RTTV Date: Mon, 27 May 2024 01:24:39 -0400 Subject: [PATCH 01/11] Added cminesweeper command --- .../clientcommands/ClientCommands.java | 1 + .../command/MinesweeperCommand.java | 341 ++++++++++++++++++ .../assets/clientcommands/lang/en_us.json | 4 + .../gui/sprites/minesweeper/bottom.png | Bin 0 -> 140 bytes .../gui/sprites/minesweeper/bottom_left.png | Bin 0 -> 167 bytes .../gui/sprites/minesweeper/bottom_right.png | Bin 0 -> 149 bytes .../gui/sprites/minesweeper/eight_tile.png | Bin 0 -> 225 bytes .../gui/sprites/minesweeper/empty_tile.png | Bin 0 -> 156 bytes .../gui/sprites/minesweeper/five_tile.png | Bin 0 -> 203 bytes .../gui/sprites/minesweeper/flagged_tile.png | Bin 0 -> 231 bytes .../gui/sprites/minesweeper/four_tile.png | Bin 0 -> 207 bytes .../minesweeper/hovered_flagged_tile.png | Bin 0 -> 240 bytes .../gui/sprites/minesweeper/hovered_tile.png | Bin 0 -> 175 bytes .../textures/gui/sprites/minesweeper/left.png | Bin 0 -> 151 bytes .../gui/sprites/minesweeper/mine_tile.png | Bin 0 -> 281 bytes .../sprites/minesweeper/not_a_mine_tile.png | Bin 0 -> 291 bytes .../gui/sprites/minesweeper/one_tile.png | Bin 0 -> 208 bytes .../gui/sprites/minesweeper/red_mine_tile.png | Bin 0 -> 263 bytes .../gui/sprites/minesweeper/right.png | Bin 0 -> 140 bytes .../gui/sprites/minesweeper/seven_tile.png | Bin 0 -> 205 bytes .../gui/sprites/minesweeper/six_tile.png | Bin 0 -> 220 bytes .../gui/sprites/minesweeper/three_tile.png | Bin 0 -> 216 bytes .../textures/gui/sprites/minesweeper/tile.png | Bin 0 -> 180 bytes .../textures/gui/sprites/minesweeper/top.png | Bin 0 -> 148 bytes .../gui/sprites/minesweeper/top_left.png | Bin 0 -> 155 bytes .../gui/sprites/minesweeper/top_right.png | Bin 0 -> 167 bytes .../gui/sprites/minesweeper/two_tile.png | Bin 0 -> 234 bytes 27 files changed, 346 insertions(+) create mode 100644 src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/bottom.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/bottom_left.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/bottom_right.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/eight_tile.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/empty_tile.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/five_tile.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/flagged_tile.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/four_tile.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/hovered_flagged_tile.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/hovered_tile.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/left.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/mine_tile.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/not_a_mine_tile.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/one_tile.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/red_mine_tile.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/right.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/seven_tile.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/six_tile.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/three_tile.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/tile.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/top.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/top_left.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/top_right.png create mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/two_tile.png diff --git a/src/main/java/net/earthcomputer/clientcommands/ClientCommands.java b/src/main/java/net/earthcomputer/clientcommands/ClientCommands.java index 81f1c5cc4..8f4aa22c8 100644 --- a/src/main/java/net/earthcomputer/clientcommands/ClientCommands.java +++ b/src/main/java/net/earthcomputer/clientcommands/ClientCommands.java @@ -147,6 +147,7 @@ public static void registerCommands(CommandDispatcher KitCommand.register(dispatcher); ListenCommand.register(dispatcher); LookCommand.register(dispatcher); + MinesweeperCommand.register(dispatcher); MoteCommand.register(dispatcher); NoteCommand.register(dispatcher); PermissionLevelCommand.register(dispatcher); diff --git a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java new file mode 100644 index 000000000..790d356d6 --- /dev/null +++ b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java @@ -0,0 +1,341 @@ +package net.earthcomputer.clientcommands.command; + +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.util.Mth; +import org.jetbrains.annotations.Nullable; +import org.joml.Vector2i; + +import java.util.OptionalInt; +import java.util.Random; + +import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger; +import static com.mojang.brigadier.arguments.IntegerArgumentType.integer; +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument; +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; + +public class MinesweeperCommand { + private static final SimpleCommandExceptionType TOO_MANY_MINES_EXCEPTION = new SimpleCommandExceptionType(Component.translatable("commands.cminesweeper.too_many_mines")); + + public static void register(CommandDispatcher dispatcher) { + dispatcher.register(literal("cminesweeper") + .then(literal("beginner") + .executes(ctx -> minesweeper(ctx.getSource(), 9, 9, 10))) + .executes(ctx -> minesweeper(ctx.getSource(), 9, 9, 10)) + .then(literal("intermediate") + .executes(ctx -> minesweeper(ctx.getSource(), 16, 16, 40))) + .then(literal("expert") + .executes(ctx -> minesweeper(ctx.getSource(), 32, 16, 99))) + .then(literal("custom") + .then(argument("width", integer(3, 128)) + .then(argument("height", integer(3, 128)) + .then(argument("mines", integer(0, 128 * 128 - 9)) + .executes(ctx -> minesweeper(ctx.getSource(), getInteger(ctx, "width"), getInteger(ctx, "height"), getInteger(ctx, "mines")))))))); + } + + private static int minesweeper(FabricClientCommandSource source, int width, int height, int mines) throws CommandSyntaxException { + if (mines > (width * height - 9)) { + throw TOO_MANY_MINES_EXCEPTION.create(); + } + + source.getClient().tell(() -> source.getClient().setScreen(new MinesweeperGameScreen(width, height, mines))); + + return 0; + } +} + +class MinesweeperGameScreen extends Screen { + private static final ResourceLocation TOP_LEFT = new ResourceLocation("clientcommands:minesweeper/top_left"); + private static final ResourceLocation TOP = new ResourceLocation("clientcommands:minesweeper/top"); + private static final ResourceLocation TOP_RIGHT = new ResourceLocation("clientcommands:minesweeper/top_right"); + private static final ResourceLocation LEFT = new ResourceLocation("clientcommands:minesweeper/left"); + private static final ResourceLocation RIGHT = new ResourceLocation("clientcommands:minesweeper/right"); + private static final ResourceLocation BOTTOM_LEFT = new ResourceLocation("clientcommands:minesweeper/bottom_left"); + private static final ResourceLocation BOTTOM = new ResourceLocation("clientcommands:minesweeper/bottom"); + private static final ResourceLocation BOTTOM_RIGHT = new ResourceLocation("clientcommands:minesweeper/bottom_right"); + + private static final ResourceLocation NOT_A_MINE_TILE = new ResourceLocation("clientcommands:minesweeper/not_a_mine_tile"); + private static final ResourceLocation MINE_TILE = new ResourceLocation("clientcommands:minesweeper/mine_tile"); + private static final ResourceLocation RED_MINE_TILE = new ResourceLocation("clientcommands:minesweeper/red_mine_tile"); + private static final ResourceLocation EMPTY_TILE = new ResourceLocation("clientcommands:minesweeper/empty_tile"); + private static final ResourceLocation HOVERED_TILE = new ResourceLocation("clientcommands:minesweeper/hovered_tile"); + private static final ResourceLocation HOVERED_FLAGGED_TILE = new ResourceLocation("clientcommands:minesweeper/hovered_flagged_tile"); + private static final ResourceLocation FLAGGED_TILE = new ResourceLocation("clientcommands:minesweeper/flagged_tile"); + private static final ResourceLocation TILE = new ResourceLocation("clientcommands:minesweeper/tile"); + private static final ResourceLocation ONE_TILE = new ResourceLocation("clientcommands:minesweeper/one_tile"); + private static final ResourceLocation TWO_TILE = new ResourceLocation("clientcommands:minesweeper/two_tile"); + private static final ResourceLocation THREE_TILE = new ResourceLocation("clientcommands:minesweeper/three_tile"); + private static final ResourceLocation FOUR_TILE = new ResourceLocation("clientcommands:minesweeper/four_tile"); + private static final ResourceLocation FIVE_TILE = new ResourceLocation("clientcommands:minesweeper/five_tile"); + private static final ResourceLocation SIX_TILE = new ResourceLocation("clientcommands:minesweeper/six_tile"); + private static final ResourceLocation SEVEN_TILE = new ResourceLocation("clientcommands:minesweeper/seven_tile"); + private static final ResourceLocation EIGHT_TILE = new ResourceLocation("clientcommands:minesweeper/eight_tile"); + + int boardWidth; + int boardHeight; + int mines; + int ticksPlaying; + byte[] board; + int gameWidth; + int gameHeight; + int topLeftX; + int topLeftY; + @Nullable Integer dragging; + @Nullable Vector2i deathCoords; + int minesLeft; + int emptyTilesRemaining; + + MinesweeperGameScreen(int width, int height, int mines) { + super(Component.translatable("minesweeperGame.title")); + this.boardWidth = width; + this.boardHeight = height; + this.mines = mines; + this.ticksPlaying = 0; + this.board = new byte[boardWidth * boardHeight]; + this.gameWidth = boardWidth * 16 + 20; + this.gameHeight = boardHeight * 16 + 20; + this.dragging = null; + this.deathCoords = null; + this.minesLeft = mines; + this.emptyTilesRemaining = width * height - mines; + } + + @Override + protected void init() { + this.topLeftX = (this.width - gameWidth) / 2; + this.topLeftY = (this.height - gameHeight) / 2; + } + + @Override + public void render(GuiGraphics graphics, int mouseX, int mouseY, float tickDelta) { + renderBackground(graphics, mouseX, mouseY, tickDelta); + + graphics.drawString(minecraft.font, "Mines Left: " + minesLeft, topLeftX, topLeftY - 10, 0xff_ffffff); + graphics.drawCenteredString(minecraft.font, title.getString(), topLeftX + gameWidth / 2, topLeftY - 20, 0xff_ffffff); + { + String str = "Time Played: " + Math.ceilDiv(ticksPlaying, 20) + "s"; + graphics.drawString(minecraft.font, str, topLeftX + gameWidth - minecraft.font.width(str), topLeftY - 10, deathCoords != null ? ChatFormatting.RED.getColor() : (emptyTilesRemaining == 0 ? ChatFormatting.GREEN.getColor() : ChatFormatting.WHITE.getColor())); + } + + graphics.blitSprite(TOP_LEFT, topLeftX, topLeftY, 12, 12); + for (int i = 0; i < boardWidth; i++) graphics.blitSprite(TOP, topLeftX + 12 + i * 16, topLeftY, 16, 12); + graphics.blitSprite(TOP_RIGHT, topLeftX + 12 + boardWidth * 16, topLeftY, 8, 12); + for (int i = 0; i < boardHeight; i++) graphics.blitSprite(LEFT, topLeftX, topLeftY + 12 + i * 16, 12, 16); + for (int i = 0; i < boardHeight; i++) graphics.blitSprite(RIGHT, topLeftX + 12 + boardWidth * 16, topLeftY + 12 + i * 16, 8, 16); + graphics.blitSprite(BOTTOM_LEFT, topLeftX, topLeftY + 12 + boardHeight * 16, 12, 8); + for (int i = 0; i < boardWidth; i++) graphics.blitSprite(BOTTOM, topLeftX + 12 + i * 16, topLeftY + 12 + boardHeight * 16, 16, 8); + graphics.blitSprite(BOTTOM_RIGHT, topLeftX + 12 + boardWidth * 16, topLeftY + 12 + boardHeight * 16, 8, 8); + + for (int x = 0; x < boardWidth; x++) { + for (int y = 0; y < boardHeight; y++) { + boolean hovered = Mth.floorDiv(mouseX - topLeftX - 12, 16) == x && Mth.floorDiv(mouseY - topLeftY - 12, 16) == y; + graphics.blitSprite(getTileSprite(x, y, hovered), topLeftX + x * 16 + 12, topLeftY + y * 16 + 12, 16, 16); + } + } + } + + @Override + public void tick() { + if (ticksPlaying > 0 && !gameFinished()) { + ticksPlaying += 1; + } + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + dragging = button; + return false; + } + + @Override + public boolean mouseReleased(double mouseX, double mouseY, int button) { + dragging = null; + + int tileX = Mth.floorDiv((int) (mouseX - topLeftX - 12), 16); + int tileY = Mth.floorDiv((int) (mouseY - topLeftY - 12), 16); + + if (isWithinBounds(tileX, tileY)) { + if (button == 0 && !gameFinished()) { + if (ticksPlaying == 0) { + generateMines(tileX, tileY); + ticksPlaying = 1; + } + + click(tileX, tileY); + + if (emptyTilesRemaining == 0) { + minecraft.player.playNotifySound(SoundEvents.NOTE_BLOCK_PLING.value(), SoundSource.MASTER, 1.0f, 2.0f); + } else if (deathCoords != null) { + minecraft.player.playNotifySound(SoundEvents.NOTE_BLOCK_BASS.value(), SoundSource.MASTER, 1.0f, 1.0f); + } + } else if (button == 1 && !gameFinished()) { + flag(tileX, tileY); + } + } + + return true; + } + + private boolean gameFinished() { + return deathCoords != null || emptyTilesRemaining == 0; + } + + private void generateMines(int avoidX, int avoidY) { + Random random = new Random(); + + for (int i = 0; i < mines; i++) { + int x = random.nextInt(boardWidth); + int y = random.nextInt(boardHeight); + + // too close to the clicked position + if (Mth.abs(avoidX - x) <= 1 && Mth.abs(avoidY - y) <= 1) { + i--; + continue; + } + + // already a mine + if ((board[y * boardWidth + x] & 0b1100) >>> 2 == 2) { + i--; + continue; + } + + incrementWarning(x - 1, y - 1); + incrementWarning(x, y - 1); + incrementWarning(x + 1, y - 1); + + incrementWarning(x - 1, y); + board[y * boardWidth + x] = 0b000_10_0_0; + incrementWarning(x + 1, y); + + incrementWarning(x - 1, y + 1); + incrementWarning(x, y + 1); + incrementWarning(x + 1, y + 1); + } + } + + private void incrementWarning(int x, int y) { + if (isWithinBounds(x, y)) { + int idx = y * boardWidth + x; + byte original_tile = board[idx]; + if ((original_tile & 0b1100) >>> 2 == 1) { + // increment warning quantity + board[idx] += 0b0_001_00_0_0; + } else if ((original_tile & 0b1100) >>> 2 == 0) { + // set to warning tile (and since it was empty beforehand, we make it have a quantity of 1) + board[idx] = 0b0_000_01_0_0; + } + } + } + + private boolean isWithinBounds(int x, int y) { + return 0 <= x && x < boardWidth && 0 <= y && y < boardHeight; + } + + private void click(int x, int y) { + byte tile = board[y * boardWidth + x]; + boolean flagged = (tile & 2) > 0; + boolean covered = (tile & 1) == 0; + int type = (tile & 0b1100) >>> 2; + if (!covered || flagged) { + return; + } + + if (type == 1) { + // set uncovered + board[y * boardWidth + x] |= 0b1; + emptyTilesRemaining -= 1; + } else if (type == 2) { + // set uncovered + board[y * boardWidth + x] |= 0b1; + deathCoords = new Vector2i(x, y); + } else { + // set uncovered + board[y * boardWidth + x] |= 0b1; + emptyTilesRemaining -= 1; + // we need to leave room for the current tile in the queue + int[] queue = new int[emptyTilesRemaining + 1]; + int queueIdx = 0; + queue[0] = y * boardWidth + x; + while (queueIdx >= 0) { + int idx = queue[queueIdx--]; + int x_part = idx % boardWidth; + int y_part = idx / boardWidth; + for (Vector2i possibleNeighbour : new Vector2i[]{ + new Vector2i(x_part - 1, y_part - 1), + new Vector2i(x_part, y_part - 1), + new Vector2i(x_part + 1, y_part - 1), + + new Vector2i(x_part - 1, y_part), + new Vector2i(x_part + 1, y_part), + + new Vector2i(x_part - 1, y_part + 1), + new Vector2i(x_part, y_part + 1), + new Vector2i(x_part + 1, y_part + 1), + }) { + if (isWithinBounds(possibleNeighbour.x, possibleNeighbour.y)) { + int pos = possibleNeighbour.y * boardWidth + possibleNeighbour.x; + byte value = board[pos]; + // set uncovered + board[pos] |= 0b1; + if ((value & 0b1) == 0) { + emptyTilesRemaining -= 1; + // if it's an empty tile, we put it in the queue to go activate all its neighbours + if ((value & 0b11_0_0) >>> 2 == 0) queue[++queueIdx] = pos; + } + } + } + } + } + } + + private void flag(int x, int y) { + if ((board[y * boardWidth + x] & 0b1) > 0) return; + + minesLeft -= ((board[y * boardWidth + x] ^= 0b1_0) & 0b1_0) > 0 ? 1 : -1; + } + + private ResourceLocation getTileSprite(int x, int y, boolean hovered) { + byte tile = board[y * boardWidth + x]; + boolean flagged = (tile & 2) > 0; + boolean covered = (tile & 1) == 0; + int type = (tile & 0b1100) >>> 2; + int warning_quantity = (tile & 0b1110000) >>> 4; + + if (deathCoords != null && type == 2 && !flagged) { + return new Vector2i(x, y).equals(deathCoords) ? RED_MINE_TILE : MINE_TILE; + } + + if (flagged) { + return hovered && deathCoords == null ? HOVERED_FLAGGED_TILE : (deathCoords != null && type != 2 ? NOT_A_MINE_TILE : FLAGGED_TILE); + } + + if (covered) { + return hovered && deathCoords == null ? (dragging != null && dragging == 0 ? EMPTY_TILE : HOVERED_TILE) : TILE; + } + + if (type == 0) { + return EMPTY_TILE; + } else { + return switch (warning_quantity) { + case 0 -> ONE_TILE; + case 1 -> TWO_TILE; + case 2 -> THREE_TILE; + case 3 -> FOUR_TILE; + case 4 -> FIVE_TILE; + case 5 -> SIX_TILE; + case 6 -> SEVEN_TILE; + default -> EIGHT_TILE; + }; + } + } +} diff --git a/src/main/resources/assets/clientcommands/lang/en_us.json b/src/main/resources/assets/clientcommands/lang/en_us.json index 208162fd6..101e6de2f 100644 --- a/src/main/resources/assets/clientcommands/lang/en_us.json +++ b/src/main/resources/assets/clientcommands/lang/en_us.json @@ -157,6 +157,8 @@ "commands.clisten.list": "Listening to the following packets:", "commands.clisten.clear": "No longer listening to any packets", + "commands.cminesweeper.too_many_mines": "Too many mines, must be between 0 and 9 less than than the amount of total tiles", + "commands.cplayerinfo.ioException": "An error occurred", "commands.cplayerinfo.getNameHistory.success": "%s has had the following names: %s", @@ -333,6 +335,8 @@ "snakeGame.title": "Snake", "snakeGame.score": "Score: %d", + "minesweeperGame.title": "Minesweeper", + "c2cpacket.messageTooLong": "Message too long (max. 255 characters) got %s characters", "c2cpacket.publicKeyNotFound": "Public key not found", "c2cpacket.encryptionFailed": "Something failed while encrypting your message", diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/bottom.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..f829ecdcc1ced3241b9d6835db9707eb6802333c GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~c!3HEhl+{lMQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0XB4uLSEsD@VqP*Bm+#W6%9IQb7h3y%ncnuf30f*TCSl8^WC g7V7hCVdUXq@VUkwGfA*z4Nx(Ir>mdKI;Vst03((mQvd(} literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/bottom_left.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/bottom_left.png new file mode 100644 index 0000000000000000000000000000000000000000..3aa06f6d173d7b53bbe240aae32df4d29b86b154 GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CB!3HGHK9Tzfq!^2X+?^QKos)S9a~60+7BevL9RguSQ4OyKprDPXi(`mJaPl917M_5DKR*gJxJAEw|K9xa z&><%_HG^&rhM=6x%##jNcoi6ec$i$W8yFYOWnpgiV`gS%n0HlT)zmirdZ0NBp00i_ I>zopr052UaO#lD@ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/bottom_right.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/bottom_right.png new file mode 100644 index 0000000000000000000000000000000000000000..c7d5482bf726e5a40d954867981c9b788f8da2c4 GIT binary patch literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1enP|MTBF+?Lc`42w}Pe8$+AB7s+j58LP_&EeH pKHivo{6Sa(^OR`El}v1G3^j8&H$Gd#x(ld_!PC{xWt~$(69BTxCqMuI literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/eight_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/eight_tile.png new file mode 100644 index 0000000000000000000000000000000000000000..1bc586895b6e8b8d8fdd3f5e01b9dc72aad1bfbb GIT binary patch literal 225 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1enu*}oNF~q_@nTMD6?|BDC2I+u^2#%+d*na)~ zEjeRB&L&3gDQ(TMyUQFSZ#2%HEj@*mQA1B*i6qN~s}H^~olr~Z;SMn8aWFeLr{lEs zi**Zcuv#z+-u!=Jn~-eB5vDn84LMH7b})1?zF=(OU9ej6#~z2ova|#S2Ch8@du6rN RHUnM2;OXk;vd$@?2>^YfNCN-> literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/empty_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/empty_tile.png new file mode 100644 index 0000000000000000000000000000000000000000..c0381c9d89f307d09f8c72a6b7241a1de3898f84 GIT binary patch literal 156 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1en(9qMxF~q_@nTMD6?|BDC2I+u^2#%+d*na)~ xEjeRB&ZdJa7#FiO99Y44;SNXYWJU=IhS+{iiTg))3IR1Uc)I$ztaD0e0stnCD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/five_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/five_tile.png new file mode 100644 index 0000000000000000000000000000000000000000..1157341e66719c5d3058c0e51e2b90ea8af3999b GIT binary patch literal 203 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1enFu~KsF~q_@nTMD6?|BDC2I+u^2#%+d*na)~ zEjeRB&L&3gDQwNLVPOGcbq~tkNK85EkSeagoD%(k@zzd;@QMYyds4&~NcTKqs`+>9 r>7qtY_7e?2f$HK1pP5>3&TM34ST#XbK0sv!$k_~@u6{1-oD!MmdKI;Vst02IhjI{*Lx literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/four_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/four_tile.png new file mode 100644 index 0000000000000000000000000000000000000000..4a3ef61ad3452fae4cf03eacafc4f484b89f9cde GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1enFvZiwF~q_@nTMD6?|BDC2I+u^2#%+d*na)~ zEjeRB&L&3gDQ=8mVY?UTu(c&0zhm&@L_?Bzf<(i4vz&%qdJfxUSsZF|l1?=2+SqXV x{EtJezcxB(E$C-ds6T9AwcrM;NLo4@8^fjNiZT!GN`sus;OXk;vd$@?2>``mYlI5XA+~w z=e^b6B_HT9a86)ynB~Z@o?A+L&H)Me16d4)Qi%+Q8Inv7F|;v$mHoXy=Mh7geglu< zHHAHm97Zl)K|-ev^L>zV;E||cE?9Qtrtsp0IxHS%`mYlI5XA+~w z=e^b6B_HT9a86)ynB~}zBYxn(3dY534F?WLGo0hz(BsILu*k)j83-7*cPWHl$*Bzn Pn#bVj>gTe~DWM4fY&kQX literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/left.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/left.png new file mode 100644 index 0000000000000000000000000000000000000000..b28aa73f56ec0d7914b181b283e644854fcbf0dd GIT binary patch literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eK!3HFi66di4DaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5hd`K7RKu$QD5&G<;uvD#pZtfPg(slk&yPY4ZqYB_zdJ|r o@c0DG$}m{fC;`F_*}ObF46b|}a#0x}wLpCgp00i_>zopr0D6xk!~g&Q literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/mine_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/mine_tile.png new file mode 100644 index 0000000000000000000000000000000000000000..807c3a4e2e27c333f7067e83c186b29c0b5d35f8 GIT binary patch literal 281 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1enaGj@%V~BTy#>;<0Zu=8Ebnd z_ZfV+SL|w~^+hx>Ap2?BlHjG*FRfb`h1PD3Y24O-yFu#NlY7?T4W40(Z!ef~DB0?H z+b7I~;m`vGhA1T^Z5|)S3yk_aF^&Ib z?7E-K^~E~=+01JHB7q2bpDOQ7f)R-aC+|=o)FcR!YWu>O?g i{^fPaztnwPzOb0Ro+a?*gQX_W4-B5JelF{r5}E)arEBv5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/one_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/one_tile.png new file mode 100644 index 0000000000000000000000000000000000000000..786b4459db5609acdbfb7df9ece42888b552153f GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1enFxAt=F~q_@nTMD6?|BDC2I+u^2#%+d*na)~ zEjeRB&YA^#?g;gKWSqk$aEXICf>$BTm?J^Lp({<`fWd;zpDiSWxj(Qe874g7O=!GS z(4Z@jm~`V%Tax$%GfiRU6^~gpX7e04z`*e1ko0D^UF_083mH6J{an^LB{Ts57}-8z literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/red_mine_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/red_mine_tile.png new file mode 100644 index 0000000000000000000000000000000000000000..e63d373186d41921c9d516414e9aac56a4861493 GIT binary patch literal 263 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1enaE_;oV~Bd^Zn#_d zk>pP~w*!5esyA(Wo_*vBSYSOpDCPTs$y*kMZ@AW){O^>bP0l+XkK${`?Y literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/seven_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/seven_tile.png new file mode 100644 index 0000000000000000000000000000000000000000..ede2a6738593e3e8d52d78095e1499685e239abf GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1enFv-)!F~q_@nTMD6?|BDC2I+u^2#%+d*na)~ zEjeRB&L&3gDQwKz+S(f2_7-JtB&Hm7NEKI@-NRR~voA?pAeCX$+ZXGW?B)J&laFaj wDWl?T$A)cs3^%zB?_fBpx4^*K*nolIl%c%P<1;05fVMGsy85}Sb4q9e03jAVNB{r; literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/six_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/six_tile.png new file mode 100644 index 0000000000000000000000000000000000000000..4483ac12c49018a8aefb7573d057e7cd5827d03a GIT binary patch literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1enu+Y=RF~q_@nTMD6?|BDC2I+u^2#%+d*na)~ zEjeRB&L&3gDQ(QFV|OpmdGlb#Z0RYij2e0hOC+Ta6fp8ExZT1XV9%4lFunXk8>1n^ z-Gn)84LMH7b}$@GY`DxYA$X#pUPBUt-SR^WyJj_>=N3szXJcc~mQ&B=vNU)Nw4A}y L)z4*}Q$iB}Mu9=} literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/three_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/three_tile.png new file mode 100644 index 0000000000000000000000000000000000000000..66acefe561992ed402c3bfbe8ad778178f73999c GIT binary patch literal 216 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1enFxS(?F~q_@nTMD6?|BDC2I+u^2#%+d*na)~ zEjeRB&L&3gDQwK%+S(f2<`#8tB&M)3s_bUCDbP0l+XkK DD40F- literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/tile.png new file mode 100644 index 0000000000000000000000000000000000000000..14c626a0766b955c24db0955f280eee21d4c9107 GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1en(9_e!F~q_@`42w}PfF9{N7H4)bHRvuxuj3uiw89nh4KW!q6jSkj22kvxo7)9)?rw8@BjrB`k6=W(EQV{}16! UkE_1T0~*TU>FVdQ&MBb@0REyiMF0Q* literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/top.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/top.png new file mode 100644 index 0000000000000000000000000000000000000000..3943eb87e70b1e327b175df1302b9ceb5112ee7a GIT binary patch literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~e!3HF=pW8M9DaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F52SJ!|$HeTnKtWAU7sn6_|KvaXEIc9%Y8t*~3vMtROFrJm oTd2>&%q-#T?A%_WV_?9*;5m;ovERbx3s4h-r>mdKI;Vst0Ac4OC;$Ke literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/top_left.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/top_left.png new file mode 100644 index 0000000000000000000000000000000000000000..0cd76e34d7a477c445c4e6f786b371163efee92a GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&k#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=Dh+L6~vJ#O${~K?6@0#}JL+-X=@kz2}zn3)-5{e=?K|L`{h^)h(6`njxgN@xNAwUH?3 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/top_right.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/top_right.png new file mode 100644 index 0000000000000000000000000000000000000000..1c84d21ff337870e5ed3af37faf45edd31ad8f6d GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^96-#&!3HGb=lz)rq!^2X+?^QKos)S9a~60+7BevL9Ry*<9TT(P0tIb6T^vI+f|LL7v+z_f2v0f2$)S~CQ}#xp zckO~^rf2^1?M&xb6gC~abV*37h3kNth?v-;um=B0jg5_r3_SLNyY_Fm^aE%PgQu&X J%Q~loCIE^5FvkD@ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/two_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/two_tile.png new file mode 100644 index 0000000000000000000000000000000000000000..8af2c13fb4d87f621d1350f8b175944df31a5535 GIT binary patch literal 234 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1enu-?=wT~yFc5I` zb1O63_0WRX;W`J?jhMDX2EE=Lds>qiG^G+5lw}o|OPCWGZU!_pdT{X6#4RweHa1{j ZxbW93F(zZ_YoJpYJYD@<);T3K0RWHLMT!6b literal 0 HcmV?d00001 From af3ee7975c89284f5c7e6a4a52502ae905a2bf8a Mon Sep 17 00:00:00 2001 From: katie Date: Mon, 27 May 2024 15:02:18 -0400 Subject: [PATCH 02/11] temporary to move to desktop --- .../command/MinesweeperCommand.java | 92 ++++++++++-------- .../gui/sprites/minesweeper/eight_tile.png | Bin 225 -> 256 bytes .../gui/sprites/minesweeper/empty_tile.png | Bin 156 -> 163 bytes .../gui/sprites/minesweeper/five_tile.png | Bin 203 -> 3490 bytes .../gui/sprites/minesweeper/four_tile.png | Bin 207 -> 3504 bytes .../gui/sprites/minesweeper/one_tile.png | Bin 208 -> 245 bytes .../gui/sprites/minesweeper/seven_tile.png | Bin 205 -> 248 bytes .../gui/sprites/minesweeper/six_tile.png | Bin 220 -> 256 bytes .../gui/sprites/minesweeper/three_tile.png | Bin 216 -> 253 bytes .../textures/gui/sprites/minesweeper/tile.png | Bin 180 -> 183 bytes .../gui/sprites/minesweeper/two_tile.png | Bin 234 -> 255 bytes 11 files changed, 51 insertions(+), 41 deletions(-) diff --git a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java index 790d356d6..741211bb8 100644 --- a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java +++ b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java @@ -1,11 +1,12 @@ package net.earthcomputer.clientcommands.command; +import com.mojang.blaze3d.platform.InputConstants; +import com.mojang.brigadier.Command; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.minecraft.ChatFormatting; -import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; @@ -16,31 +17,28 @@ import org.jetbrains.annotations.Nullable; import org.joml.Vector2i; -import java.util.OptionalInt; import java.util.Random; -import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger; -import static com.mojang.brigadier.arguments.IntegerArgumentType.integer; -import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument; -import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; +import static com.mojang.brigadier.arguments.IntegerArgumentType.*; +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.*; public class MinesweeperCommand { private static final SimpleCommandExceptionType TOO_MANY_MINES_EXCEPTION = new SimpleCommandExceptionType(Component.translatable("commands.cminesweeper.too_many_mines")); public static void register(CommandDispatcher dispatcher) { dispatcher.register(literal("cminesweeper") - .then(literal("beginner") - .executes(ctx -> minesweeper(ctx.getSource(), 9, 9, 10))) - .executes(ctx -> minesweeper(ctx.getSource(), 9, 9, 10)) - .then(literal("intermediate") - .executes(ctx -> minesweeper(ctx.getSource(), 16, 16, 40))) - .then(literal("expert") - .executes(ctx -> minesweeper(ctx.getSource(), 32, 16, 99))) - .then(literal("custom") - .then(argument("width", integer(3, 128)) - .then(argument("height", integer(3, 128)) - .then(argument("mines", integer(0, 128 * 128 - 9)) - .executes(ctx -> minesweeper(ctx.getSource(), getInteger(ctx, "width"), getInteger(ctx, "height"), getInteger(ctx, "mines")))))))); + .executes(ctx -> minesweeper(ctx.getSource(), 9, 9, 10)) + .then(literal("beginner") + .executes(ctx -> minesweeper(ctx.getSource(), 9, 9, 10))) + .then(literal("intermediate") + .executes(ctx -> minesweeper(ctx.getSource(), 16, 16, 40))) + .then(literal("expert") + .executes(ctx -> minesweeper(ctx.getSource(), 32, 16, 99))) + .then(literal("custom") + .then(argument("width", integer(3, 128)) + .then(argument("height", integer(3, 128)) + .then(argument("mines", integer(0, 128 * 128 - 9)) + .executes(ctx -> minesweeper(ctx.getSource(), getInteger(ctx, "width"), getInteger(ctx, "height"), getInteger(ctx, "mines")))))))); } private static int minesweeper(FabricClientCommandSource source, int width, int height, int mines) throws CommandSyntaxException { @@ -50,7 +48,7 @@ private static int minesweeper(FabricClientCommandSource source, int width, int source.getClient().tell(() -> source.getClient().setScreen(new MinesweeperGameScreen(width, height, mines))); - return 0; + return Command.SINGLE_SUCCESS; } } @@ -90,8 +88,10 @@ class MinesweeperGameScreen extends Screen { int gameHeight; int topLeftX; int topLeftY; - @Nullable Integer dragging; - @Nullable Vector2i deathCoords; + @Nullable + Integer dragging; + @Nullable + Vector2i deathCoords; int minesLeft; int emptyTilesRemaining; @@ -124,16 +124,22 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float tickDelta graphics.drawCenteredString(minecraft.font, title.getString(), topLeftX + gameWidth / 2, topLeftY - 20, 0xff_ffffff); { String str = "Time Played: " + Math.ceilDiv(ticksPlaying, 20) + "s"; - graphics.drawString(minecraft.font, str, topLeftX + gameWidth - minecraft.font.width(str), topLeftY - 10, deathCoords != null ? ChatFormatting.RED.getColor() : (emptyTilesRemaining == 0 ? ChatFormatting.GREEN.getColor() : ChatFormatting.WHITE.getColor())); + graphics.drawString(minecraft.font, str, topLeftX + gameWidth - minecraft.font.width(str), topLeftY - 10, deathCoords != null ? ChatFormatting.RED.getColor() : (emptyTilesRemaining == 0 ? ChatFormatting.GREEN.getColor() : ChatFormatting.WHITE.getColor())); } graphics.blitSprite(TOP_LEFT, topLeftX, topLeftY, 12, 12); - for (int i = 0; i < boardWidth; i++) graphics.blitSprite(TOP, topLeftX + 12 + i * 16, topLeftY, 16, 12); + for (int i = 0; i < boardWidth; i++) { + graphics.blitSprite(TOP, topLeftX + 12 + i * 16, topLeftY, 16, 12); + } graphics.blitSprite(TOP_RIGHT, topLeftX + 12 + boardWidth * 16, topLeftY, 8, 12); - for (int i = 0; i < boardHeight; i++) graphics.blitSprite(LEFT, topLeftX, topLeftY + 12 + i * 16, 12, 16); - for (int i = 0; i < boardHeight; i++) graphics.blitSprite(RIGHT, topLeftX + 12 + boardWidth * 16, topLeftY + 12 + i * 16, 8, 16); + for (int i = 0; i < boardHeight; i++) { + graphics.blitSprite(LEFT, topLeftX, topLeftY + 12 + i * 16, 12, 16); + graphics.blitSprite(RIGHT, topLeftX + 12 + boardWidth * 16, topLeftY + 12 + i * 16, 8, 16); + } graphics.blitSprite(BOTTOM_LEFT, topLeftX, topLeftY + 12 + boardHeight * 16, 12, 8); - for (int i = 0; i < boardWidth; i++) graphics.blitSprite(BOTTOM, topLeftX + 12 + i * 16, topLeftY + 12 + boardHeight * 16, 16, 8); + for (int i = 0; i < boardWidth; i++) { + graphics.blitSprite(BOTTOM, topLeftX + 12 + i * 16, topLeftY + 12 + boardHeight * 16, 16, 8); + } graphics.blitSprite(BOTTOM_RIGHT, topLeftX + 12 + boardWidth * 16, topLeftY + 12 + boardHeight * 16, 8, 8); for (int x = 0; x < boardWidth; x++) { @@ -164,8 +170,8 @@ public boolean mouseReleased(double mouseX, double mouseY, int button) { int tileX = Mth.floorDiv((int) (mouseX - topLeftX - 12), 16); int tileY = Mth.floorDiv((int) (mouseY - topLeftY - 12), 16); - if (isWithinBounds(tileX, tileY)) { - if (button == 0 && !gameFinished()) { + if (isWithinBounds(tileX, tileY) && !gameFinished()) { + if (button == InputConstants.MOUSE_BUTTON_LEFT) { if (ticksPlaying == 0) { generateMines(tileX, tileY); ticksPlaying = 1; @@ -178,7 +184,7 @@ public boolean mouseReleased(double mouseX, double mouseY, int button) { } else if (deathCoords != null) { minecraft.player.playNotifySound(SoundEvents.NOTE_BLOCK_BASS.value(), SoundSource.MASTER, 1.0f, 1.0f); } - } else if (button == 1 && !gameFinished()) { + } else if (button == InputConstants.MOUSE_BUTTON_RIGHT) { flag(tileX, tileY); } } @@ -268,19 +274,19 @@ private void click(int x, int y) { queue[0] = y * boardWidth + x; while (queueIdx >= 0) { int idx = queue[queueIdx--]; - int x_part = idx % boardWidth; - int y_part = idx / boardWidth; + int xPart = idx % boardWidth; + int yPart = idx / boardWidth; for (Vector2i possibleNeighbour : new Vector2i[]{ - new Vector2i(x_part - 1, y_part - 1), - new Vector2i(x_part, y_part - 1), - new Vector2i(x_part + 1, y_part - 1), + new Vector2i(xPart - 1, yPart - 1), + new Vector2i(xPart, yPart - 1), + new Vector2i(xPart + 1, yPart - 1), - new Vector2i(x_part - 1, y_part), - new Vector2i(x_part + 1, y_part), + new Vector2i(xPart - 1, yPart), + new Vector2i(xPart + 1, yPart), - new Vector2i(x_part - 1, y_part + 1), - new Vector2i(x_part, y_part + 1), - new Vector2i(x_part + 1, y_part + 1), + new Vector2i(xPart - 1, yPart + 1), + new Vector2i(xPart, yPart + 1), + new Vector2i(xPart + 1, yPart + 1), }) { if (isWithinBounds(possibleNeighbour.x, possibleNeighbour.y)) { int pos = possibleNeighbour.y * boardWidth + possibleNeighbour.x; @@ -290,7 +296,9 @@ private void click(int x, int y) { if ((value & 0b1) == 0) { emptyTilesRemaining -= 1; // if it's an empty tile, we put it in the queue to go activate all its neighbours - if ((value & 0b11_0_0) >>> 2 == 0) queue[++queueIdx] = pos; + if ((value & 0b11_0_0) >>> 2 == 0) { + queue[++queueIdx] = pos; + } } } } @@ -299,7 +307,9 @@ private void click(int x, int y) { } private void flag(int x, int y) { - if ((board[y * boardWidth + x] & 0b1) > 0) return; + if ((board[y * boardWidth + x] & 0b1) > 0) { + return; + } minesLeft -= ((board[y * boardWidth + x] ^= 0b1_0) & 0b1_0) > 0 ? 1 : -1; } diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/eight_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/eight_tile.png index 1bc586895b6e8b8d8fdd3f5e01b9dc72aad1bfbb..af2eb1128f9c3b688a7c794e0607f83c10ba9faf 100644 GIT binary patch delta 191 zcmV;w06_oY0e}LKNq@lr01m+cxRGn^0001$Nkl^Kt$xdZ)GtEIOkf=%+uY`&8-8A-jNxil{f)2x1LY{u`+lRqLl$+ thG>ByZo}yi=`GIaSNi>#D8^X-ume`Xpv7VrteOA-002ovPDHLkV1n?0P+$N6 delta 160 zcmV;R0AK%r0^tFWNq@os01mx4 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/empty_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/empty_tile.png index c0381c9d89f307d09f8c72a6b7241a1de3898f84..21a498265b32576d0b97020fd7d5d84d25f0ac95 100644 GIT binary patch delta 97 zcmbQkxR`N*XVgIk2EK!gJ0@noWnf^i@N{tuvG7keF*pBz-a(CnlQS^^#FiHlYSMET z(a_XPOmGrc5$%yO$YMCWf>GeY-MfG13o$TQzH*h->0!G=ss@)z4*}Q$iB}&chy_ delta 90 zcmV-g0Hyz<0h|GlNmIfA01m7~jRY5&!@I07*qoM6N<$f;#pdz5oCK diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/five_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/five_tile.png index 1157341e66719c5d3058c0e51e2b90ea8af3999b..c4933821d5873464c71b4e87ce330a8bc7b97409 100644 GIT binary patch literal 3490 zcmd^B$!{A~7@ujpO`Foty#-O%LKRYi<9f*=#St^MW1QNKmpC*HQ97P^8BaWmJBt%@ z=z&9vgoK0&XAlUG_#coE2TmN2xFRIfg2bhjkdUehwS3=<9or?P1&LFhHE;Red%tge z-{(@g7`skWb1hNJsk}sj+p=gilA()JpVzt)D)Fha3 zxMa&5TYw>L#mHjSp*E7DGftLk~95zW1x;;v~6JC*!mzREUJ zY<_$u-IlWT+~yWCXEVyea=|dWXY+ZAh95;ef`%iu(F4#GOT4UE zY27LkE1c#nej?bj`LM|+f+<_EY=a~=_V0Qx|7raT1xCU7z?r!PnQ;QF)3Pfo`n(F<>i- z@j~ZC^4>PXGrksYfNREB!{9q;$ngysjeTT*V9IZiqXX-<`yxF6zo(yFUtrH*EHHlP zaDtx)nLg$wM~;mGzoi?#je@Mgs$vk0G)c$X#-~ctJ_ZPfUnV>9X4vAT$XaCGcMwSFIV1&TF&T zk;`EqP4>A&XQ6aCTmai;65D0MN~{a`dk^r)5MTlU@u^M^0L}oA131$I1Uj57f0-i$PV~+!aV9yFXhHur$9mf%PWb_0KLj@wG8>F8T|5JfL=u?AP zoRck;Z#lW#sSzzhZxO?iiRm|OW0M!in6o+FFCK?nf>S$2-ML#qx+nV(PR8-P`UHOC z1H4PSY%%PP4c@4_VxTqXK;Zn~mdo7fhXI@fcoJ?fr=aVn=F_n7BK_aVgxS+y2SD5X@&kCs=_`Kil9imrod|v*z`c=9dcNK zsJhYN6kTYdN$~4cp4VW`oQ2MddOqD!=x~q5tK{zm-;cQ;G#-^rju)Deq1&41*IT?G zTOGzRML`z{jTO$bUur!~A2>Vcd?)Z6ccU$O4)?tPHaXb08uKEoY5I}(HYARJxbFm+ zlXNyVr~sm2^J4fsW60royywLjcv8@y#{v+slGT`sGY#G>IsZZeBH1K{K}6VQXd1)H zNk%x*epJCJ^*HX6Qh%s#0E${W_ig}n2hYZ)ryuFX3wQ6{z461Ht79L3e%*J&_etcl z2WL+I`Of$EZk{^!=|?9YenIZD-+ldy^v%yVkKB6c;RoNI)4sa@9 r>7qtY_7e?2f$HK1pP5>3&TM34ST#XbK0sv!$k_~@u6{1-oD!Mkf9oT4~o#x}-j>?D4KI8l^d&)nM6jAz_= z#BrBM6d{oK3rM^+{0BBDY}j?ff(@c#StL*;R0+yCGj?s4mKG#dxz^mrx%YnOdC&1` zx)8m?G7BwP%QZ=z2HJ{jHIl*ExnQ6{m3qT+=PKz?!-RP-V3Iv5zoS@b3$(O)GN`PJE5&yBTDGnW&`JIjZF#YX%l%Q(t;%K-O3`Um?~9@;<|XVT#cjzAyds3cQfrw zW~rGH&E;%3zj@mvE4dumPi?jv>1;KZZLf&A>V89LEp?=gOhneRRbe)pR!eW|F}<;? z#)T59R4?lVb+g==X&_HQC{@;1ir3<)YA%-y24)r)W_m`N>DhjfVd2LxkD%d*ZS)9q zg;k0CA&#Ai-V1$ikVi-mTpp+bG`0$VuEwSfq(4&mu!<7d1?_EB+6N|X)+#$85v>E z3_>qs;4CYqg^Kw7CrTX?j)uDO|IBvRDP2{mWI;HYp)A#?p-3SRdYz~?1vuk+WNWK? zv}75IR-XZycaqzlAmrfJj1n!0j?Pr41;vgkW)Jf8hdPjU@Eui$$|Br`!YQM|5QJ_zQCTx zSm1ro;RHVqGJV2LjvPCAa#J_BoxGyqAliy5^E*Ylr(hOeXWuu@M$rgwpV=>eY{0*)f^sV9L!uond$$G7U_j?)M{GI|Dvp#qW84cgC%|EWMA z^tr(-E-F@&w47Y-)QFa$x2Rz$)byFQaf3*7+}WJ!7ms5u!Kodi?%b^)-IIL?C*yc7 zKZD=Y0PoeuY%%Ok4c;iZVxToxzyH$Umdo7fhXI@fcouH(=b-DS=JT-dBK_aVgxS+q z14qg$Ezjhj1Qn>1qPt;E6?CIX)b0{RaKv~Sd7>Ck(+d4PRE0Scil9urrbM(bYp$bz`mgkL0Ak#=8e#@!ct2p>y)E~?b6>i^71n$BXc59@ iZXEIWGa;o^pKt(2L1M0F=tfKc0000D%PDHLkV1hc2GP(c& diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/seven_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/seven_tile.png index ede2a6738593e3e8d52d78095e1499685e239abf..8a9035db46d12fe5152d2f9350ba946a8292acb0 100644 GIT binary patch delta 183 zcmV;o07(DM0r&xsNq@lr01m+cxRGn^0001uNklXl lKoTPII32+E&jgbF3m5PxV^vHX^BMpE002ovPDHLkV1i|BOC$gQ delta 140 zcmV;70CWHN0nGuBNq@os01m==~AKxG#on~V-{xsGBN5M=LGsCm5sI|%si@$QmLhBt%0WT%w zp@UDCMMT=Zhn!nDj`IMLg&E&AEG2jc>ng4H6bKg}pa>Uu<2ZdDBo}zj;1vum05f0& t0bG((z)pHbFC{GtGF!U*nZ(`46&|aff}DRb;GF;f002ovPDHLkV1gGPPGA54 delta 155 zcmV;M0A&Aw0^9+RNq@os01m-TTT z84GeYF>+5~WA@h8*5Ed`sCy$Zg_TidH^W^a5%C4H`*;d=_B}E C05W3$ diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/tile.png index 14c626a0766b955c24db0955f280eee21d4c9107..a4de3c7dcde43cb4888a5f2242e7260e2f00672c 100644 GIT binary patch delta 117 zcmV-*0E+*#0k;8=Np8Ua01m+cxRGn^0000?NklfPq`0ShtU_w}j z4$j1~b0#0*L($;x%_JCLLJ;7EH8Q$8;KST9cax6bv!~*=NH=GY3U|c924_MR3mbGi sxA=C(MUD*;u07*XG~E770-)Yu0fv-q8}F8}}l delta 169 zcmV;a09OD10qOyeNq@os01m Date: Mon, 27 May 2024 19:55:23 -0400 Subject: [PATCH 03/11] Changed to atlas --- .../command/MinesweeperCommand.java | 111 ++++++++++-------- .../gui/sprites/minesweeper/bottom.png | Bin 140 -> 0 bytes .../gui/sprites/minesweeper/bottom_left.png | Bin 167 -> 0 bytes .../gui/sprites/minesweeper/bottom_right.png | Bin 149 -> 0 bytes .../gui/sprites/minesweeper/eight_tile.png | Bin 256 -> 0 bytes .../gui/sprites/minesweeper/empty_tile.png | Bin 163 -> 0 bytes .../gui/sprites/minesweeper/five_tile.png | Bin 3490 -> 0 bytes .../gui/sprites/minesweeper/flagged_tile.png | Bin 231 -> 0 bytes .../gui/sprites/minesweeper/four_tile.png | Bin 3504 -> 0 bytes .../minesweeper/hovered_flagged_tile.png | Bin 240 -> 0 bytes .../gui/sprites/minesweeper/hovered_tile.png | Bin 175 -> 0 bytes .../textures/gui/sprites/minesweeper/left.png | Bin 151 -> 0 bytes .../gui/sprites/minesweeper/mine_tile.png | Bin 281 -> 0 bytes .../sprites/minesweeper/not_a_mine_tile.png | Bin 291 -> 0 bytes .../gui/sprites/minesweeper/one_tile.png | Bin 245 -> 0 bytes .../gui/sprites/minesweeper/red_mine_tile.png | Bin 263 -> 0 bytes .../gui/sprites/minesweeper/right.png | Bin 140 -> 0 bytes .../gui/sprites/minesweeper/seven_tile.png | Bin 248 -> 0 bytes .../gui/sprites/minesweeper/six_tile.png | Bin 256 -> 0 bytes .../gui/sprites/minesweeper/three_tile.png | Bin 253 -> 0 bytes .../textures/gui/sprites/minesweeper/tile.png | Bin 183 -> 0 bytes .../textures/gui/sprites/minesweeper/top.png | Bin 148 -> 0 bytes .../gui/sprites/minesweeper/top_left.png | Bin 155 -> 0 bytes .../gui/sprites/minesweeper/top_right.png | Bin 167 -> 0 bytes .../gui/sprites/minesweeper/two_tile.png | Bin 255 -> 0 bytes .../textures/minesweeper_atlas.png | Bin 0 -> 1671 bytes 26 files changed, 59 insertions(+), 52 deletions(-) delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/bottom.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/bottom_left.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/bottom_right.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/eight_tile.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/empty_tile.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/five_tile.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/flagged_tile.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/four_tile.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/hovered_flagged_tile.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/hovered_tile.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/left.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/mine_tile.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/not_a_mine_tile.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/one_tile.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/red_mine_tile.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/right.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/seven_tile.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/six_tile.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/three_tile.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/tile.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/top.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/top_left.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/top_right.png delete mode 100644 src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/two_tile.png create mode 100644 src/main/resources/assets/clientcommands/textures/minesweeper_atlas.png diff --git a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java index 741211bb8..f3e2f7745 100644 --- a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java +++ b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java @@ -53,31 +53,33 @@ private static int minesweeper(FabricClientCommandSource source, int width, int } class MinesweeperGameScreen extends Screen { - private static final ResourceLocation TOP_LEFT = new ResourceLocation("clientcommands:minesweeper/top_left"); - private static final ResourceLocation TOP = new ResourceLocation("clientcommands:minesweeper/top"); - private static final ResourceLocation TOP_RIGHT = new ResourceLocation("clientcommands:minesweeper/top_right"); - private static final ResourceLocation LEFT = new ResourceLocation("clientcommands:minesweeper/left"); - private static final ResourceLocation RIGHT = new ResourceLocation("clientcommands:minesweeper/right"); - private static final ResourceLocation BOTTOM_LEFT = new ResourceLocation("clientcommands:minesweeper/bottom_left"); - private static final ResourceLocation BOTTOM = new ResourceLocation("clientcommands:minesweeper/bottom"); - private static final ResourceLocation BOTTOM_RIGHT = new ResourceLocation("clientcommands:minesweeper/bottom_right"); - - private static final ResourceLocation NOT_A_MINE_TILE = new ResourceLocation("clientcommands:minesweeper/not_a_mine_tile"); - private static final ResourceLocation MINE_TILE = new ResourceLocation("clientcommands:minesweeper/mine_tile"); - private static final ResourceLocation RED_MINE_TILE = new ResourceLocation("clientcommands:minesweeper/red_mine_tile"); - private static final ResourceLocation EMPTY_TILE = new ResourceLocation("clientcommands:minesweeper/empty_tile"); - private static final ResourceLocation HOVERED_TILE = new ResourceLocation("clientcommands:minesweeper/hovered_tile"); - private static final ResourceLocation HOVERED_FLAGGED_TILE = new ResourceLocation("clientcommands:minesweeper/hovered_flagged_tile"); - private static final ResourceLocation FLAGGED_TILE = new ResourceLocation("clientcommands:minesweeper/flagged_tile"); - private static final ResourceLocation TILE = new ResourceLocation("clientcommands:minesweeper/tile"); - private static final ResourceLocation ONE_TILE = new ResourceLocation("clientcommands:minesweeper/one_tile"); - private static final ResourceLocation TWO_TILE = new ResourceLocation("clientcommands:minesweeper/two_tile"); - private static final ResourceLocation THREE_TILE = new ResourceLocation("clientcommands:minesweeper/three_tile"); - private static final ResourceLocation FOUR_TILE = new ResourceLocation("clientcommands:minesweeper/four_tile"); - private static final ResourceLocation FIVE_TILE = new ResourceLocation("clientcommands:minesweeper/five_tile"); - private static final ResourceLocation SIX_TILE = new ResourceLocation("clientcommands:minesweeper/six_tile"); - private static final ResourceLocation SEVEN_TILE = new ResourceLocation("clientcommands:minesweeper/seven_tile"); - private static final ResourceLocation EIGHT_TILE = new ResourceLocation("clientcommands:minesweeper/eight_tile"); + private static final ResourceLocation MINESWEEPER_ATLAS = new ResourceLocation("clientcommands:textures/minesweeper_atlas.png"); + + private static final Vector2i TOP_LEFT_UV = new Vector2i(0, 0); + private static final Vector2i TOP_UV = new Vector2i(12, 0); + private static final Vector2i TOP_RIGHT_UV = new Vector2i(28, 0); + private static final Vector2i LEFT_UV = new Vector2i(0, 12); + private static final Vector2i RIGHT_UV = new Vector2i(28, 12); + private static final Vector2i BOTTOM_LEFT_UV = new Vector2i(0, 28); + private static final Vector2i BOTTOM_UV = new Vector2i(12, 28); + private static final Vector2i BOTTOM_RIGHT_UV = new Vector2i(28, 28); + + private static final Vector2i NOT_A_MINE_TILE_UV = new Vector2i(68, 32); + private static final Vector2i MINE_TILE_UV = new Vector2i(52, 32); + private static final Vector2i RED_MINE_TILE_UV = new Vector2i(84, 16); + private static final Vector2i EMPTY_TILE_UV = new Vector2i(12, 12); + private static final Vector2i HOVERED_TILE_UV = new Vector2i(100, 16); + private static final Vector2i HOVERED_FLAGGED_TILE_UV = new Vector2i(36, 32); + private static final Vector2i FLAGGED_TILE_UV = new Vector2i(100, 32); + private static final Vector2i TILE_UV = new Vector2i(84, 32); + private static final Vector2i ONE_TILE_UV = new Vector2i(36, 0); + private static final Vector2i TWO_TILE_UV = new Vector2i(52, 0); + private static final Vector2i THREE_TILE_UV = new Vector2i(68, 0); + private static final Vector2i FOUR_TILE_UV = new Vector2i(84, 0); + private static final Vector2i FIVE_TILE_UV = new Vector2i(100, 0); + private static final Vector2i SIX_TILE_UV = new Vector2i(36, 16); + private static final Vector2i SEVEN_TILE_UV = new Vector2i(52, 16); + private static final Vector2i EIGHT_TILE_UV = new Vector2i(68, 16); int boardWidth; int boardHeight; @@ -127,32 +129,36 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float tickDelta graphics.drawString(minecraft.font, str, topLeftX + gameWidth - minecraft.font.width(str), topLeftY - 10, deathCoords != null ? ChatFormatting.RED.getColor() : (emptyTilesRemaining == 0 ? ChatFormatting.GREEN.getColor() : ChatFormatting.WHITE.getColor())); } - graphics.blitSprite(TOP_LEFT, topLeftX, topLeftY, 12, 12); + blitSprite(graphics, TOP_LEFT_UV, 0, 0, 12, 12); for (int i = 0; i < boardWidth; i++) { - graphics.blitSprite(TOP, topLeftX + 12 + i * 16, topLeftY, 16, 12); + blitSprite(graphics, TOP_UV, 12 + i * 16, 0, 16, 12); } - graphics.blitSprite(TOP_RIGHT, topLeftX + 12 + boardWidth * 16, topLeftY, 8, 12); + blitSprite(graphics, TOP_RIGHT_UV, 12 + boardWidth * 16, 0, 8, 12); for (int i = 0; i < boardHeight; i++) { - graphics.blitSprite(LEFT, topLeftX, topLeftY + 12 + i * 16, 12, 16); - graphics.blitSprite(RIGHT, topLeftX + 12 + boardWidth * 16, topLeftY + 12 + i * 16, 8, 16); + blitSprite(graphics, LEFT_UV, 0, 12 + i * 16, 12, 16); + blitSprite(graphics, RIGHT_UV, 12 + boardWidth * 16, 12 + i * 16, 8, 16); } - graphics.blitSprite(BOTTOM_LEFT, topLeftX, topLeftY + 12 + boardHeight * 16, 12, 8); + blitSprite(graphics, BOTTOM_LEFT_UV, 0, 12 + boardHeight * 16, 12, 8); for (int i = 0; i < boardWidth; i++) { - graphics.blitSprite(BOTTOM, topLeftX + 12 + i * 16, topLeftY + 12 + boardHeight * 16, 16, 8); + blitSprite(graphics, BOTTOM_UV, 12 + i * 16, 12 + boardHeight * 16, 16, 8); } - graphics.blitSprite(BOTTOM_RIGHT, topLeftX + 12 + boardWidth * 16, topLeftY + 12 + boardHeight * 16, 8, 8); + blitSprite(graphics, BOTTOM_RIGHT_UV, 12 + boardWidth * 16, 12 + boardHeight * 16, 8, 8); for (int x = 0; x < boardWidth; x++) { for (int y = 0; y < boardHeight; y++) { boolean hovered = Mth.floorDiv(mouseX - topLeftX - 12, 16) == x && Mth.floorDiv(mouseY - topLeftY - 12, 16) == y; - graphics.blitSprite(getTileSprite(x, y, hovered), topLeftX + x * 16 + 12, topLeftY + y * 16 + 12, 16, 16); + blitSprite(graphics, getTileSprite(x, y, hovered), x * 16 + 12, y * 16 + 12, 16, 16); } } } + public void blitSprite(GuiGraphics graphics, Vector2i uv, int x, int y, int width, int height) { + graphics.blit(MINESWEEPER_ATLAS, topLeftX + x, topLeftY + y, width, height, uv.x, uv.y, width, height, 128, 64); + } + @Override public void tick() { - if (ticksPlaying > 0 && !gameFinished()) { + if (ticksPlaying > 0 && gameActive()) { ticksPlaying += 1; } } @@ -170,7 +176,7 @@ public boolean mouseReleased(double mouseX, double mouseY, int button) { int tileX = Mth.floorDiv((int) (mouseX - topLeftX - 12), 16); int tileY = Mth.floorDiv((int) (mouseY - topLeftY - 12), 16); - if (isWithinBounds(tileX, tileY) && !gameFinished()) { + if (isWithinBounds(tileX, tileY) && gameActive()) { if (button == InputConstants.MOUSE_BUTTON_LEFT) { if (ticksPlaying == 0) { generateMines(tileX, tileY); @@ -179,7 +185,8 @@ public boolean mouseReleased(double mouseX, double mouseY, int button) { click(tileX, tileY); - if (emptyTilesRemaining == 0) { + assert minecraft != null && minecraft.player != null; + if (emptyTilesRemaining <= 0) { minecraft.player.playNotifySound(SoundEvents.NOTE_BLOCK_PLING.value(), SoundSource.MASTER, 1.0f, 2.0f); } else if (deathCoords != null) { minecraft.player.playNotifySound(SoundEvents.NOTE_BLOCK_BASS.value(), SoundSource.MASTER, 1.0f, 1.0f); @@ -192,8 +199,8 @@ public boolean mouseReleased(double mouseX, double mouseY, int button) { return true; } - private boolean gameFinished() { - return deathCoords != null || emptyTilesRemaining == 0; + private boolean gameActive() { + return deathCoords == null && emptyTilesRemaining > 0; } private void generateMines(int avoidX, int avoidY) { @@ -314,7 +321,7 @@ private void flag(int x, int y) { minesLeft -= ((board[y * boardWidth + x] ^= 0b1_0) & 0b1_0) > 0 ? 1 : -1; } - private ResourceLocation getTileSprite(int x, int y, boolean hovered) { + private Vector2i getTileSprite(int x, int y, boolean hovered) { byte tile = board[y * boardWidth + x]; boolean flagged = (tile & 2) > 0; boolean covered = (tile & 1) == 0; @@ -322,29 +329,29 @@ private ResourceLocation getTileSprite(int x, int y, boolean hovered) { int warning_quantity = (tile & 0b1110000) >>> 4; if (deathCoords != null && type == 2 && !flagged) { - return new Vector2i(x, y).equals(deathCoords) ? RED_MINE_TILE : MINE_TILE; + return new Vector2i(x, y).equals(deathCoords) ? RED_MINE_TILE_UV : MINE_TILE_UV; } if (flagged) { - return hovered && deathCoords == null ? HOVERED_FLAGGED_TILE : (deathCoords != null && type != 2 ? NOT_A_MINE_TILE : FLAGGED_TILE); + return hovered && deathCoords == null ? HOVERED_FLAGGED_TILE_UV : (deathCoords != null && type != 2 ? NOT_A_MINE_TILE_UV : FLAGGED_TILE_UV); } if (covered) { - return hovered && deathCoords == null ? (dragging != null && dragging == 0 ? EMPTY_TILE : HOVERED_TILE) : TILE; + return hovered && deathCoords == null ? (dragging != null && dragging == 0 ? EMPTY_TILE_UV : HOVERED_TILE_UV) : TILE_UV; } if (type == 0) { - return EMPTY_TILE; + return EMPTY_TILE_UV; } else { return switch (warning_quantity) { - case 0 -> ONE_TILE; - case 1 -> TWO_TILE; - case 2 -> THREE_TILE; - case 3 -> FOUR_TILE; - case 4 -> FIVE_TILE; - case 5 -> SIX_TILE; - case 6 -> SEVEN_TILE; - default -> EIGHT_TILE; + case 0 -> ONE_TILE_UV; + case 1 -> TWO_TILE_UV; + case 2 -> THREE_TILE_UV; + case 3 -> FOUR_TILE_UV; + case 4 -> FIVE_TILE_UV; + case 5 -> SIX_TILE_UV; + case 6 -> SEVEN_TILE_UV; + default -> EIGHT_TILE_UV; }; } } diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/bottom.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/bottom.png deleted file mode 100644 index f829ecdcc1ced3241b9d6835db9707eb6802333c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~c!3HEhl+{lMQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0XB4uLSEsD@VqP*Bm+#W6%9IQb7h3y%ncnuf30f*TCSl8^WC g7V7hCVdUXq@VUkwGfA*z4Nx(Ir>mdKI;Vst03((mQvd(} diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/bottom_left.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/bottom_left.png deleted file mode 100644 index 3aa06f6d173d7b53bbe240aae32df4d29b86b154..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CB!3HGHK9Tzfq!^2X+?^QKos)S9a~60+7BevL9RguSQ4OyKprDPXi(`mJaPl917M_5DKR*gJxJAEw|K9xa z&><%_HG^&rhM=6x%##jNcoi6ec$i$W8yFYOWnpgiV`gS%n0HlT)zmirdZ0NBp00i_ I>zopr052UaO#lD@ diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/bottom_right.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/bottom_right.png deleted file mode 100644 index c7d5482bf726e5a40d954867981c9b788f8da2c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1enP|MTBF+?Lc`42w}Pe8$+AB7s+j58LP_&EeH pKHivo{6Sa(^OR`El}v1G3^j8&H$Gd#x(ld_!PC{xWt~$(69BTxCqMuI diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/eight_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/eight_tile.png deleted file mode 100644 index af2eb1128f9c3b688a7c794e0607f83c10ba9faf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 256 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBuf-vKbiP>*~f>S+R978PpmrmZzdq9E5Wv+(o?Hz?j#pGIb zCA#P3uJD|!u;YQoeDz49gt_O`H+Fa|?O&m#s}vL}dS6b^X@RKz{USk)rFX=PIL@#M z%-LySanh3i>g1rTy_ya#Pxj`g8gf`Xk2-(m^4*JP*D`nCn<%+xDx>lCc>xR?jVeTd y?4-7gM#a3tF9lxeo_i7g>+ejBV-f#1Fozvna5PDL%`Bh;89ZJ6T-G@yGywoKv0OU< diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/empty_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/empty_tile.png deleted file mode 100644 index 21a498265b32576d0b97020fd7d5d84d25f0ac95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBuf-vKbiP>*~f)<`Gjv*HQ$tLFJ|Ia(9ad2`bCV<%TLPAY? z?jjnRnu!Tc;wqv&QU+NJhgUEPT)2Dp?|dN!2Fq8jvf4R4JAh^|c)I$ztaD0e0ss!F BD)|5a diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/five_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/five_tile.png deleted file mode 100644 index c4933821d5873464c71b4e87ce330a8bc7b97409..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3490 zcmd^B$!{A~7@ujpO`Foty#-O%LKRYi<9f*=#St^MW1QNKmpC*HQ97P^8BaWmJBt%@ z=z&9vgoK0&XAlUG_#coE2TmN2xFRIfg2bhjkdUehwS3=<9or?P1&LFhHE;Red%tge z-{(@g7`skWb1hNJsk}sj+p=gilA()JpVzt)D)Fha3 zxMa&5TYw>L#mHjSp*E7DGftLk~95zW1x;;v~6JC*!mzREUJ zY<_$u-IlWT+~yWCXEVyea=|dWXY+ZAh95;ef`%iu(F4#GOT4UE zY27LkE1c#nej?bj`LM|+f+<_EY=a~=_V0Qx|7raT1xCU7z?r!PnQ;QF)3Pfo`n(F<>i- z@j~ZC^4>PXGrksYfNREB!{9q;$ngysjeTT*V9IZiqXX-<`yxF6zo(yFUtrH*EHHlP zaDtx)nLg$wM~;mGzoi?#je@Mgs$vk0G)c$X#-~ctJ_ZPfUnV>9X4vAT$XaCGcMwSFIV1&TF&T zk;`EqP4>A&XQ6aCTmai;65D0MN~{a`dk^r)5MTlU@u^M^0L}oA131$I1Uj57f0-i$PV~+!aV9yFXhHur$9mf%PWb_0KLj@wG8>F8T|5JfL=u?AP zoRck;Z#lW#sSzzhZxO?iiRm|OW0M!in6o+FFCK?nf>S$2-ML#qx+nV(PR8-P`UHOC z1H4PSY%%PP4c@4_VxTqXK;Zn~mdo7fhXI@fcoJ?fr=aVn=F_n7BK_aVgxS+y2SD5X@&kCs=_`Kil9imrod|v*z`c=9dcNK zsJhYN6kTYdN$~4cp4VW`oQ2MddOqD!=x~q5tK{zm-;cQ;G#-^rju)Deq1&41*IT?G zTOGzRML`z{jTO$bUur!~A2>Vcd?)Z6ccU$O4)?tPHaXb08uKEoY5I}(HYARJxbFm+ zlXNyVr~sm2^J4fsW60royywLjcv8@y#{v+slGT`sGY#G>IsZZeBH1K{K}6VQXd1)H zNk%x*epJCJ^*HX6Qh%s#0E${W_ig}n2hYZ)ryuFX3wQ6{z461Ht79L3e%*J&_etcl z2WL+I`Of$EZk{^!=|?9YenIZD-+ldy^v%yVkKB6c;RoNI)4sa@mdKI;Vst02IhjI{*Lx diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/four_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/four_tile.png deleted file mode 100644 index 6b65bbb01759097e615d3977c8513ab6ae1b5686..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3504 zcmd^BOK%%h6rO49v8PR&&^IkoTnh!Eq>kf9oT4~o#x}-j>?D4KI8l^d&)nM6jAz_= z#BrBM6d{oK3rM^+{0BBDY}j?ff(@c#StL*;R0+yCGj?s4mKG#dxz^mrx%YnOdC&1` zx)8m?G7BwP%QZ=z2HJ{jHIl*ExnQ6{m3qT+=PKz?!-RP-V3Iv5zoS@b3$(O)GN`PJE5&yBTDGnW&`JIjZF#YX%l%Q(t;%K-O3`Um?~9@;<|XVT#cjzAyds3cQfrw zW~rGH&E;%3zj@mvE4dumPi?jv>1;KZZLf&A>V89LEp?=gOhneRRbe)pR!eW|F}<;? z#)T59R4?lVb+g==X&_HQC{@;1ir3<)YA%-y24)r)W_m`N>DhjfVd2LxkD%d*ZS)9q zg;k0CA&#Ai-V1$ikVi-mTpp+bG`0$VuEwSfq(4&mu!<7d1?_EB+6N|X)+#$85v>E z3_>qs;4CYqg^Kw7CrTX?j)uDO|IBvRDP2{mWI;HYp)A#?p-3SRdYz~?1vuk+WNWK? zv}75IR-XZycaqzlAmrfJj1n!0j?Pr41;vgkW)Jf8hdPjU@Eui$$|Br`!YQM|5QJ_zQCTx zSm1ro;RHVqGJV2LjvPCAa#J_BoxGyqAliy5^E*Ylr(hOeXWuu@M$rgwpV=>eY{0*)f^sV9L!uond$$G7U_j?)M{GI|Dvp#qW84cgC%|EWMA z^tr(-E-F@&w47Y-)QFa$x2Rz$)byFQaf3*7+}WJ!7ms5u!Kodi?%b^)-IIL?C*yc7 zKZD=Y0PoeuY%%Ok4c;iZVxToxzyH$Umdo7fhXI@fcouH(=b-DS=JT-dBK_aVgxS+q z14qg$Ezjhj1Qn>1qPt;E6?CIX)b0{RaKv~Sd7>Ck(+d4PRE0Scil9urrbM(bYp$bz`mYlI5XA+~w z=e^b6B_HT9a86)ynB~Z@o?A+L&H)Me16d4)Qi%+Q8Inv7F|;v$mHoXy=Mh7geglu< zHHAHm97Zl)K|-ev^L>zV;E||cE?9Qtrtsp0IxHS%`mYlI5XA+~w z=e^b6B_HT9a86)ynB~}zBYxn(3dY534F?WLGo0hz(BsILu*k)j83-7*cPWHl$*Bzn Pn#bVj>gTe~DWM4fY&kQX diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/left.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/left.png deleted file mode 100644 index b28aa73f56ec0d7914b181b283e644854fcbf0dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eK!3HFi66di4DaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5hd`K7RKu$QD5&G<;uvD#pZtfPg(slk&yPY4ZqYB_zdJ|r o@c0DG$}m{fC;`F_*}ObF46b|}a#0x}wLpCgp00i_>zopr0D6xk!~g&Q diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/mine_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/mine_tile.png deleted file mode 100644 index 807c3a4e2e27c333f7067e83c186b29c0b5d35f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 281 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1enaGj@%V~BTy#>;<0Zu=8Ebnd z_ZfV+SL|w~^+hx>Ap2?BlHjG*FRfb`h1PD3Y24O-yFu#NlY7?T4W40(Z!ef~DB0?H z+b7I~;m`vGhA1T^Z5|)S3yk_aF^&Ib z?7E-K^~E~=+01JHB7q2bpDOQ7f)R-aC+|=o)FcR!YWu>O?g i{^fPaztnwPzOb0Ro+a?*gQX_W4-B5JelF{r5}E)arEBv5 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/one_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/one_tile.png deleted file mode 100644 index fd0cf3196c43542b191c6aae66deba6597562c77..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 245 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBuf-vKbiP>*~f?b|2jv*HQYbS3MJfgtE!hb&8Wzij0ft4bn z4t=W^GE8^yw)iEf)AE1g-iJ-o7z$iM3Wd|!loy>kQ}tHgg{6Di<`}jju_roF^Cj4B z9hA6!IjURoM`@O~_zcN5QI14sP1o0ou?!4JceY9;v87emC*0lpeP40>t^=ais()k% m9!krT`S`0tR=-q;=^p+d^Zn#_d zk>pP~w*!5esyA(Wo_*vBSYSOpDCPTs$y*kMZ@AW){O^>bP0l+XkK${`?Y diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/seven_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/seven_tile.png deleted file mode 100644 index 8a9035db46d12fe5152d2f9350ba946a8292acb0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 248 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBuf-vKbiP>*~g1w$Djv*HQODCV^J)*$F8oy}m332mB+_es( z>jic#R4wZ6S;{c`%t`so9G$`yS;xK4@U*WgGw$B2TXfDM`D1*Yo#xUXUj!$W|H*2O zdM(Q@JwayHylYW9jDZXcnoA>?)SA|+|G3?8;=*kqmp{|I59U~vu}rL3yfVR5R@+g< p@3@zPkkTg$*#qCtvrPKSE&f3xIn+nyvlP%_44$rjF6*2Ung9f_R-^y` diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/six_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/six_tile.png deleted file mode 100644 index 628234762be2da11fd2c1f5e6ded57df48c1ac46..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 256 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBuf-vKbiP>*~f>S+R978PpmrmZzd)R=-<)y;hZH0$VMHh%< za`ipEcY8(HEEa+OeSiKih%H&b+`mXHRQ8j4np*cNKI6li*RR-minn`z(Q&8OvfhmP zs!tX+`%iauxwWr-PP9eeXNF0wlK0JYR4dqDYpwk*!Xd7(fJ40Eajl$+c*VH~qC9#G y#tAHpF_VH1_*J>-tLkzaMeq7E^T^%fqH?R}H_fRxd@vX2Kn71&KbLh*2~7Z8{#rl) diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/three_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/three_tile.png deleted file mode 100644 index 7a993d75f8fae5c8728686942cf0fd7ea33b0d79..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 253 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBuf-vKbiP>*~f|ER5978PpmrlOOdsurWUQ wxp>cb8DEu;^OL>RtXv;IrZ>&Js$Ro*>QgZX+nbJRpz9bsUHx3vIVCg!0GOy>Q2+n{ diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/tile.png deleted file mode 100644 index a4de3c7dcde43cb4888a5f2242e7260e2f00672c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 183 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBuf-vKbiP>*~f!6|I*xtlvxKB(P&d#2<^oI<8v#nM#_62%)%3Cb|;7ih`#uBxk^`thm6 a11A3u;Y~aG7kUECW$<+Mb6Mw<&;$UZvOW+1 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/top.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/top.png deleted file mode 100644 index 3943eb87e70b1e327b175df1302b9ceb5112ee7a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~e!3HF=pW8M9DaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F52SJ!|$HeTnKtWAU7sn6_|KvaXEIc9%Y8t*~3vMtROFrJm oTd2>&%q-#T?A%_WV_?9*;5m;ovERbx3s4h-r>mdKI;Vst0Ac4OC;$Ke diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/top_left.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/top_left.png deleted file mode 100644 index 0cd76e34d7a477c445c4e6f786b371163efee92a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&k#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=Dh+L6~vJ#O${~K?6@0#}JL+-X=@kz2}zn3)-5{e=?K|L`{h^)h(6`njxgN@xNAwUH?3 diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/top_right.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/top_right.png deleted file mode 100644 index 1c84d21ff337870e5ed3af37faf45edd31ad8f6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^96-#&!3HGb=lz)rq!^2X+?^QKos)S9a~60+7BevL9Ry*<9TT(P0tIb6T^vI+f|LL7v+z_f2v0f2$)S~CQ}#xp zckO~^rf2^1?M&xb6gC~abV*37h3kNth?v-;um=B0jg5_r3_SLNyY_Fm^aE%PgQu&X J%Q~loCIE^5FvkD@ diff --git a/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/two_tile.png b/src/main/resources/assets/clientcommands/textures/gui/sprites/minesweeper/two_tile.png deleted file mode 100644 index 1ba77efba4894894d19fd480080dba1c862db40f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 255 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBuf-vKbiP>*~f>S(Q978PpmrmX&*lfV#>e|VlB{H^6X-d?K^#ys4!PC{xWt~$(696FqVuSzy diff --git a/src/main/resources/assets/clientcommands/textures/minesweeper_atlas.png b/src/main/resources/assets/clientcommands/textures/minesweeper_atlas.png new file mode 100644 index 0000000000000000000000000000000000000000..6c15f76950262cefdd83b7382b818b2c2e9f4076 GIT binary patch literal 1671 zcmV;226*|2P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1{_I5K~#8N?VG=A z97hz#Pay=s{RPe+Ad^-BAqftH{s1?U1tN_gO-5m^1knT^LF;U^gg3gBi7f~ zMbDj`ot@6v*_k+Urw!wiBv}%NR@71e_=ot=@An`4_@xYSXvIgOjXY4MGQic5aRqiy|cTN_R>3*o{OG8GmZx=GlUS5 z5kN>C5GsO?MQh~f=t%U+1J(W_P!@SCY;B#7dVsI>6t`$~@|;xsD(CX3*XIya_qqa) ze*&)YT?Q)20C4`s#)deWAIgYlQSTc0x*EV#1Y*sXO-6N&kk@*$vRJqPT%C_1P%Z>l zS6BUtLxhbmS`w5QLLjgE+!len-g7GpX93*Z-Fe&E+FGfRZ@V8*gzhoW27Llw459OT zWdQ6{`51PpT%o4`l@&4d7-%vLrhNc1;93MucK`S%s6h?D=TaF6SrV+af_V{$NQN_g zkOiQc&$Ja>gl;R=mNtxc-3qRq04^>rX0CH#Fc>`O@r@Ti$m1dYuBzY1UteE~BR{@6 zI2Ap2-v0Va=jDs7<_jR?^Q%t5ySuxc)8SB@abx${Gj9RF`S0HS+4=GNFXQ(C>dLKX zZGb~v49@qV_5w)8W22c!vgc(RGcnHQFqsRFMO!CoEr22igJcx`KK*KQDDK@6#Zy%{Gsrwm`2qAX|Ja= z6MK7mO7o$Y%|&JlMf~#evgl24sR!msa|Dn@t-Su*ED5fU&f$t000ujjTKR00eSXh^JpJVkh2+YIz@nz67^fD-9Z{PK0khK67Mbp0z z00D&X+2_x_oevr>fWJHbnFf*b`){wsksqh0{_o>)|3Wfl=y-^4I2=Aq0Z`if=dYi< zzf^+nJ@^U$_pT1(TO$BC)CEeLCIRg4?{|)mkHyg}Qw|W{th&0q%v&8Bo11xy^&8N5 z*L#V%LFjl_0W@kO=-U@tx%qN?YrpeOjwc6$f3rS}px+gVq%1HW|9i^7NiB=u=gUb( z;u%18`Zup;|1*{@18inD>@sr@q8|cSSy{=m0G;RX3_uY`H~ek>bHXRtINAASMX+kT z>~xjjTAKkvA|AlWa5hChT9xy4(9M35|C}H@f1Z>b@iMg+fGXNuK;#4YeLS7Ffs25I zun6aadC${`8UP}26#^X0BVT?WPnp102;32iaz26i<~3)dia?0q(?^fQkr}M>Nb^|p zRp2~+Z+a@=@KikSw5$Unu>JSj(kKD=pmVUT;{jju$pKY~pln(%04n$>6Hw&iybav> z1ohh>g4PRws(p%hYU#WQmGg*h=!qLu}D^-toei RVKo2%002ovPDHLkV1khl8aMy| literal 0 HcmV?d00001 From e9c09f4ef458cb7517140ba3a62288e158600b94 Mon Sep 17 00:00:00 2001 From: RTTV Date: Tue, 28 May 2024 16:36:15 -0400 Subject: [PATCH 04/11] Changes in response to review --- .../command/MinesweeperCommand.java | 498 +++++++++--------- .../assets/clientcommands/lang/en_us.json | 2 +- 2 files changed, 252 insertions(+), 248 deletions(-) diff --git a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java index f3e2f7745..18d80efa7 100644 --- a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java +++ b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java @@ -6,7 +6,6 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import net.minecraft.ChatFormatting; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; @@ -23,7 +22,7 @@ import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.*; public class MinesweeperCommand { - private static final SimpleCommandExceptionType TOO_MANY_MINES_EXCEPTION = new SimpleCommandExceptionType(Component.translatable("commands.cminesweeper.too_many_mines")); + private static final SimpleCommandExceptionType TOO_MANY_MINES_EXCEPTION = new SimpleCommandExceptionType(Component.translatable("commands.cminesweeper.tooManyMines")); public static void register(CommandDispatcher dispatcher) { dispatcher.register(literal("cminesweeper") @@ -50,299 +49,304 @@ private static int minesweeper(FabricClientCommandSource source, int width, int return Command.SINGLE_SUCCESS; } -} -class MinesweeperGameScreen extends Screen { - private static final ResourceLocation MINESWEEPER_ATLAS = new ResourceLocation("clientcommands:textures/minesweeper_atlas.png"); - - private static final Vector2i TOP_LEFT_UV = new Vector2i(0, 0); - private static final Vector2i TOP_UV = new Vector2i(12, 0); - private static final Vector2i TOP_RIGHT_UV = new Vector2i(28, 0); - private static final Vector2i LEFT_UV = new Vector2i(0, 12); - private static final Vector2i RIGHT_UV = new Vector2i(28, 12); - private static final Vector2i BOTTOM_LEFT_UV = new Vector2i(0, 28); - private static final Vector2i BOTTOM_UV = new Vector2i(12, 28); - private static final Vector2i BOTTOM_RIGHT_UV = new Vector2i(28, 28); - - private static final Vector2i NOT_A_MINE_TILE_UV = new Vector2i(68, 32); - private static final Vector2i MINE_TILE_UV = new Vector2i(52, 32); - private static final Vector2i RED_MINE_TILE_UV = new Vector2i(84, 16); - private static final Vector2i EMPTY_TILE_UV = new Vector2i(12, 12); - private static final Vector2i HOVERED_TILE_UV = new Vector2i(100, 16); - private static final Vector2i HOVERED_FLAGGED_TILE_UV = new Vector2i(36, 32); - private static final Vector2i FLAGGED_TILE_UV = new Vector2i(100, 32); - private static final Vector2i TILE_UV = new Vector2i(84, 32); - private static final Vector2i ONE_TILE_UV = new Vector2i(36, 0); - private static final Vector2i TWO_TILE_UV = new Vector2i(52, 0); - private static final Vector2i THREE_TILE_UV = new Vector2i(68, 0); - private static final Vector2i FOUR_TILE_UV = new Vector2i(84, 0); - private static final Vector2i FIVE_TILE_UV = new Vector2i(100, 0); - private static final Vector2i SIX_TILE_UV = new Vector2i(36, 16); - private static final Vector2i SEVEN_TILE_UV = new Vector2i(52, 16); - private static final Vector2i EIGHT_TILE_UV = new Vector2i(68, 16); - - int boardWidth; - int boardHeight; - int mines; - int ticksPlaying; - byte[] board; - int gameWidth; - int gameHeight; - int topLeftX; - int topLeftY; - @Nullable - Integer dragging; - @Nullable - Vector2i deathCoords; - int minesLeft; - int emptyTilesRemaining; - - MinesweeperGameScreen(int width, int height, int mines) { - super(Component.translatable("minesweeperGame.title")); - this.boardWidth = width; - this.boardHeight = height; - this.mines = mines; - this.ticksPlaying = 0; - this.board = new byte[boardWidth * boardHeight]; - this.gameWidth = boardWidth * 16 + 20; - this.gameHeight = boardHeight * 16 + 20; - this.dragging = null; - this.deathCoords = null; - this.minesLeft = mines; - this.emptyTilesRemaining = width * height - mines; - } + private static class MinesweeperGameScreen extends Screen { + private static final ResourceLocation MINESWEEPER_ATLAS = new ResourceLocation("clientcommands:textures/minesweeper_atlas.png"); + private static final int MINESWEEPER_ATLAS_WIDTH = 128; + private static final int MINESWEEPER_ATLAS_HEIGHT = 64; + + private static final Vector2i TOP_LEFT_UV = new Vector2i(0, 0); + private static final Vector2i TOP_UV = new Vector2i(12, 0); + private static final Vector2i TOP_RIGHT_UV = new Vector2i(28, 0); + private static final Vector2i LEFT_UV = new Vector2i(0, 12); + private static final Vector2i RIGHT_UV = new Vector2i(28, 12); + private static final Vector2i BOTTOM_LEFT_UV = new Vector2i(0, 28); + private static final Vector2i BOTTOM_UV = new Vector2i(12, 28); + private static final Vector2i BOTTOM_RIGHT_UV = new Vector2i(28, 28); + + private static final Vector2i NOT_A_MINE_TILE_UV = new Vector2i(68, 32); + private static final Vector2i MINE_TILE_UV = new Vector2i(52, 32); + private static final Vector2i RED_MINE_TILE_UV = new Vector2i(84, 16); + private static final Vector2i EMPTY_TILE_UV = new Vector2i(12, 12); + private static final Vector2i HOVERED_TILE_UV = new Vector2i(100, 16); + private static final Vector2i HOVERED_FLAGGED_TILE_UV = new Vector2i(36, 32); + private static final Vector2i FLAGGED_TILE_UV = new Vector2i(100, 32); + private static final Vector2i TILE_UV = new Vector2i(84, 32); + private static final Vector2i ONE_TILE_UV = new Vector2i(36, 0); + private static final Vector2i TWO_TILE_UV = new Vector2i(52, 0); + private static final Vector2i THREE_TILE_UV = new Vector2i(68, 0); + private static final Vector2i FOUR_TILE_UV = new Vector2i(84, 0); + private static final Vector2i FIVE_TILE_UV = new Vector2i(100, 0); + private static final Vector2i SIX_TILE_UV = new Vector2i(36, 16); + private static final Vector2i SEVEN_TILE_UV = new Vector2i(52, 16); + private static final Vector2i EIGHT_TILE_UV = new Vector2i(68, 16); + + private static final Random RANDOM = new Random(); + + private final int boardWidth; + private final int boardHeight; + private final int mines; + private int ticksPlaying; + private final byte[] board; + private final int gameWidth; + private final int gameHeight; + private int topLeftX; + private int topLeftY; + @Nullable + private Vector2i deathCoords; + private int minesLeft; + private int emptyTilesRemaining; + + MinesweeperGameScreen(int width, int height, int mines) { + super(Component.translatable("minesweeperGame.title")); + this.boardWidth = width; + this.boardHeight = height; + this.mines = mines; + this.ticksPlaying = 0; + this.board = new byte[boardWidth * boardHeight]; + this.gameWidth = boardWidth * 16 + 20; + this.gameHeight = boardHeight * 16 + 20; + this.deathCoords = null; + this.minesLeft = mines; + this.emptyTilesRemaining = width * height - mines; + } - @Override - protected void init() { - this.topLeftX = (this.width - gameWidth) / 2; - this.topLeftY = (this.height - gameHeight) / 2; - } + @Override + protected void init() { + this.topLeftX = (this.width - gameWidth) / 2; + this.topLeftY = (this.height - gameHeight) / 2; + } - @Override - public void render(GuiGraphics graphics, int mouseX, int mouseY, float tickDelta) { - renderBackground(graphics, mouseX, mouseY, tickDelta); + @Override + public void render(GuiGraphics graphics, int mouseX, int mouseY, float tickDelta) { + renderBackground(graphics, mouseX, mouseY, tickDelta); + + graphics.drawString(minecraft.font, "Mines Left: " + minesLeft, topLeftX, topLeftY - 10, 0xFFFFFF); + graphics.drawCenteredString(minecraft.font, title.getString(), topLeftX + gameWidth / 2, topLeftY - 20, 0xFFFFFF); + { + String str = "Time Played: " + Math.ceilDiv(ticksPlaying, 20) + "s"; + int color; + if (deathCoords != null) { + color = 0xFF5555; + } else if (emptyTilesRemaining <= 0) { + color = 0x55FF55; + } else { + color = 0xFFFFFF; + } + graphics.drawString(minecraft.font, str, topLeftX + gameWidth - minecraft.font.width(str), topLeftY - 10, color); + } - graphics.drawString(minecraft.font, "Mines Left: " + minesLeft, topLeftX, topLeftY - 10, 0xff_ffffff); - graphics.drawCenteredString(minecraft.font, title.getString(), topLeftX + gameWidth / 2, topLeftY - 20, 0xff_ffffff); - { - String str = "Time Played: " + Math.ceilDiv(ticksPlaying, 20) + "s"; - graphics.drawString(minecraft.font, str, topLeftX + gameWidth - minecraft.font.width(str), topLeftY - 10, deathCoords != null ? ChatFormatting.RED.getColor() : (emptyTilesRemaining == 0 ? ChatFormatting.GREEN.getColor() : ChatFormatting.WHITE.getColor())); - } + blitSprite(graphics, TOP_LEFT_UV, 0, 0, 12, 12); + for (int i = 0; i < boardWidth; i++) { + blitSprite(graphics, TOP_UV, 12 + i * 16, 0, 16, 12); + } + blitSprite(graphics, TOP_RIGHT_UV, 12 + boardWidth * 16, 0, 8, 12); + for (int i = 0; i < boardHeight; i++) { + blitSprite(graphics, LEFT_UV, 0, 12 + i * 16, 12, 16); + blitSprite(graphics, RIGHT_UV, 12 + boardWidth * 16, 12 + i * 16, 8, 16); + } + blitSprite(graphics, BOTTOM_LEFT_UV, 0, 12 + boardHeight * 16, 12, 8); + for (int i = 0; i < boardWidth; i++) { + blitSprite(graphics, BOTTOM_UV, 12 + i * 16, 12 + boardHeight * 16, 16, 8); + } + blitSprite(graphics, BOTTOM_RIGHT_UV, 12 + boardWidth * 16, 12 + boardHeight * 16, 8, 8); - blitSprite(graphics, TOP_LEFT_UV, 0, 0, 12, 12); - for (int i = 0; i < boardWidth; i++) { - blitSprite(graphics, TOP_UV, 12 + i * 16, 0, 16, 12); - } - blitSprite(graphics, TOP_RIGHT_UV, 12 + boardWidth * 16, 0, 8, 12); - for (int i = 0; i < boardHeight; i++) { - blitSprite(graphics, LEFT_UV, 0, 12 + i * 16, 12, 16); - blitSprite(graphics, RIGHT_UV, 12 + boardWidth * 16, 12 + i * 16, 8, 16); + for (int x = 0; x < boardWidth; x++) { + for (int y = 0; y < boardHeight; y++) { + boolean hovered = Mth.floorDiv(mouseX - topLeftX - 12, 16) == x && Mth.floorDiv(mouseY - topLeftY - 12, 16) == y; + blitSprite(graphics, getTileSprite(x, y, hovered), x * 16 + 12, y * 16 + 12, 16, 16); + } + } } - blitSprite(graphics, BOTTOM_LEFT_UV, 0, 12 + boardHeight * 16, 12, 8); - for (int i = 0; i < boardWidth; i++) { - blitSprite(graphics, BOTTOM_UV, 12 + i * 16, 12 + boardHeight * 16, 16, 8); + + public void blitSprite(GuiGraphics graphics, Vector2i uv, int x, int y, int width, int height) { + graphics.blit(MINESWEEPER_ATLAS, topLeftX + x, topLeftY + y, width, height, uv.x, uv.y, width, height, MINESWEEPER_ATLAS_WIDTH, MINESWEEPER_ATLAS_HEIGHT); } - blitSprite(graphics, BOTTOM_RIGHT_UV, 12 + boardWidth * 16, 12 + boardHeight * 16, 8, 8); - for (int x = 0; x < boardWidth; x++) { - for (int y = 0; y < boardHeight; y++) { - boolean hovered = Mth.floorDiv(mouseX - topLeftX - 12, 16) == x && Mth.floorDiv(mouseY - topLeftY - 12, 16) == y; - blitSprite(graphics, getTileSprite(x, y, hovered), x * 16 + 12, y * 16 + 12, 16, 16); + @Override + public void tick() { + if (ticksPlaying > 0 && gameActive()) { + ticksPlaying += 1; } } - } - - public void blitSprite(GuiGraphics graphics, Vector2i uv, int x, int y, int width, int height) { - graphics.blit(MINESWEEPER_ATLAS, topLeftX + x, topLeftY + y, width, height, uv.x, uv.y, width, height, 128, 64); - } - @Override - public void tick() { - if (ticksPlaying > 0 && gameActive()) { - ticksPlaying += 1; + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + return false; } - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - dragging = button; - return false; - } - @Override - public boolean mouseReleased(double mouseX, double mouseY, int button) { - dragging = null; + @Override + public boolean mouseReleased(double mouseX, double mouseY, int button) { - int tileX = Mth.floorDiv((int) (mouseX - topLeftX - 12), 16); - int tileY = Mth.floorDiv((int) (mouseY - topLeftY - 12), 16); + int tileX = Mth.floorDiv((int) (mouseX - topLeftX - 12), 16); + int tileY = Mth.floorDiv((int) (mouseY - topLeftY - 12), 16); - if (isWithinBounds(tileX, tileY) && gameActive()) { - if (button == InputConstants.MOUSE_BUTTON_LEFT) { - if (ticksPlaying == 0) { - generateMines(tileX, tileY); - ticksPlaying = 1; - } + if (isWithinBounds(tileX, tileY) && gameActive()) { + if (button == InputConstants.MOUSE_BUTTON_LEFT) { + if (ticksPlaying == 0) { + generateMines(tileX, tileY); + ticksPlaying = 1; + } - click(tileX, tileY); + click(tileX, tileY); - assert minecraft != null && minecraft.player != null; - if (emptyTilesRemaining <= 0) { - minecraft.player.playNotifySound(SoundEvents.NOTE_BLOCK_PLING.value(), SoundSource.MASTER, 1.0f, 2.0f); - } else if (deathCoords != null) { - minecraft.player.playNotifySound(SoundEvents.NOTE_BLOCK_BASS.value(), SoundSource.MASTER, 1.0f, 1.0f); + assert minecraft != null && minecraft.player != null; + if (emptyTilesRemaining <= 0) { + minecraft.player.playNotifySound(SoundEvents.NOTE_BLOCK_PLING.value(), SoundSource.MASTER, 1.0f, 2.0f); + } else if (deathCoords != null) { + minecraft.player.playNotifySound(SoundEvents.NOTE_BLOCK_BASS.value(), SoundSource.MASTER, 1.0f, 1.0f); + } + } else if (button == InputConstants.MOUSE_BUTTON_RIGHT) { + flag(tileX, tileY); } - } else if (button == InputConstants.MOUSE_BUTTON_RIGHT) { - flag(tileX, tileY); } - } - - return true; - } - private boolean gameActive() { - return deathCoords == null && emptyTilesRemaining > 0; - } + return true; + } - private void generateMines(int avoidX, int avoidY) { - Random random = new Random(); + private boolean gameActive() { + return deathCoords == null && emptyTilesRemaining > 0; + } - for (int i = 0; i < mines; i++) { - int x = random.nextInt(boardWidth); - int y = random.nextInt(boardHeight); + private void generateMines(int avoidX, int avoidY) { + for (int i = 0; i < mines; i++) { + int x = RANDOM.nextInt(boardWidth); + int y = RANDOM.nextInt(boardHeight); - // too close to the clicked position - if (Mth.abs(avoidX - x) <= 1 && Mth.abs(avoidY - y) <= 1) { - i--; - continue; - } + // too close to the clicked position + if (Mth.abs(avoidX - x) <= 1 && Mth.abs(avoidY - y) <= 1) { + i--; + continue; + } - // already a mine - if ((board[y * boardWidth + x] & 0b1100) >>> 2 == 2) { - i--; - continue; - } + // already a mine + if ((board[y * boardWidth + x] & 0b1100) >>> 2 == 2) { + i--; + continue; + } - incrementWarning(x - 1, y - 1); - incrementWarning(x, y - 1); - incrementWarning(x + 1, y - 1); + incrementWarning(x - 1, y - 1); + incrementWarning(x, y - 1); + incrementWarning(x + 1, y - 1); - incrementWarning(x - 1, y); - board[y * boardWidth + x] = 0b000_10_0_0; - incrementWarning(x + 1, y); + incrementWarning(x - 1, y); + board[y * boardWidth + x] = 0b000_10_0_0; + incrementWarning(x + 1, y); - incrementWarning(x - 1, y + 1); - incrementWarning(x, y + 1); - incrementWarning(x + 1, y + 1); + incrementWarning(x - 1, y + 1); + incrementWarning(x, y + 1); + incrementWarning(x + 1, y + 1); + } } - } - private void incrementWarning(int x, int y) { - if (isWithinBounds(x, y)) { - int idx = y * boardWidth + x; - byte original_tile = board[idx]; - if ((original_tile & 0b1100) >>> 2 == 1) { - // increment warning quantity - board[idx] += 0b0_001_00_0_0; - } else if ((original_tile & 0b1100) >>> 2 == 0) { - // set to warning tile (and since it was empty beforehand, we make it have a quantity of 1) - board[idx] = 0b0_000_01_0_0; + private void incrementWarning(int x, int y) { + if (isWithinBounds(x, y)) { + int idx = y * boardWidth + x; + byte original_tile = board[idx]; + if ((original_tile & 0b1100) >>> 2 == 1) { + // increment warning quantity + board[idx] += 0b0_001_00_0_0; + } else if ((original_tile & 0b1100) >>> 2 == 0) { + // set to warning tile (and since it was empty beforehand, we make it have a quantity of 1) + board[idx] = 0b0_000_01_0_0; + } } } - } - - private boolean isWithinBounds(int x, int y) { - return 0 <= x && x < boardWidth && 0 <= y && y < boardHeight; - } - private void click(int x, int y) { - byte tile = board[y * boardWidth + x]; - boolean flagged = (tile & 2) > 0; - boolean covered = (tile & 1) == 0; - int type = (tile & 0b1100) >>> 2; - if (!covered || flagged) { - return; + private boolean isWithinBounds(int x, int y) { + return 0 <= x && x < boardWidth && 0 <= y && y < boardHeight; } - if (type == 1) { - // set uncovered - board[y * boardWidth + x] |= 0b1; - emptyTilesRemaining -= 1; - } else if (type == 2) { - // set uncovered - board[y * boardWidth + x] |= 0b1; - deathCoords = new Vector2i(x, y); - } else { - // set uncovered - board[y * boardWidth + x] |= 0b1; - emptyTilesRemaining -= 1; - // we need to leave room for the current tile in the queue - int[] queue = new int[emptyTilesRemaining + 1]; - int queueIdx = 0; - queue[0] = y * boardWidth + x; - while (queueIdx >= 0) { - int idx = queue[queueIdx--]; - int xPart = idx % boardWidth; - int yPart = idx / boardWidth; - for (Vector2i possibleNeighbour : new Vector2i[]{ - new Vector2i(xPart - 1, yPart - 1), - new Vector2i(xPart, yPart - 1), - new Vector2i(xPart + 1, yPart - 1), - - new Vector2i(xPart - 1, yPart), - new Vector2i(xPart + 1, yPart), - - new Vector2i(xPart - 1, yPart + 1), - new Vector2i(xPart, yPart + 1), - new Vector2i(xPart + 1, yPart + 1), - }) { - if (isWithinBounds(possibleNeighbour.x, possibleNeighbour.y)) { - int pos = possibleNeighbour.y * boardWidth + possibleNeighbour.x; - byte value = board[pos]; - // set uncovered - board[pos] |= 0b1; - if ((value & 0b1) == 0) { - emptyTilesRemaining -= 1; - // if it's an empty tile, we put it in the queue to go activate all its neighbours - if ((value & 0b11_0_0) >>> 2 == 0) { - queue[++queueIdx] = pos; + private void click(int x, int y) { + byte tile = board[y * boardWidth + x]; + boolean flagged = (tile & 2) > 0; + boolean covered = (tile & 1) == 0; + int type = (tile & 0b1100) >>> 2; + if (!covered || flagged) { + return; + } + + if (type == 1) { + // set uncovered + board[y * boardWidth + x] |= 0b1; + emptyTilesRemaining -= 1; + } else if (type == 2) { + // set uncovered + board[y * boardWidth + x] |= 0b1; + deathCoords = new Vector2i(x, y); + } else { + // set uncovered + board[y * boardWidth + x] |= 0b1; + emptyTilesRemaining -= 1; + // we need to leave room for the current tile in the queue + int[] queue = new int[emptyTilesRemaining + 1]; + int queueIdx = 0; + queue[0] = y * boardWidth + x; + while (queueIdx >= 0) { + int idx = queue[queueIdx--]; + int xPart = idx % boardWidth; + int yPart = idx / boardWidth; + for (Vector2i possibleNeighbour : new Vector2i[]{ + new Vector2i(xPart - 1, yPart - 1), + new Vector2i(xPart, yPart - 1), + new Vector2i(xPart + 1, yPart - 1), + + new Vector2i(xPart - 1, yPart), + new Vector2i(xPart + 1, yPart), + + new Vector2i(xPart - 1, yPart + 1), + new Vector2i(xPart, yPart + 1), + new Vector2i(xPart + 1, yPart + 1), + }) { + if (isWithinBounds(possibleNeighbour.x, possibleNeighbour.y)) { + int pos = possibleNeighbour.y * boardWidth + possibleNeighbour.x; + byte value = board[pos]; + // set uncovered + board[pos] |= 0b1; + if ((value & 0b1) == 0) { + emptyTilesRemaining -= 1; + // if it's an empty tile, we put it in the queue to go activate all its neighbours + if ((value & 0b11_0_0) >>> 2 == 0) { + queue[++queueIdx] = pos; + } } } } } } } - } - private void flag(int x, int y) { - if ((board[y * boardWidth + x] & 0b1) > 0) { - return; + private void flag(int x, int y) { + if ((board[y * boardWidth + x] & 0b1) > 0) { + return; + } + + minesLeft -= ((board[y * boardWidth + x] ^= 0b1_0) & 0b1_0) > 0 ? 1 : -1; } - minesLeft -= ((board[y * boardWidth + x] ^= 0b1_0) & 0b1_0) > 0 ? 1 : -1; - } + private Vector2i getTileSprite(int x, int y, boolean hovered) { + byte tile = board[y * boardWidth + x]; + boolean flagged = (tile & 2) > 0; + boolean covered = (tile & 1) == 0; + int type = (tile & 0b1100) >>> 2; + int warning_quantity = (tile & 0b1110000) >>> 4; - private Vector2i getTileSprite(int x, int y, boolean hovered) { - byte tile = board[y * boardWidth + x]; - boolean flagged = (tile & 2) > 0; - boolean covered = (tile & 1) == 0; - int type = (tile & 0b1100) >>> 2; - int warning_quantity = (tile & 0b1110000) >>> 4; + if (deathCoords != null && type == 2 && !flagged) { + return new Vector2i(x, y).equals(deathCoords) ? RED_MINE_TILE_UV : MINE_TILE_UV; + } - if (deathCoords != null && type == 2 && !flagged) { - return new Vector2i(x, y).equals(deathCoords) ? RED_MINE_TILE_UV : MINE_TILE_UV; - } + if (flagged) { + return hovered && deathCoords == null ? HOVERED_FLAGGED_TILE_UV : (deathCoords != null && type != 2 ? NOT_A_MINE_TILE_UV : FLAGGED_TILE_UV); + } - if (flagged) { - return hovered && deathCoords == null ? HOVERED_FLAGGED_TILE_UV : (deathCoords != null && type != 2 ? NOT_A_MINE_TILE_UV : FLAGGED_TILE_UV); - } + if (covered) { + return hovered && deathCoords == null ? (isDragging() ? EMPTY_TILE_UV : HOVERED_TILE_UV) : TILE_UV; + } - if (covered) { - return hovered && deathCoords == null ? (dragging != null && dragging == 0 ? EMPTY_TILE_UV : HOVERED_TILE_UV) : TILE_UV; - } + if (type == 0) { + return EMPTY_TILE_UV; + } - if (type == 0) { - return EMPTY_TILE_UV; - } else { return switch (warning_quantity) { case 0 -> ONE_TILE_UV; case 1 -> TWO_TILE_UV; diff --git a/src/main/resources/assets/clientcommands/lang/en_us.json b/src/main/resources/assets/clientcommands/lang/en_us.json index 101e6de2f..706501635 100644 --- a/src/main/resources/assets/clientcommands/lang/en_us.json +++ b/src/main/resources/assets/clientcommands/lang/en_us.json @@ -157,7 +157,7 @@ "commands.clisten.list": "Listening to the following packets:", "commands.clisten.clear": "No longer listening to any packets", - "commands.cminesweeper.too_many_mines": "Too many mines, must be between 0 and 9 less than than the amount of total tiles", + "commands.cminesweeper.tooManyMines": "Too many mines, must be between 0 and 9 less than than the amount of total tiles", "commands.cplayerinfo.ioException": "An error occurred", "commands.cplayerinfo.getNameHistory.success": "%s has had the following names: %s", From 62c43d0c36c44f1a7ee0a28324e8867b24645a76 Mon Sep 17 00:00:00 2001 From: RTTV Date: Tue, 28 May 2024 18:10:13 -0400 Subject: [PATCH 05/11] Changes in response to review --- .../command/MinesweeperCommand.java | 87 ++++++++++++------- .../assets/clientcommands/lang/en_us.json | 2 + 2 files changed, 57 insertions(+), 32 deletions(-) diff --git a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java index 18d80efa7..04cc085e5 100644 --- a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java +++ b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java @@ -80,13 +80,50 @@ private static class MinesweeperGameScreen extends Screen { private static final Vector2i SIX_TILE_UV = new Vector2i(36, 16); private static final Vector2i SEVEN_TILE_UV = new Vector2i(52, 16); private static final Vector2i EIGHT_TILE_UV = new Vector2i(68, 16); - - private static final Random RANDOM = new Random(); + private static final Vector2i[] WARNING_TILE_UV = new Vector2i[] { + ONE_TILE_UV, + TWO_TILE_UV, + THREE_TILE_UV, + FOUR_TILE_UV, + FIVE_TILE_UV, + SIX_TILE_UV, + SEVEN_TILE_UV, + EIGHT_TILE_UV + }; + + private static final Random random = new Random(); private final int boardWidth; private final int boardHeight; private final int mines; private int ticksPlaying; + /** + * Each byte on the board follows a spec of what each collection of bits represents + *
+         * 0 0
+         * 
+ * These bits are unused + *

+ *

+         *      _ _ _
+         * 
+ * These bits are used to refer to the number displayed on warning tiles (technically one less): 0b000 represents a 1 tile, 0b001 represents a 2 tile, and so on. + *

+ *

+         *            _ _
+         * 
+ * These bits represent the type of tile that is there; 0b00 means an empty tile, 0b01 means a warning tile, and 0b10 means a mine. + *

+ *

+         *                _
+         * 
+ *

+ * This bit represents the flag... flag. If it is 1, the tile is flagged, if it is 0, the tile is not flagged. + *

+         *                  _
+         * 
+ * This bit represents if the tile has been uncovered, by default, all tiles are covered. + */ private final byte[] board; private final int gameWidth; private final int gameHeight; @@ -121,10 +158,10 @@ protected void init() { public void render(GuiGraphics graphics, int mouseX, int mouseY, float tickDelta) { renderBackground(graphics, mouseX, mouseY, tickDelta); - graphics.drawString(minecraft.font, "Mines Left: " + minesLeft, topLeftX, topLeftY - 10, 0xFFFFFF); + graphics.drawString(minecraft.font, Component.translatable("minesweeperGame.minesLeft").getString() + ": " + minesLeft, topLeftX, topLeftY - 10, 0xFFFFFF); graphics.drawCenteredString(minecraft.font, title.getString(), topLeftX + gameWidth / 2, topLeftY - 20, 0xFFFFFF); { - String str = "Time Played: " + Math.ceilDiv(ticksPlaying, 20) + "s"; + String str = Component.translatable("minesweeperGame.timePlayed").getString() + ": " + Math.ceilDiv(ticksPlaying, 20) + "s"; int color; if (deathCoords != null) { color = 0xFF5555; @@ -170,11 +207,6 @@ public void tick() { } } - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - return false; - } - @Override public boolean mouseReleased(double mouseX, double mouseY, int button) { @@ -210,8 +242,8 @@ private boolean gameActive() { private void generateMines(int avoidX, int avoidY) { for (int i = 0; i < mines; i++) { - int x = RANDOM.nextInt(boardWidth); - int y = RANDOM.nextInt(boardHeight); + int x = random.nextInt(boardWidth); + int y = random.nextInt(boardHeight); // too close to the clicked position if (Mth.abs(avoidX - x) <= 1 && Mth.abs(avoidY - y) <= 1) { @@ -242,11 +274,11 @@ private void generateMines(int avoidX, int avoidY) { private void incrementWarning(int x, int y) { if (isWithinBounds(x, y)) { int idx = y * boardWidth + x; - byte original_tile = board[idx]; - if ((original_tile & 0b1100) >>> 2 == 1) { + byte originalTile = board[idx]; + if ((originalTile & 0b1100) >>> 2 == 1) { // increment warning quantity board[idx] += 0b0_001_00_0_0; - } else if ((original_tile & 0b1100) >>> 2 == 0) { + } else if ((originalTile & 0b1100) >>> 2 == 0) { // set to warning tile (and since it was empty beforehand, we make it have a quantity of 1) board[idx] = 0b0_000_01_0_0; } @@ -266,11 +298,11 @@ private void click(int x, int y) { return; } - if (type == 1) { + if (type == 0b01) { // set uncovered board[y * boardWidth + x] |= 0b1; emptyTilesRemaining -= 1; - } else if (type == 2) { + } else if (type == 0b10) { // set uncovered board[y * boardWidth + x] |= 0b1; deathCoords = new Vector2i(x, y); @@ -326,37 +358,28 @@ private void flag(int x, int y) { private Vector2i getTileSprite(int x, int y, boolean hovered) { byte tile = board[y * boardWidth + x]; - boolean flagged = (tile & 2) > 0; - boolean covered = (tile & 1) == 0; + boolean flagged = (tile & 0b10) > 0; + boolean covered = (tile & 0b1) == 0; int type = (tile & 0b1100) >>> 2; - int warning_quantity = (tile & 0b1110000) >>> 4; + int warningQuantity = (tile & 0b1110000) >>> 4; - if (deathCoords != null && type == 2 && !flagged) { + if (deathCoords != null && type == 0b10 && !flagged) { return new Vector2i(x, y).equals(deathCoords) ? RED_MINE_TILE_UV : MINE_TILE_UV; } if (flagged) { - return hovered && deathCoords == null ? HOVERED_FLAGGED_TILE_UV : (deathCoords != null && type != 2 ? NOT_A_MINE_TILE_UV : FLAGGED_TILE_UV); + return hovered && deathCoords == null ? HOVERED_FLAGGED_TILE_UV : (deathCoords != null && type != 0b10 ? NOT_A_MINE_TILE_UV : FLAGGED_TILE_UV); } if (covered) { return hovered && deathCoords == null ? (isDragging() ? EMPTY_TILE_UV : HOVERED_TILE_UV) : TILE_UV; } - if (type == 0) { + if (type == 0b00) { return EMPTY_TILE_UV; } - return switch (warning_quantity) { - case 0 -> ONE_TILE_UV; - case 1 -> TWO_TILE_UV; - case 2 -> THREE_TILE_UV; - case 3 -> FOUR_TILE_UV; - case 4 -> FIVE_TILE_UV; - case 5 -> SIX_TILE_UV; - case 6 -> SEVEN_TILE_UV; - default -> EIGHT_TILE_UV; - }; + return WARNING_TILE_UV[warningQuantity]; } } } diff --git a/src/main/resources/assets/clientcommands/lang/en_us.json b/src/main/resources/assets/clientcommands/lang/en_us.json index 706501635..73d19d7b1 100644 --- a/src/main/resources/assets/clientcommands/lang/en_us.json +++ b/src/main/resources/assets/clientcommands/lang/en_us.json @@ -336,6 +336,8 @@ "snakeGame.score": "Score: %d", "minesweeperGame.title": "Minesweeper", + "minesweeperGame.timePlayed": "Time Played", + "minesweeperGame.minesLeft": "Mines Left", "c2cpacket.messageTooLong": "Message too long (max. 255 characters) got %s characters", "c2cpacket.publicKeyNotFound": "Public key not found", From ce76e5b1793d01862c04a192b689bcee3a514217 Mon Sep 17 00:00:00 2001 From: RTTV Date: Tue, 28 May 2024 22:40:36 -0400 Subject: [PATCH 06/11] Changes in response to review --- .../command/MinesweeperCommand.java | 84 ++++++++++++------- 1 file changed, 55 insertions(+), 29 deletions(-) diff --git a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java index 04cc085e5..d10b8d2ce 100644 --- a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java +++ b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java @@ -91,6 +91,10 @@ private static class MinesweeperGameScreen extends Screen { EIGHT_TILE_UV }; + private static final byte EMPTY_TILE_TYPE = 0; + private static final byte WARNING_TILE_TYPE = 1; + private static final byte MINE_TILE_TYPE = 2; + private static final Random random = new Random(); private final int boardWidth; @@ -209,7 +213,6 @@ public void tick() { @Override public boolean mouseReleased(double mouseX, double mouseY, int button) { - int tileX = Mth.floorDiv((int) (mouseX - topLeftX - 12), 16); int tileY = Mth.floorDiv((int) (mouseY - topLeftY - 12), 16); @@ -251,8 +254,7 @@ private void generateMines(int avoidX, int avoidY) { continue; } - // already a mine - if ((board[y * boardWidth + x] & 0b1100) >>> 2 == 2) { + if (tileType(getTile(x, y)) == MINE_TILE_TYPE) { i--; continue; } @@ -275,10 +277,10 @@ private void incrementWarning(int x, int y) { if (isWithinBounds(x, y)) { int idx = y * boardWidth + x; byte originalTile = board[idx]; - if ((originalTile & 0b1100) >>> 2 == 1) { + if (tileType(originalTile) == WARNING_TILE_TYPE) { // increment warning quantity board[idx] += 0b0_001_00_0_0; - } else if ((originalTile & 0b1100) >>> 2 == 0) { + } else if (tileType(originalTile) == EMPTY_TILE_TYPE) { // set to warning tile (and since it was empty beforehand, we make it have a quantity of 1) board[idx] = 0b0_000_01_0_0; } @@ -291,24 +293,19 @@ private boolean isWithinBounds(int x, int y) { private void click(int x, int y) { byte tile = board[y * boardWidth + x]; - boolean flagged = (tile & 2) > 0; - boolean covered = (tile & 1) == 0; - int type = (tile & 0b1100) >>> 2; - if (!covered || flagged) { + if (!isCovered(tile) || isFlagged(tile)) { return; } + int type = tileType(tile); if (type == 0b01) { - // set uncovered - board[y * boardWidth + x] |= 0b1; + uncover(x, y); emptyTilesRemaining -= 1; } else if (type == 0b10) { - // set uncovered - board[y * boardWidth + x] |= 0b1; + uncover(x, y); deathCoords = new Vector2i(x, y); } else { - // set uncovered - board[y * boardWidth + x] |= 0b1; + uncover(x, y); emptyTilesRemaining -= 1; // we need to leave room for the current tile in the queue int[] queue = new int[emptyTilesRemaining + 1]; @@ -332,13 +329,12 @@ private void click(int x, int y) { }) { if (isWithinBounds(possibleNeighbour.x, possibleNeighbour.y)) { int pos = possibleNeighbour.y * boardWidth + possibleNeighbour.x; - byte value = board[pos]; - // set uncovered - board[pos] |= 0b1; - if ((value & 0b1) == 0) { + byte value = getTile(possibleNeighbour.x, possibleNeighbour.y); + uncover(possibleNeighbour.x, possibleNeighbour.y); + if (isCovered(value)) { emptyTilesRemaining -= 1; // if it's an empty tile, we put it in the queue to go activate all its neighbours - if ((value & 0b11_0_0) >>> 2 == 0) { + if (tileType(value) == EMPTY_TILE_TYPE) { queue[++queueIdx] = pos; } } @@ -349,7 +345,7 @@ private void click(int x, int y) { } private void flag(int x, int y) { - if ((board[y * boardWidth + x] & 0b1) > 0) { + if (!isCovered(getTile(x, y))) { return; } @@ -357,29 +353,59 @@ private void flag(int x, int y) { } private Vector2i getTileSprite(int x, int y, boolean hovered) { - byte tile = board[y * boardWidth + x]; - boolean flagged = (tile & 0b10) > 0; - boolean covered = (tile & 0b1) == 0; - int type = (tile & 0b1100) >>> 2; - int warningQuantity = (tile & 0b1110000) >>> 4; + byte tile = getTile(x, y); + boolean flagged = isFlagged(tile); + boolean covered = isCovered(tile); + int type = tileType(tile); + int warningQuantity = warningQuantity(tile); - if (deathCoords != null && type == 0b10 && !flagged) { + if (deathCoords != null && type == MINE_TILE_TYPE && !flagged) { return new Vector2i(x, y).equals(deathCoords) ? RED_MINE_TILE_UV : MINE_TILE_UV; } if (flagged) { - return hovered && deathCoords == null ? HOVERED_FLAGGED_TILE_UV : (deathCoords != null && type != 0b10 ? NOT_A_MINE_TILE_UV : FLAGGED_TILE_UV); + return hovered && deathCoords == null ? HOVERED_FLAGGED_TILE_UV : (deathCoords != null && type != MINE_TILE_TYPE ? NOT_A_MINE_TILE_UV : FLAGGED_TILE_UV); } if (covered) { return hovered && deathCoords == null ? (isDragging() ? EMPTY_TILE_UV : HOVERED_TILE_UV) : TILE_UV; } - if (type == 0b00) { + if (type == EMPTY_TILE_TYPE) { return EMPTY_TILE_UV; } return WARNING_TILE_UV[warningQuantity]; } + + private byte getTile(int x, int y) { + return board[y * boardWidth + x]; + } + + /** + * @return 0 for an empty tile
1 for a warning tile
2 for a mine tile + */ + private int tileType(byte tile) { + return (tile & 0b1100) >>> 2; + } + + /** + * @return a value between 0 and 7 (inclusive) representing one less than the amount of mines near the tile + */ + private int warningQuantity(byte tile) { + return (tile & 0b1110000) >>> 4; + } + + private boolean isCovered(byte tile) { + return (tile & 0b1) == 0; + } + + private void uncover(int x, int y) { + board[y * boardWidth + x] |= 1; + } + + private boolean isFlagged(byte tile) { + return (tile & 0b10) > 0; + } } } From 02883490650d2cc0a22e7444f7a4647dd29ebd30 Mon Sep 17 00:00:00 2001 From: RTTV Date: Tue, 28 May 2024 22:41:58 -0400 Subject: [PATCH 07/11] forgor lol --- .../clientcommands/command/MinesweeperCommand.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java index d10b8d2ce..f86e59981 100644 --- a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java +++ b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java @@ -298,10 +298,10 @@ private void click(int x, int y) { } int type = tileType(tile); - if (type == 0b01) { + if (type == WARNING_TILE_TYPE) { uncover(x, y); emptyTilesRemaining -= 1; - } else if (type == 0b10) { + } else if (type == MINE_TILE_TYPE) { uncover(x, y); deathCoords = new Vector2i(x, y); } else { @@ -328,14 +328,13 @@ private void click(int x, int y) { new Vector2i(xPart + 1, yPart + 1), }) { if (isWithinBounds(possibleNeighbour.x, possibleNeighbour.y)) { - int pos = possibleNeighbour.y * boardWidth + possibleNeighbour.x; byte value = getTile(possibleNeighbour.x, possibleNeighbour.y); uncover(possibleNeighbour.x, possibleNeighbour.y); if (isCovered(value)) { emptyTilesRemaining -= 1; // if it's an empty tile, we put it in the queue to go activate all its neighbours if (tileType(value) == EMPTY_TILE_TYPE) { - queue[++queueIdx] = pos; + queue[++queueIdx] = possibleNeighbour.y * boardWidth + possibleNeighbour.x; } } } From d42d4a3404fe63e74a232ef6fd2a5b662c2ee0bf Mon Sep 17 00:00:00 2001 From: katie Date: Mon, 27 May 2024 15:19:20 -0400 Subject: [PATCH 08/11] Changes in response to review --- .../command/MinesweeperCommand.java | 36 +++++++++++++++---- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java index f86e59981..9a5b96f5b 100644 --- a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java +++ b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java @@ -264,7 +264,7 @@ private void generateMines(int avoidX, int avoidY) { incrementWarning(x + 1, y - 1); incrementWarning(x - 1, y); - board[y * boardWidth + x] = 0b000_10_0_0; + board[y * boardWidth + x] = createTile(false, false, MINE_TILE_TYPE, null); incrementWarning(x + 1, y); incrementWarning(x - 1, y + 1); @@ -275,14 +275,11 @@ private void generateMines(int avoidX, int avoidY) { private void incrementWarning(int x, int y) { if (isWithinBounds(x, y)) { - int idx = y * boardWidth + x; - byte originalTile = board[idx]; + byte originalTile = getTile(x, y); if (tileType(originalTile) == WARNING_TILE_TYPE) { - // increment warning quantity - board[idx] += 0b0_001_00_0_0; + setTile(x, y, createTile(isCovered(originalTile), isFlagged(originalTile), WARNING_TILE_TYPE, warningQuantity(originalTile))); } else if (tileType(originalTile) == EMPTY_TILE_TYPE) { - // set to warning tile (and since it was empty beforehand, we make it have a quantity of 1) - board[idx] = 0b0_000_01_0_0; + setTile(x, y, createTile(isCovered(originalTile), isFlagged(originalTile), WARNING_TILE_TYPE, 1)); } } } @@ -348,6 +345,7 @@ private void flag(int x, int y) { return; } + // this code flips the state of the tile's flag, and then uses a ternary statement to either subtract 1, or subtract -1 from the amount of mines left. minesLeft -= ((board[y * boardWidth + x] ^= 0b1_0) & 0b1_0) > 0 ? 1 : -1; } @@ -381,6 +379,10 @@ private byte getTile(int x, int y) { return board[y * boardWidth + x]; } + private void setTile(int x, int y, byte value) { + board[y * boardWidth + x] = value; + } + /** * @return 0 for an empty tile
1 for a warning tile
2 for a mine tile */ @@ -406,5 +408,25 @@ private void uncover(int x, int y) { private boolean isFlagged(byte tile) { return (tile & 0b10) > 0; } + + private byte createTile(boolean covered, boolean flagged, int type, @Nullable Integer warningQuantity) { + if (!covered && flagged) { + throw new IllegalArgumentException("Tile cannot be uncovered and flagged at once"); + } + + if (type == WARNING_TILE_TYPE && (warningQuantity != null && 1 <= warningQuantity && warningQuantity <= 8)) { + throw new IllegalArgumentException("Warning tiles must have a warning quantity between 0 and 8"); + } + + if (type != WARNING_TILE_TYPE && warningQuantity != null) { + throw new IllegalArgumentException("Non-Warning tiles must have a null warning quantity"); + } + + if (type != EMPTY_TILE_TYPE && type != WARNING_TILE_TYPE && type != MINE_TILE_TYPE) { + throw new IllegalArgumentException("Tile type must be empty, warning, or mine"); + } + + return (byte) ((covered ? 1 : 0) | ((flagged ? 1 : 0) << 1) | (type << 2) | ((warningQuantity == null ? 0 : warningQuantity - 1) << 4)); + } } } From 89927e47ce16b9cc29e2ed7c4a1e20c8b467ee6a Mon Sep 17 00:00:00 2001 From: katie Date: Mon, 27 May 2024 15:29:28 -0400 Subject: [PATCH 09/11] forgor --- .../clientcommands/command/MinesweeperCommand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java index 9a5b96f5b..c66cbcbf8 100644 --- a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java +++ b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java @@ -264,7 +264,7 @@ private void generateMines(int avoidX, int avoidY) { incrementWarning(x + 1, y - 1); incrementWarning(x - 1, y); - board[y * boardWidth + x] = createTile(false, false, MINE_TILE_TYPE, null); + setTile(x, y, createTile(false, false, MINE_TILE_TYPE, null)); incrementWarning(x + 1, y); incrementWarning(x - 1, y + 1); @@ -289,7 +289,7 @@ private boolean isWithinBounds(int x, int y) { } private void click(int x, int y) { - byte tile = board[y * boardWidth + x]; + byte tile = getTile(x, y); if (!isCovered(tile) || isFlagged(tile)) { return; } From 66f5908588c9487efb6bf4e67a07931bce28b0c8 Mon Sep 17 00:00:00 2001 From: katie Date: Wed, 29 May 2024 16:09:38 -0400 Subject: [PATCH 10/11] Changes in response to review --- .../clientcommands/command/MinesweeperCommand.java | 4 ++-- src/main/resources/assets/clientcommands/lang/en_us.json | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java index c66cbcbf8..a9e4e7dc6 100644 --- a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java +++ b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java @@ -162,10 +162,10 @@ protected void init() { public void render(GuiGraphics graphics, int mouseX, int mouseY, float tickDelta) { renderBackground(graphics, mouseX, mouseY, tickDelta); - graphics.drawString(minecraft.font, Component.translatable("minesweeperGame.minesLeft").getString() + ": " + minesLeft, topLeftX, topLeftY - 10, 0xFFFFFF); + graphics.drawString(minecraft.font, Component.translatable("minesweeperGame.minesLeft", minesLeft).getString(), topLeftX, topLeftY - 10, 0xFFFFFF); graphics.drawCenteredString(minecraft.font, title.getString(), topLeftX + gameWidth / 2, topLeftY - 20, 0xFFFFFF); { - String str = Component.translatable("minesweeperGame.timePlayed").getString() + ": " + Math.ceilDiv(ticksPlaying, 20) + "s"; + String str = Component.translatable("minesweeperGame.timePlayed", Math.ceilDiv(ticksPlaying, 20)).getString(); int color; if (deathCoords != null) { color = 0xFF5555; diff --git a/src/main/resources/assets/clientcommands/lang/en_us.json b/src/main/resources/assets/clientcommands/lang/en_us.json index d40a83a26..eb879e701 100644 --- a/src/main/resources/assets/clientcommands/lang/en_us.json +++ b/src/main/resources/assets/clientcommands/lang/en_us.json @@ -292,6 +292,10 @@ "itemCrack.notEnoughItems": "Unable to use RNG SeedCracker: Not Enough Items in Player Hand", + "minesweeperGame.minesLeft": "Mines Left: %d", + "minesweeperGame.timePlayed": "Time Played: %ds", + "minesweeperGame.title": "Minesweeper", + "playerManip.state": "Player Crack State: %s", "playerManip.state.uncracked": "Uncracked", "playerManip.state.cracked": "Cracked", @@ -343,10 +347,6 @@ "ticTacToeGame.noughts": "noughts (O)", "ticTacToeGame.crosses": "crosses (X)", - "minesweeperGame.title": "Minesweeper", - "minesweeperGame.timePlayed": "Time Played", - "minesweeperGame.minesLeft": "Mines Left", - "c2cpacket.messageTooLong": "Message too long (max. 255 characters) got %s characters", "c2cpacket.publicKeyNotFound": "Public key not found", "c2cpacket.encryptionFailed": "Something failed while encrypting your message", From b69176f25b8f9531c73f593327a94ebec4a7a206 Mon Sep 17 00:00:00 2001 From: RTTV Date: Wed, 29 May 2024 17:37:17 -0400 Subject: [PATCH 11/11] Changes in response to review --- .../clientcommands/command/MinesweeperCommand.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java index a9e4e7dc6..8a9d8b961 100644 --- a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java +++ b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java @@ -8,6 +8,7 @@ import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.resources.language.I18n; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvents; @@ -162,10 +163,10 @@ protected void init() { public void render(GuiGraphics graphics, int mouseX, int mouseY, float tickDelta) { renderBackground(graphics, mouseX, mouseY, tickDelta); - graphics.drawString(minecraft.font, Component.translatable("minesweeperGame.minesLeft", minesLeft).getString(), topLeftX, topLeftY - 10, 0xFFFFFF); + graphics.drawString(minecraft.font, I18n.get("minesweeperGame.minesLeft", minesLeft), topLeftX, topLeftY - 10, 0xFFFFFF); graphics.drawCenteredString(minecraft.font, title.getString(), topLeftX + gameWidth / 2, topLeftY - 20, 0xFFFFFF); { - String str = Component.translatable("minesweeperGame.timePlayed", Math.ceilDiv(ticksPlaying, 20)).getString(); + String str = I18n.get("minesweeperGame.timePlayed", Math.ceilDiv(ticksPlaying, 20)); int color; if (deathCoords != null) { color = 0xFF5555;