All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.janno.evaluator.dice.function.Explode Maven / Gradle / Ivy

The newest version!
package de.janno.evaluator.dice.function;

import com.google.common.collect.ImmutableList;
import de.janno.evaluator.dice.*;
import lombok.NonNull;

import java.util.Collections;
import java.util.List;
import java.util.Optional;

import static de.janno.evaluator.dice.ValidatorUtil.checkRollSize;
import static de.janno.evaluator.dice.ValidatorUtil.throwNotIntegerExpression;

public class Explode extends Function {
    public Explode(int maxNumberOfElements, boolean keepChildrenRolls) {
        super("exp", 2, 3, maxNumberOfElements, keepChildrenRolls);
    }

    @Override
    public @NonNull RollBuilder evaluate(@NonNull List arguments, @NonNull ExpressionPosition expressionPosition) throws ExpressionException {
        return new RollBuilder() {
            @Override
            public @NonNull Optional> extendRoll(@NonNull RollContext rollContext) throws ExpressionException {
                if (arguments.size() != 2 && arguments.size() != 3) {
                    throw new ExpressionException(String.format("'%s' requires 2 or 3 arguments but was %d", getName(), arguments.size()), expressionPosition);
                }
                ImmutableList.Builder allChildrenRollBuilder = ImmutableList.builder();
                ImmutableList.Builder rollExpression = ImmutableList.builder();
                RollBuilder inputRoll = arguments.getFirst();
                final List firstRoll = inputRoll.extendRoll(rollContext).orElse(Collections.emptyList());
                rollExpression.addAll(firstRoll);
                allChildrenRollBuilder.addAll(firstRoll);

                Optional> compareToRoll = arguments.get(1).extendRoll(rollContext);
                if (compareToRoll.isEmpty()) {
                    throw new ExpressionException(String.format("'%s' requires a non-empty input as second argument", expressionPosition.getValue()), expressionPosition);
                }
                checkRollSize(expressionPosition, compareToRoll.get(), 1, 1);
                Roll compareTo = compareToRoll.get().getFirst();
                allChildrenRollBuilder.add(compareTo);
                rollExpression.add(compareTo);

                final int maxNumberOfRerolls;
                if (arguments.size() == 3) {
                    Optional> maxRerollsRoll = arguments.get(2).extendRoll(rollContext);
                    if (maxRerollsRoll.isEmpty()) {
                        throw new ExpressionException(String.format("'%s' requires a non-empty input as third argument", expressionPosition.getValue()), expressionPosition);
                    }
                    checkRollSize(expressionPosition, maxRerollsRoll.get(), 1, 1);
                    Roll maxNumberOfRerollsRoll = maxRerollsRoll.get().getFirst();
                    maxNumberOfRerolls = maxNumberOfRerollsRoll.asInteger().orElseThrow(() -> throwNotIntegerExpression(expressionPosition, maxRerollsRoll.get().getFirst(), "third argument"));
                    if (maxNumberOfRerolls > 100 || maxNumberOfRerolls < 0) {
                        throw new ExpressionException(String.format("'%s' requires as third argument a number between 0 and 100", expressionPosition.getValue()), expressionPosition);
                    }
                    allChildrenRollBuilder.add(maxNumberOfRerollsRoll);
                    rollExpression.add(maxNumberOfRerollsRoll);
                } else {
                    maxNumberOfRerolls = 100;
                }

                int rerolls = 0;
                List lastRoll = firstRoll;
                ImmutableList.Builder allResultRollsBuilder = ImmutableList.builder();
                allResultRollsBuilder.addAll(firstRoll);
                while (rerolls < maxNumberOfRerolls && lastRoll.stream().flatMap(r -> r.getElements().stream()).anyMatch(compareTo::isElementsContainsElementWithValueAndTag)) {
                    lastRoll = inputRoll.extendRoll(rollContext).orElse(Collections.emptyList());
                    allResultRollsBuilder.addAll(lastRoll);
                    allChildrenRollBuilder.addAll(lastRoll);
                    rerolls++;
                }
                final ImmutableList allResultRolls = allResultRollsBuilder.build();
                return Optional.of(ImmutableList.of(new Roll(toExpression(),
                        allResultRolls.stream().flatMap(r -> r.getElements().stream()).collect(ImmutableList.toImmutableList()),
                        RandomElementsBuilder.fromRolls(allChildrenRollBuilder.build(), rollContext), allChildrenRollBuilder.build(),
                        expressionPosition,
                        maxNumberOfElements,
                        keepChildrenRolls)));
            }

            @Override
            public @NonNull String toExpression() {
                return getExpression(expressionPosition, arguments);
            }
        };

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy