Skip to content

Commit

Permalink
Add JavaDocs
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinthegreat1 committed Aug 13, 2024
1 parent af03351 commit 57f8844
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,27 @@ public final class ChronomatronSolver extends ExperimentSolver {
)
);

/**
* The list of items to remember, in order.
*/
private final List<Item> chronomatronSlots = new ArrayList<>();
/**
* The index of the current item shown in the chain, used for remembering.
*/
private int chronomatronChainLengthCount;
/**
* The slot id of the current item shown, used for detecting when the experiment finishes showing the current item.
*/
private int chronomatronCurrentSlot;
/**
* The next index in the chain to click.
*/
private int chronomatronCurrentOrdinal;

public ChronomatronSolver() {
super("^Chronomatron \\(\\w+\\)$");
}

@Override
public boolean onClickSlot(int slot, ItemStack stack, int screenId) {
if (getState() == State.SHOW) {
Item item = chronomatronSlots.get(chronomatronCurrentOrdinal);
if ((stack.isOf(item) || ChronomatronSolver.TERRACOTTA_TO_GLASS.get(stack.getItem()) == item) && ++chronomatronCurrentOrdinal >= chronomatronSlots.size()) {
setState(ExperimentSolver.State.END);
}
}
return super.onClickSlot(slot, stack, screenId);
}

