Skip to content

Commit

Permalink
ログ解析: ゲームシステムを自動で検知するように
Browse files Browse the repository at this point in the history
  • Loading branch information
cp-20 committed Jan 2, 2025
1 parent 75359b2 commit 8bb264c
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { parsers } from './messageParser';
import type { System } from './';
import { parseHtmlLog } from './htmlParser';

const shuffle = <T>(array: T[]): T[] => {
const shuffled = array.slice(); // 元の配列をコピー
for (let i = shuffled.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1)); // 0 から i のランダムなインデックス
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]; // 要素をスワップ
}
return shuffled;
};
const takeRandom = <T>(array: T[], sample: number): T[] => shuffle(array).slice(0, sample);

const memorized = new Map<string, System>();

// 与えられたメッセージからシステムを推測する
// 計算量が多いので、システム数が増えてきたら最適化が必要
// (メッセージの数が多い場合は、メッセージの一部をサンプリングして判断するなど)
export const detectSystem = (html: string): System => {
if (memorized.has(html)) {
return memorized.get(html) as System;
}

const logs = parseHtmlLog(html);
const messages = logs.map((l) => l.message);
const sampledMessages = takeRandom(messages, 100);

const scores = Object.entries(parsers)
.map(([system, parser]) => ({
system: system as System,
score: sampledMessages.filter((m) => !!parser(m)).length,
}))
.toSorted((a, b) => b.score - a.score);

memorized.set(html, scores[0].system);

return scores[0].system;
};
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export type SystemStats = {
pivots: number[];
};

const parsers: Record<System, MessageParser> = {
export const parsers: Record<System, MessageParser> = {
emoklore: emokloreParser,
CoC6th: CoC6thParser,
CoC7th: CoC7thParser,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { atom, useAtom } from 'jotai';
import { useCallback } from 'react';

const characterAtom = atom<string | undefined>(undefined);
const characterAtom = atom<string>('all');

export const useCharacterSelect = () => {
const [character, setCharacter] = useAtom(characterAtom);
Expand All @@ -13,13 +13,8 @@ export const useCharacterSelect = () => {
[setCharacter],
);

const clearCharacter = useCallback(() => {
setCharacter(undefined);
}, [setCharacter]);

return {
character,
selectCharacter,
clearCharacter,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { useCallback, useEffect } from 'react';
import { analyzeCcfoliaLog, type System, type DiceResultForCharacter } from './ccfoliaLogAnalysis';
import { round } from '@/shared/lib/round';
import { useGoogleAnalytics } from '@/shared/lib/useGoogleAnalytics';
import { useFileContent } from '@/app/[locale]/(app)/analyze-logs/_components/hooks/useFileContent';
import { useFileContent } from './useFileContent';
import { detectSystem } from './ccfoliaLogAnalysis/detector';

const resultAtom = atom<DiceResultForCharacter[]>([]);
const systemAtom = atom<System | null>(null);
Expand All @@ -12,7 +13,7 @@ export const useLogAnalysis = () => {
const { fileContent } = useFileContent();

const [result, setResult] = useAtom(resultAtom);
const [system] = useAtom(systemAtom);
const [system, setSystem] = useAtom(systemAtom);
const { sendEvent } = useGoogleAnalytics();

const analyze = useCallback(
Expand Down Expand Up @@ -44,8 +45,10 @@ export const useLogAnalysis = () => {
reset();
return;
}

setSystem(detectSystem(fileContent));
analyze(fileContent);
}, [fileContent, analyze, reset]);
}, [fileContent, analyze, reset, setSystem]);

return {
result,
Expand Down

0 comments on commit 8bb264c

Please sign in to comment.