impr(custom text): add shuffle mode

with this, you can ensure you will encounter each word at least once
This commit is contained in:
Miodec 2024-04-27 11:43:38 +02:00
parent f541f7c579
commit 25fd805004
5 changed files with 35 additions and 10 deletions

View file

@ -430,6 +430,7 @@
<div class="buttonGroup">
<button value="simple">simple</button>
<button value="repeat">repeat</button>
<button value="shuffle">shuffle</button>
<button value="random">random</button>
</div>
</div>

View file

@ -727,6 +727,8 @@ export async function getNextWord(
(wordset.length < 4 || PractiseWords.before.mode !== null)
) {
randomWord = wordset.randomWord(funboxFrequency);
} else if (Config.mode === "custom" && CustomText.getMode() === "shuffle") {
randomWord = wordset.shuffledWord();
} else if (
Config.mode === "custom" &&
CustomText.getLimitMode() === "section"

View file

@ -1,28 +1,47 @@
import * as FunboxList from "./funbox/funbox-list";
import { dreymarIndex } from "../utils/misc";
import { randomElementFromArray } from "../utils/arrays";
import { randomElementFromArray, shuffle } from "../utils/arrays";
import Config from "../config";
let currentWordset: Wordset | null = null;
let currentWordset: MonkeyTypes.Wordset | null = null;
export class Wordset implements MonkeyTypes.Wordset {
words: string[];
length: number;
shuffledIndexes: number[];
export class Wordset {
public words: string[];
public length: number;
constructor(words: string[]) {
this.words = words;
this.length = this.words.length;
this.shuffledIndexes = [];
}
public randomWord(mode: MonkeyTypes.FunboxWordsFrequency): string {
randomWord(mode: MonkeyTypes.FunboxWordsFrequency): string {
if (mode === "zipf") {
return this.words[dreymarIndex(this.words.length)] as string;
} else {
return randomElementFromArray(this.words);
}
}
shuffledWord(): string {
if (this.shuffledIndexes.length === 0) {
this.generateShuffledIndexes();
}
return this.words[this.shuffledIndexes.pop() as number] as string;
}
generateShuffledIndexes(): void {
this.shuffledIndexes = [];
for (let i = 0; i < this.length; i++) {
this.shuffledIndexes.push(i);
}
shuffle(this.shuffledIndexes);
}
}
export async function withWords(words: string[]): Promise<Wordset> {
export async function withWords(words: string[]): Promise<MonkeyTypes.Wordset> {
const wordFunbox = FunboxList.get(Config.funbox).find(
(f) => f.functions?.withWords
);

View file

@ -109,10 +109,13 @@ declare namespace MonkeyTypes {
| `wordOrder:${FunboxWordOrder}`;
class Wordset {
public words: string[];
public length: number;
words: string[];
length: number;
shuffledIndexes: number[];
constructor(words: string[]);
randomWord(mode: MonkeyTypes.FunboxWordsFrequency): string;
shuffledWord(): string;
generateShuffledIndexes(): void;
}
class Section {

View file

@ -239,7 +239,7 @@ declare namespace SharedTypes {
hash?: string;
}
type CustomTextMode = "repeat" | "random";
type CustomTextMode = "repeat" | "random" | "shuffle";
type CustomTextLimitMode = "word" | "time" | "section";
type CustomTextLimit = {
value: number;