Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ private static int startGame(CommandContext<CommandSourceStack> context, int tea
try {
board = BingoBoard.generate(
size,
difficulty.value().number(),
difficulty.value(),
teams.size(),
RandomSource.create(seed),
gamemode::isGoalAllowed,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,42 @@
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.ComponentSerialization;
import net.minecraft.util.ExtraCodecs;
import org.jetbrains.annotations.Nullable;

import java.util.Arrays;
import java.util.List;
import java.util.NavigableSet;
import java.util.Optional;

public record BingoDifficulty(Component description, int number) {
public record BingoDifficulty(Component description, int number, @Nullable List<Float> distribution) {
public static final Codec<BingoDifficulty> CODEC = RecordCodecBuilder.create(instance ->
instance.group(
ComponentSerialization.CODEC.fieldOf("description").forGetter(BingoDifficulty::description),
ExtraCodecs.NON_NEGATIVE_INT.fieldOf("number").forGetter(BingoDifficulty::number)
ExtraCodecs.NON_NEGATIVE_INT.fieldOf("number").forGetter(BingoDifficulty::number),
Codec.FLOAT.listOf().optionalFieldOf("distribution").forGetter(dist -> Optional.ofNullable(dist.distribution))
).apply(instance, BingoDifficulty::new)
);

private BingoDifficulty(Component description, int number, Optional<List<Float>> distribution) {
this(description, number, distribution.orElse(null));
}

public BingoDifficulty(Component description, int number) {
this(description, number, Optional.empty());
}

private static List<Float> unscale5x5(int[] scaledBy5x5) {
final Float[] unscaled = new Float[scaledBy5x5.length];
for (int i = 0; i < scaledBy5x5.length; i++) {
unscaled[i] = scaledBy5x5[i] / 25f;
}
return Arrays.asList(unscaled);
}

public BingoDifficulty(Component description, int number, int[] scaledBy5x5) {
this(description, number, unscale5x5(scaledBy5x5));
}

public static NavigableSet<Integer> getNumbers(HolderLookup<BingoDifficulty> lookup) {
return lookup.listElements()
.map(Holder.Reference::value)
Expand Down
56 changes: 38 additions & 18 deletions common/src/main/java/io/github/gaming32/bingo/game/BingoBoard.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ private static BingoBoard create(PartiallyParsed parsed) {

public static BingoBoard generate(
int size,
int difficulty,
BingoDifficulty difficulty,
int teamCount,
RandomSource rand,
Predicate<GoalHolder> isAllowedGoal,
Expand Down Expand Up @@ -120,7 +120,7 @@ public static BingoBoard generate(
public static GoalHolder[] generateGoals(
HolderLookup<BingoDifficulty> difficultyLookup,
int size,
int difficulty,
BingoDifficulty difficulty,
RandomSource rand,
Predicate<GoalHolder> isAllowedGoal,
Collection<GoalHolder> requiredGoals,
Expand All @@ -142,7 +142,7 @@ public static GoalHolder[] generateGoals(
final Set<String> catalysts = new HashSet<>();

for (final var tag : excludedTags) {
tagCount.put(tag, tag.value().getMaxForDifficulty(difficulty, size));
tagCount.put(tag, tag.value().getMaxForDifficulty(difficulty.number(), size));
}

for (int i = 0; i < size * size; i++) {
Expand Down Expand Up @@ -197,7 +197,7 @@ public static GoalHolder[] generateGoals(

if (goalCandidate.goal().getTags().size() != 0) {
for (final var tag : goalCandidate.goal().getTags()) {
if (tagCount.getInt(tag) >= tag.value().getMaxForDifficulty(difficulty, size)) {
if (tagCount.getInt(tag) >= tag.value().getMaxForDifficulty(difficulty.number(), size)) {
continue goalGen;
}
}
Expand Down Expand Up @@ -263,23 +263,43 @@ private static boolean isOnSameLine(int size, int a, int b) {
return false;
}

private static int[] generateDifficulty(NavigableSet<Integer> difficulties, int size, int difficulty, RandomSource rand) {
private static int[] generateDifficulty(NavigableSet<Integer> difficulties, int size, BingoDifficulty difficulty, RandomSource rand) {
final int[] layout = new int[size * size];

final Iterator<Integer> available = difficulties.headSet(difficulty, true).descendingIterator();
if (!available.hasNext()) {
throw new IllegalArgumentException("No difficulty exists with number " + difficulty);
}
final int difficulty1 = available.next();
if (!available.hasNext()) {
Arrays.fill(layout, difficulty1);
if (difficulty.distribution() != null) {
Arrays.fill(layout, difficulty.number());
float[] cumDistribution = new float[difficulty.distribution().size()];
for (int d = 0; d < cumDistribution.length; d++) {
cumDistribution[d] = difficulty.distribution().get(d) * layout.length;
if (d > 0) {
cumDistribution[d] += cumDistribution[d - 1];
}
}
for (int i = 0; i < layout.length; ++i) {
for (int d = 0; d < cumDistribution.length; d++) {
if ((i + 1) <= cumDistribution[d]) {
layout[i] = d;
break;
}
}
}
BingoUtil.shuffle(layout, rand);
} else {
final int difficulty2 = available.next();
final int amountOf1 = rand.nextInt(size * size * 3 / 5, size * size * 3 / 5 + size);
final int[] indices = BingoUtil.shuffle(BingoUtil.generateIntArray(size * size), rand);
Arrays.fill(layout, difficulty2);
for (int i = 0; i < amountOf1; i++) {
layout[indices[i]] = difficulty1;
final Iterator<Integer> available = difficulties.headSet(difficulty.number(), true).descendingIterator();
if (!available.hasNext()) {
throw new IllegalArgumentException("No difficulty exists with number " + difficulty);
}
final int difficulty1 = available.next();
if (!available.hasNext()) {
Arrays.fill(layout, difficulty1);
} else {
final int difficulty2 = available.next();
final int amountOf1 = rand.nextInt(size * size * 3 / 5, size * size * 3 / 5 + size);
final int[] indices = BingoUtil.shuffle(BingoUtil.generateIntArray(size * size), rand);
Arrays.fill(layout, difficulty2);
for (int i = 0; i < amountOf1; i++) {
layout[indices[i]] = difficulty1;
}
}
}
return layout;
Expand Down