@Override
protected boolean isEnabled(HelperConfig.Experiments experimentsConfig) {
return experimentsConfig.enableChronomatronSolver;
Expand All @@ -57,19 +58,24 @@ protected void tick(GenericContainerScreen screen) {
switch (getState()) {
case REMEMBER -> {
Inventory inventory = screen.getScreenHandler().getInventory();
// Only try to look for items with enchantment glint if there is no item being currently shown.
if (chronomatronCurrentSlot == 0) {
for (int index = 10; index < 43; index++) {
if (inventory.getStack(index).hasGlint()) {
// If the list of items is smaller than the index of the current item shown, add the item to the list and set the state to wait.
if (chronomatronSlots.size() <= chronomatronChainLengthCount) {
chronomatronSlots.add(TERRACOTTA_TO_GLASS.get(inventory.getStack(index).getItem()));
setState(State.WAIT);
} else {
// If the item is already in the list, increment the current item shown index.
chronomatronChainLengthCount++;
}
// Remember the slot shown to detect when the experiment finishes showing the current item.
chronomatronCurrentSlot = index;
return;
}
}
// If the current item shown no longer has enchantment glint, the experiment finished showing the current item.
} else if (!inventory.getStack(chronomatronCurrentSlot).hasGlint()) {
chronomatronCurrentSlot = 0;
}
Expand All @@ -82,6 +88,7 @@ protected void tick(GenericContainerScreen screen) {
case END -> {
String name = screen.getScreenHandler().getInventory().getStack(49).getName().getString();
if (!name.startsWith("Timer: ")) {
// Get ready for another round if the instructions say to remember the pattern.
if (name.equals("Remember the pattern!")) {
chronomatronChainLengthCount = 0;
chronomatronCurrentOrdinal = 0;
Expand All @@ -94,6 +101,9 @@ protected void tick(GenericContainerScreen screen) {
}
}

/**
* Highlights the slots that contain the item at index {@link #chronomatronCurrentOrdinal} of {@link #chronomatronSlots} in the chain.
*/
@Override
public List<ColorHighlight> getColors(Int2ObjectMap<ItemStack> slots) {
List<ColorHighlight> highlights = new ArrayList<>();
Expand All @@ -110,6 +120,20 @@ public List<ColorHighlight> getColors(Int2ObjectMap<ItemStack> slots) {
return highlights;
}

/**
* Increments {@link #chronomatronCurrentOrdinal} if the item clicked matches the item at {@link #chronomatronCurrentOrdinal the current index} in the chain.
*/
@Override
public boolean onClickSlot(int slot, ItemStack stack, int screenId) {
if (getState() == State.SHOW) {
Item item = chronomatronSlots.get(chronomatronCurrentOrdinal);
if ((stack.isOf(item) || ChronomatronSolver.TERRACOTTA_TO_GLASS.get(stack.getItem()) == item) && ++chronomatronCurrentOrdinal >= chronomatronSlots.size()) {
setState(ExperimentSolver.State.END);
}
}
return super.onClickSlot(slot, stack, screenId);
}

@Override
public void reset() {
chronomatronSlots.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NotNull;

/**
* The general class for all experiment solvers, implemented with a state machine.
*/
public abstract sealed class ExperimentSolver extends SimpleContainerSolver permits ChronomatronSolver, SuperpairsSolver, UltrasequencerSolver {
public enum State {
REMEMBER, WAIT, SHOW, END
}

private State state = State.REMEMBER;
private final Int2ObjectMap<ItemStack> slots = new Int2ObjectOpenHashMap<>();

Expand Down Expand Up @@ -56,4 +55,23 @@ public void reset() {
}

protected abstract void tick(GenericContainerScreen screen);

public enum State {
/**
* The state where the player has to remember the pattern.
*/
REMEMBER,
/**
* The state where the solver has remembered the pattern and is waiting for the show state.
*/
WAIT,
/**
* The state where the player has to recall the pattern and where the solver shows the player the pattern.
*/
SHOW,
/**
* The state where the player has finished recalling the pattern and the current round is over.
*/
END
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@
import java.util.List;

public final class SuperpairsSolver extends ExperimentSolver {
/**
* The slot id of the last clicked slot.
*/
private int superpairsPrevClickedSlot = 0;
/**
* The item stack of the last clicked slot.
*/
private ItemStack superpairsCurrentSlot = ItemStack.EMPTY;
/**
* The set of slot ids that contain duplicated items.
*/
private final IntSet superpairsDuplicatedSlots = new IntArraySet(28);

@Override
public boolean onClickSlot(int slot, ItemStack stack, int screenId) {
if (getState() == State.SHOW) {
this.superpairsPrevClickedSlot = slot;
this.superpairsCurrentSlot = ItemStack.EMPTY;
}
return super.onClickSlot(slot, stack, screenId);
}

public SuperpairsSolver() {
super("^Superpairs \\(\\w+\\)$");
}
Expand All @@ -35,37 +35,45 @@ protected boolean isEnabled(HelperConfig.Experiments experimentsConfig) {
return experimentsConfig.enableSuperpairsSolver;
}

/**
* Sets the state to {@link State#SHOW} since Superpairs does not require a state machine.
* @param screen
*/
@Override
public void start(GenericContainerScreen screen) {
super.start(screen);
setState(State.SHOW);
}

@Override
public void reset() {
superpairsPrevClickedSlot = 0;
superpairsCurrentSlot = ItemStack.EMPTY;
superpairsDuplicatedSlots.clear();
}

/**
* Checks the screen if the item of the last clicked slot is unknown.
* Adds duplicated items to the item of the last clicked slot to {@link #superpairsDuplicatedSlots},
* save the item of the last clicked slot to the slot map,
* and sets {@link #superpairsCurrentSlot} to the item of the last clicked slot.
*/
@Override
protected void tick(GenericContainerScreen screen) {
if (getState() == State.SHOW && getSlots().get(superpairsPrevClickedSlot) == null) {
ItemStack itemStack = screen.getScreenHandler().getInventory().getStack(superpairsPrevClickedSlot);
if (!(itemStack.isOf(Items.CYAN_STAINED_GLASS) || itemStack.isOf(Items.BLACK_STAINED_GLASS_PANE) || itemStack.isOf(Items.AIR))) {
getSlots().int2ObjectEntrySet().stream()
.filter(entry -> ItemStack.areEqual(entry.getValue(), itemStack))
.findAny()
.ifPresent(entry -> {
superpairsDuplicatedSlots.add(entry.getIntKey());
superpairsDuplicatedSlots.add(superpairsPrevClickedSlot);
});
.filter(entry -> ItemStack.areEqual(entry.getValue(), itemStack))
.findAny()
.ifPresent(entry -> {
superpairsDuplicatedSlots.add(entry.getIntKey());
superpairsDuplicatedSlots.add(superpairsPrevClickedSlot);
});
getSlots().put(superpairsPrevClickedSlot, itemStack);
superpairsCurrentSlot = itemStack;
}
}
}

/**
* Displays a green highlight on the slot that matches {@link #superpairsCurrentSlot} and the experiment is waiting for a second click.
* Displays a yellow highlight on the slots that contain duplicated items.
* Displays a red highlight on the slots that do not match anything.
*/
@Override
public List<ColorHighlight> getColors(Int2ObjectMap<ItemStack> displaySlots) {
List<ColorHighlight> highlights = new ArrayList<>();
Expand All @@ -87,4 +95,20 @@ public List<ColorHighlight> getColors(Int2ObjectMap<ItemStack> displaySlots) {
}
return highlights;
}

@Override
public boolean onClickSlot(int slot, ItemStack stack, int screenId) {
if (getState() == State.SHOW) {
this.superpairsPrevClickedSlot = slot;
this.superpairsCurrentSlot = ItemStack.EMPTY;
}
return super.onClickSlot(slot, stack, screenId);
}

@Override
public void reset() {
superpairsPrevClickedSlot = 0;
superpairsCurrentSlot = ItemStack.EMPTY;
superpairsDuplicatedSlots.clear();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,15 @@
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;

import java.util.ArrayList;
import java.util.List;

public final class UltrasequencerSolver extends ExperimentSolver {
public static final UltrasequencerSolver INSTANCE = new UltrasequencerSolver();
/**
* The slot id of the next slot to click.
*/
private int ultrasequencerNextSlot;

@Override
public boolean onClickSlot(int slot, ItemStack stack, int screenId) {
if (getState() == State.SHOW && slot == ultrasequencerNextSlot) {
int count = getSlots().get(ultrasequencerNextSlot).getCount() + 1;
getSlots().int2ObjectEntrySet().stream()
.filter(entry -> entry.getValue().getCount() == count)
.findAny()
.map(Int2ObjectMap.Entry::getIntKey)
.ifPresentOrElse(nextSlot -> this.ultrasequencerNextSlot = nextSlot, () -> setState(ExperimentSolver.State.END));
}
return super.onClickSlot(slot, stack, screenId);
}

private UltrasequencerSolver() {
super("^Ultrasequencer \\(\\w+\\)$");
}
Expand All @@ -37,6 +26,10 @@ protected boolean isEnabled(HelperConfig.Experiments experimentsConfig) {
return experimentsConfig.enableUltrasequencerSolver;
}

/**
* Saves the shown items to {@link #slots the slot map}.
*/
@SuppressWarnings("JavadocReference")
@Override
protected void tick(GenericContainerScreen screen) {
switch (getState()) {
Expand All @@ -46,10 +39,13 @@ protected void tick(GenericContainerScreen screen) {
for (int index = 9; index < 45; index++) {
ItemStack itemStack = inventory.getStack(index);
String name = itemStack.getName().getString();
// Remember the item if its name is a number
if (name.matches("\\d+")) {
// Set the next slot to click to the item with the name "1"
if (name.equals("1")) {
ultrasequencerNextSlot = index;
}
// Save the item to the slot map
getSlots().put(index, itemStack);
}
}
Expand Down Expand Up @@ -78,6 +74,23 @@ protected void tick(GenericContainerScreen screen) {

@Override
public List<ColorHighlight> getColors(Int2ObjectMap<ItemStack> slots) {
return getState() == State.SHOW && ultrasequencerNextSlot != 0 ? List.of(ColorHighlight.green(ultrasequencerNextSlot)) : new ArrayList<>();
return getState() == State.SHOW && ultrasequencerNextSlot != 0 ? List.of(ColorHighlight.green(ultrasequencerNextSlot)) : List.of();
}

/**
* Finds the next slot to click via searching for the item stack count in {@link #slots the slot map} and sets {@link #ultrasequencerNextSlot} if the current slot was clicked.
*/
@SuppressWarnings("JavadocReference")
@Override
public boolean onClickSlot(int slot, ItemStack stack, int screenId) {
if (getState() == State.SHOW && slot == ultrasequencerNextSlot) {
int count = getSlots().get(ultrasequencerNextSlot).getCount() + 1;
getSlots().int2ObjectEntrySet().stream()
.filter(entry -> entry.getValue().getCount() == count)
.findAny()
.map(Int2ObjectMap.Entry::getIntKey)
.ifPresentOrElse(nextSlot -> this.ultrasequencerNextSlot = nextSlot, () -> setState(ExperimentSolver.State.END));
}
return super.onClickSlot(slot, stack, screenId);
}
}

0 comments on commit 57f8844

Please sign in to comment.