Skip to content

Commit

Permalink
Move stuff to random service
Browse files Browse the repository at this point in the history
  • Loading branch information
holzmaster committed Jan 23, 2025
1 parent c531e52 commit e075370
Show file tree
Hide file tree
Showing 14 changed files with 49 additions and 51 deletions.
2 changes: 1 addition & 1 deletion src/commands/boobs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { ProcessableMessage } from "@/service/command.js";
import type { MessageCommand } from "@/commands/command.js";
import * as boob from "@/storage/boob.js";
import log from "@log";
import { randomEntry } from "@/utils/arrayUtils.js";
import { randomEntry } from "@/service/random.js";

interface Booba {
description: string;
Expand Down
2 changes: 1 addition & 1 deletion src/commands/dadJoke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { ProcessableMessage } from "@/service/command.js";
import type { SpecialCommand } from "@/commands/command.js";
import type { BotContext } from "@/context.js";
import { substringAfter } from "@/utils/stringUtils.js";
import { randomEntry } from "@/utils/arrayUtils.js";
import { randomEntry } from "@/service/random.js";

type Lang = "german" | "austrian";

Expand Down
2 changes: 1 addition & 1 deletion src/commands/ficktabelle.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { MessageCommand } from "@/commands/command.js";
import type { ProcessableMessage } from "@/service/command.js";
import { randomEntry } from "@/utils/arrayUtils.js";
import { randomEntry } from "@/service/random.js";

const FICKTABELLE_URL =
"https://cdn.discordapp.com/attachments/620721921767505942/636149543154614272/20160901-164533-Kovrtep-id1487186.png";
Expand Down
2 changes: 1 addition & 1 deletion src/commands/gegenstand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import type { ApplicationCommand } from "@/commands/command.js";
import type { LootUseCommandInteraction } from "@/storage/loot.js";
import * as lootService from "@/service/loot.js";
import * as lootRoleService from "@/service/lootRoles.js";
import { randomEntry } from "@/utils/arrayUtils.js";
import { randomEntry } from "@/service/random.js";
import { ensureChatInputCommand } from "@/utils/interactionUtils.js";
import * as imageService from "@/service/image.js";

Expand Down
2 changes: 1 addition & 1 deletion src/commands/google.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
} from "discord.js";

import type { ApplicationCommand } from "@/commands/command.js";
import { randomEntry } from "@/utils/arrayUtils.js";
import { randomEntry } from "@/service/random.js";

