UNPKG

4.49 kBJavaScriptView Raw
1import { assert } from "../core/util/Debug.js";
2import { clamp } from "../core/util/Math.js";
3/**
4 * Start at the first value and go up to the last
5 */
6function* upPatternGen(numValues) {
7 let index = 0;
8 while (index < numValues) {
9 index = clamp(index, 0, numValues - 1);
10 yield index;
11 index++;
12 }
13}
14/**
15 * Start at the last value and go down to 0
16 */
17function* downPatternGen(numValues) {
18 let index = numValues - 1;
19 while (index >= 0) {
20 index = clamp(index, 0, numValues - 1);
21 yield index;
22 index--;
23 }
24}
25/**
26 * Infinitely yield the generator
27 */
28function* infiniteGen(numValues, gen) {
29 while (true) {
30 yield* gen(numValues);
31 }
32}
33/**
34 * Alternate between two generators
35 */
36function* alternatingGenerator(numValues, directionUp) {
37 let index = directionUp ? 0 : numValues - 1;
38 while (true) {
39 index = clamp(index, 0, numValues - 1);
40 yield index;
41 if (directionUp) {
42 index++;
43 if (index >= numValues - 1) {
44 directionUp = false;
45 }
46 }
47 else {
48 index--;
49 if (index <= 0) {
50 directionUp = true;
51 }
52 }
53 }
54}
55/**
56 * Starting from the bottom move up 2, down 1
57 */
58function* jumpUp(numValues) {
59 let index = 0;
60 let stepIndex = 0;
61 while (index < numValues) {
62 index = clamp(index, 0, numValues - 1);
63 yield index;
64 stepIndex++;
65 index += stepIndex % 2 ? 2 : -1;
66 }
67}
68/**
69 * Starting from the top move down 2, up 1
70 */
71function* jumpDown(numValues) {
72 let index = numValues - 1;
73 let stepIndex = 0;
74 while (index >= 0) {
75 index = clamp(index, 0, numValues - 1);
76 yield index;
77 stepIndex++;
78 index += stepIndex % 2 ? -2 : 1;
79 }
80}
81/**
82 * Choose a random index each time
83 */
84function* randomGen(numValues) {
85 while (true) {
86 const randomIndex = Math.floor(Math.random() * numValues);
87 yield randomIndex;
88 }
89}
90/**
91 * Randomly go through all of the values once before choosing a new random order
92 */
93function* randomOnce(numValues) {
94 // create an array of indices
95 const copy = [];
96 for (let i = 0; i < numValues; i++) {
97 copy.push(i);
98 }
99 while (copy.length > 0) {
100 // random choose an index, and then remove it so it's not chosen again
101 const randVal = copy.splice(Math.floor(copy.length * Math.random()), 1);
102 const index = clamp(randVal[0], 0, numValues - 1);
103 yield index;
104 }
105}
106/**
107 * Randomly choose to walk up or down 1 index
108 */
109function* randomWalk(numValues) {
110 // randomly choose a starting index
111 let index = Math.floor(Math.random() * numValues);
112 while (true) {
113 if (index === 0) {
114 index++; // at bottom, so force upward step
115 }
116 else if (index === numValues - 1) {
117 index--; // at top, so force downward step
118 }
119 else if (Math.random() < 0.5) {
120 // else choose random downward or upward step
121 index--;
122 }
123 else {
124 index++;
125 }
126 yield index;
127 }
128}
129/**
130 * PatternGenerator returns a generator which will yield numbers between 0 and numValues
131 * according to the passed in pattern that can be used as indexes into an array of size numValues.
132 * @param numValues The size of the array to emit indexes for
133 * @param pattern The name of the pattern use when iterating over
134 * @param index Where to start in the offset of the values array
135 */
136export function* PatternGenerator(numValues, pattern = "up", index = 0) {
137 // safeguards
138 assert(numValues >= 1, "The number of values must be at least one");
139 switch (pattern) {
140 case "up":
141 yield* infiniteGen(numValues, upPatternGen);
142 case "down":
143 yield* infiniteGen(numValues, downPatternGen);
144 case "upDown":
145 yield* alternatingGenerator(numValues, true);
146 case "downUp":
147 yield* alternatingGenerator(numValues, false);
148 case "alternateUp":
149 yield* infiniteGen(numValues, jumpUp);
150 case "alternateDown":
151 yield* infiniteGen(numValues, jumpDown);
152 case "random":
153 yield* randomGen(numValues);
154 case "randomOnce":
155 yield* infiniteGen(numValues, randomOnce);
156 case "randomWalk":
157 yield* randomWalk(numValues);
158 }
159}
160//# sourceMappingURL=PatternGenerator.js.map
\No newline at end of file