added zipf funbox

This commit is contained in:
Miodec 2023-02-21 13:14:36 +01:00
parent e36c57c047
commit 6ed5a9422d
9 changed files with 78 additions and 10 deletions

View file

@ -123,6 +123,10 @@ const Funboxes: Record<string, MonkeyTypes.FunboxMetadata> = {
canGetPb: false,
difficultyLevel: 1,
},
zipf: {
canGetPb: false,
difficultyLevel: 1,
},
};
export default Funboxes;

View file

@ -214,6 +214,12 @@ const list: MonkeyTypes.FunboxMetadata[] = [
punctuation: [false],
},
},
{
name: "zipf",
alias: "frequency",
info: "Words are generated according to Zipf's law. (not all languages will produce Zipfy results, use with caution)",
properties: ["changesWordsFrequency"],
},
];
export function getAll(): MonkeyTypes.FunboxMetadata[] {

View file

@ -98,7 +98,8 @@ export function canSetConfigWithCurrentFunboxes(
f.properties?.find((fp) => fp.startsWith("toPush:")) ||
f.properties?.includes("changesWordsVisibility") ||
f.properties?.includes("speaks") ||
f.properties?.includes("changesLayout")
f.properties?.includes("changesLayout") ||
f.properties?.includes("changesWordsFrequency")
)
);
}
@ -108,7 +109,8 @@ export function canSetConfigWithCurrentFunboxes(
(f) =>
f.functions?.getWord ||
f.functions?.pullSection ||
f.functions?.withWords
f.functions?.withWords ||
f.properties?.includes("changesWordsFrequency")
)
);
}
@ -222,6 +224,17 @@ export function areFunboxesCompatible(
funboxesToCheck.filter((f) =>
f.properties?.find((fp) => fp == "changesWordsVisibility")
).length <= 1;
const oneFrequencyChangesMax =
funboxesToCheck.filter((f) =>
f.properties?.find((fp) => fp == "changesWordsFrequency")
).length <= 1;
const noFrequencyChangesConflicts =
funboxesToCheck.filter((f) =>
f.properties?.find((fp) => fp == "changesWordsFrequency")
).length == 0 ||
funboxesToCheck.filter((f) =>
f.properties?.find((fp) => fp == "ignoresLanguage")
).length == 0;
const capitalisationChangePosibility =
funboxesToCheck.filter((f) => f.properties?.find((fp) => fp == "noLetters"))
.length == 0 ||
@ -284,6 +297,8 @@ export function areFunboxesCompatible(
layoutUsability &&
oneNospaceOrToPushMax &&
oneChangesWordsVisibilityMax &&
oneFrequencyChangesMax &&
noFrequencyChangesConflicts &&
capitalisationChangePosibility &&
noConflictsWithSymmetricChars &&
canSpeak &&

View file

@ -526,6 +526,12 @@ FunboxList.setFunboxFunctions("binary", {
},
});
FunboxList.setFunboxFunctions("zipf", {
getWordsFrequencyMode(): MonkeyTypes.FunboxWordsFrequency {
return "zipf";
},
});
export function toggleScript(...params: string[]): void {
FunboxList.get(Config.funbox).forEach((funbox) => {
if (funbox.functions?.toggleScript) funbox.functions.toggleScript(params);

View file

@ -677,6 +677,18 @@ export function restart(options = {} as RestartOptions): void {
);
}
function getFunboxWordsFrequency():
| MonkeyTypes.FunboxWordsFrequency
| undefined {
const wordFunbox = FunboxList.get(Config.funbox).find(
(f) => f.functions?.getWordsFrequencyMode
);
if (wordFunbox?.functions?.getWordsFrequencyMode) {
return wordFunbox.functions.getWordsFrequencyMode();
}
return undefined;
}
function getFunboxWord(word: string, wordset?: Misc.Wordset): string {
const wordFunbox = FunboxList.get(Config.funbox).find(
(f) => f.functions?.getWord
@ -718,7 +730,9 @@ async function getNextWord(
language: MonkeyTypes.LanguageObject,
wordsBound: number
): Promise<string> {
let randomWord = wordset.randomWord();
const funboxFrequency = getFunboxWordsFrequency() ?? "normal";
let randomWord = wordset.randomWord(funboxFrequency);
const previousWord = TestWords.words.get(TestWords.words.length - 1, true);
const previousWord2 = TestWords.words.get(TestWords.words.length - 2, true);
if (Config.mode === "quote") {
@ -735,7 +749,7 @@ async function getNextWord(
(CustomText.isWordRandom || CustomText.isTimeRandom) &&
(wordset.length < 4 || PractiseWords.before.mode !== null)
) {
randomWord = wordset.randomWord();
randomWord = wordset.randomWord(funboxFrequency);
} else {
let regenarationCount = 0; //infinite loop emergency stop button
while (
@ -754,12 +768,12 @@ async function getNextWord(
/[0-9]/i.test(randomWord)))
) {
regenarationCount++;
randomWord = wordset.randomWord();
randomWord = wordset.randomWord(funboxFrequency);
}
}
if (randomWord === undefined) {
randomWord = wordset.randomWord();
randomWord = wordset.randomWord(funboxFrequency);
}
if (

View file

@ -63,7 +63,7 @@ export function getWord(wordset: Wordset): string {
let highScore;
let randomWord = "";
for (let i = 0; i < wordSamples; i++) {
const newWord = wordset.randomWord();
const newWord = wordset.randomWord("normal");
const newScore = score(newWord);
if (i == 0 || highScore === undefined || newScore > highScore) {
randomWord = newWord;

View file

@ -187,6 +187,8 @@ declare namespace MonkeyTypes {
display?: string;
}
type FunboxWordsFrequency = "normal" | "zipf";
type FunboxProperty =
| "symmetricChars"
| "conflictsWithSymmetricChars"
@ -202,7 +204,8 @@ declare namespace MonkeyTypes {
| "changesCapitalisation"
| "nospace"
| `toPush:${number}`
| "noInfiniteDuration";
| "noInfiniteDuration"
| "changesWordsFrequency";
interface FunboxFunctions {
getWord?: (wordset?: Misc.Wordset) => string;
@ -227,6 +230,7 @@ declare namespace MonkeyTypes {
start?: () => void;
restart?: () => void;
getWordHtml?: (char: string, letterTag?: boolean) => string;
getWordsFrequencyMode?: () => FunboxWordsFrequency;
}
interface FunboxForcedConfig {

View file

@ -1309,8 +1309,12 @@ export class Wordset {
this.length = this.words.length;
}
public randomWord(): string {
return randomElementFromArray(this.words);
public randomWord(mode: MonkeyTypes.FunboxWordsFrequency): string {
if (mode === "zipf") {
return this.words[dreymarIndex(this.words.length)];
} else {
return randomElementFromArray(this.words);
}
}
}
@ -1388,3 +1392,13 @@ export function getBinary(): string {
const ret = Math.floor(Math.random() * 256).toString(2);
return ret.padStart(8, "0");
}
export function dreymarIndex(arrayLength: number): number {
const n = arrayLength;
const g = 0.5772156649;
const M = Math.log(n) + g;
const r = Math.random();
const h = Math.exp(r * M - g);
const W = Math.ceil(h);
return W - 1;
}

View file

@ -155,5 +155,10 @@
"name": "binary",
"info": "01000010 01100101 01100101 01110000 00100000 01100010 01101111 01101111 01110000 00101110",
"canGetPb": false
},
{
"name": "zipf",
"info": "Words are generated according to Zipf's law. (not all languages will produce Zipfy results, use with caution)",
"canGetPb": false
}
]