const replies = [
"Da bitte, dein Suchergebnis, du Opfer: {0}",
Expand Down
2 changes: 1 addition & 1 deletion src/commands/metafrage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { ProcessableMessage } from "@/service/command.js";
import { parseLegacyMessageParts } from "@/service/command.js";
import { defer } from "@/utils/interactionUtils.js";

import { randomEntry } from "@/utils/arrayUtils.js";
import { randomEntry } from "@/service/random.js";

const argsConfig = {
options: {
Expand Down
2 changes: 1 addition & 1 deletion src/commands/stempeln.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {

import type { ApplicationCommand } from "@/commands/command.js";
import * as stempelService from "@/service/stempel.js";
import { randomEntry } from "@/utils/arrayUtils.js";
import { randomEntry } from "@/service/random.js";

const replies = [
"Der Bruder {0} hat den neuen Bruder {1} eingeladen und du hast dies so eben bestätigt!",
Expand Down
3 changes: 1 addition & 2 deletions src/handler/voiceHandler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import path from "node:path";
import fs from "node:fs/promises";
import { setTimeout } from "node:timers/promises";
import { readdir } from "node:fs/promises";

Expand All @@ -21,7 +20,7 @@ import * as sentry from "@sentry/bun";

import type { BotContext } from "@/context.js";

import { randomEntry } from "@/utils/arrayUtils.js";
import { randomEntry } from "@/service/random.js";
import log from "@log";

const player = createAudioPlayer();
Expand Down
2 changes: 1 addition & 1 deletion src/service/banner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as path from "node:path";
import * as fs from "node:fs/promises";

import type { BotContext } from "@/context.js";
import { randomEntry } from "@/utils/arrayUtils.js";
import { randomEntry } from "@/service/random.js";
import log from "@log";

export const rotate = async (context: BotContext) => {
Expand Down
2 changes: 1 addition & 1 deletion src/service/lootDegradation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as time from "@/utils/time.js";
import * as lootService from "@/service/loot.js";
import { LootAttributeKindId, LootKindId } from "@/service/lootData.js";
import log from "@log";
import { randomEntry } from "@/utils/arrayUtils.js";
import { randomEntry } from "@/service/random.js";

export async function degradeItems(_context: BotContext) {
log.info("Degrading loot items");
Expand Down
3 changes: 1 addition & 2 deletions src/service/lootDrop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@ import * as sentry from "@sentry/bun";

import type { BotContext } from "@/context.js";
import type { Loot, LootId } from "@/storage/db/model.js";
import { randomEntry, randomEntryWeighted } from "@/utils/arrayUtils.js";
import { randomEntry, randomEntryWeighted } from "@/service/random.js";

import * as lootService from "@/service/loot.js";
import {
LootAttributeClassId,
LootAttributeKindId,
lootAttributeTemplates,
LootKindId,
lootTemplates,
Expand Down
2 changes: 1 addition & 1 deletion src/service/nickNameRoll.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as sentry from "@sentry/bun";

import * as nickName from "@/storage/nickName.js";
import { randomEntry } from "@/utils/arrayUtils.js";
import { randomEntry } from "@/service/random.js";
import log from "@log";
import type { BotContext } from "@/context.js";

Expand Down
37 changes: 37 additions & 0 deletions src/service/random.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,40 @@ export function randomValue(range: Range): number {
const upperLimit = "maxInclusive" in range ? range.maxInclusive + 1 : range.maxExclusive;
return Math.round(range.min + Math.random() * (upperLimit - range.min));
}

export function randomEntry<T>(array: readonly T[]): T {
return array[(array.length * Math.random()) | 0];
}

export function randomEntryWeighted<T>(
array: readonly Readonly<T>[],
weights: readonly number[],
): Readonly<T> {
if (array.length === 0) {
throw new Error("Cannot select random entry from empty array");
}
if (array.length !== weights.length) {
throw new Error("Array and weights must have the same length");
}

const prefixSum = [0];
for (let i = 0; i < weights.length; ++i) {
prefixSum[i] = weights[i] + (prefixSum[i - 1] ?? 0);
}

const offset = Math.random() * prefixSum[prefixSum.length - 1];

for (let i = 0; i < array.length; ++i) {
if (prefixSum[i] > offset && weights[i] > 0) {
return array[i];
}
}

for (let i = weights.length - 1; i >= 0; --i) {
if (weights[i] > 0) {
return array[i];
}
}

throw new Error("No valid entry found");
}
37 changes: 0 additions & 37 deletions src/utils/arrayUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,43 +9,6 @@ export function chunkArray<T>(array: readonly T[], chunkSize: number): T[][] {
return result;
}

export function randomEntry<T>(array: readonly T[]): T {
return array[(array.length * Math.random()) | 0];
}

export function randomEntryWeighted<T>(
array: readonly Readonly<T>[],
weights: readonly number[],
): Readonly<T> {
if (array.length === 0) {
throw new Error("Cannot select random entry from empty array");
}
if (array.length !== weights.length) {
throw new Error("Array and weights must have the same length");
}

const prefixSum = [0];
for (let i = 0; i < weights.length; ++i) {
prefixSum[i] = weights[i] + (prefixSum[i - 1] ?? 0);
}

const offset = Math.random() * prefixSum[prefixSum.length - 1];

for (let i = 0; i < array.length; ++i) {
if (prefixSum[i] > offset && weights[i] > 0) {
return array[i];
}
}

for (let i = weights.length - 1; i >= 0; --i) {
if (weights[i] > 0) {
return array[i];
}
}

throw new Error("No valid entry found");
}

export function shuffleArray<T>(array: readonly T[], biasFn: (item: T) => number): T[] {
return array
.map((value, _idx) => ({ value, bias: biasFn(value) }))
Expand Down

0 comments on commit e075370

Please sign in to comment.