summaryrefslogtreecommitdiff
path: root/dice/src/main/java/bjc/dicelang/dicev2/DieMods.java
blob: 5e90aeffe2c3b3369b3f9385a6601be290727647 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package bjc.dicelang.dicev2;

import bjc.utils.data.GeneratingIterator;

import java.util.Comparator;
import java.util.Iterator;

import java.util.function.LongPredicate;
import java.util.function.LongBinaryOperator;
import java.util.function.LongUnaryOperator;

/*
 * @NOTE
 *
 * :SyntheticMod
 *
 * These mods are less efficent than if they were hard-coded, involving
 * additional function calls and object allocations. If this ends up causing
 * performance issues, replace these with custom classes.
 */

public class DieMods {
	public Die reduce(LongBinaryOperator fold, long initial, Die... dice) {
		return new ReduceDieMod(fold, initial, dice);
	}

	public Die concat(Die... dice) {
		return new ConcatDieMod(dice);
	}

	public Die counted(LongPredicate success, Die... dice) {
		return new CountDieMod(success, dice);
	}

	public Die counted(LongPredicate success, LongPredicate failure, Die... dice) {
		return new CountDieMod(success, failure, dice);
	}

	public Die explode(LongPredicate explode, Die... dice) {
		return new ExplodingDieMod(explode, dice);
	}

	public Die explode(LongPredicate explode, boolean penetrate, Die... dice) {
		return new ExplodingDieMod(explode, penetrate, dice);
	}

	public Die compound(LongPredicate compound, Die... dice) {
		return new CompoundDieMod(compound, dice);
	}

	public Die compound(LongPredicate compound, boolean penetrate, Die... dice) {
		return new CompoundDieMod(compound, penetrate, dice);
	}

	public Die pool(Die... dice) {
		return new PoolDiceMod(dice);
	}

	public Die filter(LongPredicate filter, Die... dice) {
		return new FilterDieMod(filter, dice);
	}

	public Die sort(Comparator<Long> sorter, Die die) {
		return new SortDieMod(sorter, die);
	}

	public Die map(LongUnaryOperator map, Die die) {
		return new MapDieMod(map, die);
	}

	/* :SyntheticMod */
	public Die sum(Die... dice) {
		return reduce((l, r) -> l + r, 0, dice);
	}

	/* :SyntheticMod */
	public Die subtract(Die... dice) {
		return reduce((l, r) -> l - r, 0, dice);
	}

	/* :SyntheticMod */
	public Die multiply(Die... dice) {
		return reduce((l, r) -> l * r, 1, dice);
	}

	/* :SyntheticMod */
	public Die divide(Die... dice) {
		return reduce((l, r) -> l / r, 1, dice);
	}

	/* :SyntheticMod */
	public Die ascending(Die die) {
		return new SortDieMod(Comparator.naturalOrder(), die);
	}

	/* :SyntheticMod */
	public Die descending(Die die) {
		return new SortDieMod((v1, v2) -> {
			return Long.compare(v1, v2);
		}, die);
	}

	/* :SyntheticMod */
	public Die take(int num, Die die) {
		GeneratingIterator<Integer> itr = new GeneratingIterator<>(num, (val) -> {
			return val - 1;
		}, (val) -> val == 0); 

		return filter((val) -> {
			if(itr.hasNext()) {
				itr.next();
				return true;
			}

			return false;
		}, die);
	}

	/* :SyntheticMod */
	public Die drop(int num, Die die) {
		GeneratingIterator<Integer> itr = new GeneratingIterator<>(num, (val) -> {
			return val - 1;
		}, (val) -> val == 0); 

		return filter((val) -> {
			if(itr.hasNext()) {
				itr.next();
				return false;
			}

			return true;
		}, die);
	}

	/* :SyntheticMod */
	public Die rerollOnce(LongPredicate reroll, Die die) {
		return map((val) -> {
			if(reroll.test(val)) return die.rollSingle();

			return val;
		}, die);
	}

	/* :SyntheticMod */
	public Die reroll(LongPredicate reroll, Die die) {
		return map((val) -> {
			long nVal = val;

			while(reroll.test(nVal)) {
				nVal = die.rollSingle();
			}

			return nVal;
		}, die);
	}
}