-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
123 lines (100 loc) · 2.93 KB
/
script.js
File metadata and controls
123 lines (100 loc) · 2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
const answers = [
"Yes",
"No",
"Definitely",
"Ask again later",
"Absolutely",
"Unlikely",
"Maybe",
"It is certain",
"Very doubtful",
"Without a doubt"
];
// Memory structures
let lastAnswer = null;
const usage = {};
answers.forEach(a => usage[a] = 0);
const questionMemory = new Map();
// Normalize questions
function normalize(q) {
return q.toLowerCase().replace(/[^\w\s]/g, "").trim();
}
// Detect similarity
function areRelated(q1, q2) {
const a = normalize(q1).split(" ");
const b = normalize(q2).split(" ");
const overlap = a.filter(word => b.includes(word));
return overlap.length >= 2;
}
// Smart answer engine
function getSmartAnswer(question) {
const norm = normalize(question);
// Asked before
if (questionMemory.has(norm)) {
const previous = questionMemory.get(norm);
previous.timesAsked++;
let answer;
// Chance to change its mind
if (previous.timesAsked >= 3 && Math.random() < 0.3) {
do {
answer = answers[Math.floor(Math.random() * answers.length)];
} while (answer === previous.answer);
} else {
do {
answer = answers[Math.floor(Math.random() * answers.length)];
} while (answer === previous.answer);
}
previous.answer = answer;
usage[answer]++;
lastAnswer = answer;
return answer;
}
// Related questions
for (const [pastQ, data] of questionMemory.entries()) {
if (areRelated(norm, pastQ)) {
const answer = data.answer;
questionMemory.set(norm, { answer, timesAsked: 1 });
usage[answer]++;
lastAnswer = answer;
return answer;
}
}
// Weighted selection
const minUsage = Math.min(...Object.values(usage));
const leastUsed = answers.filter(a => usage[a] === minUsage);
let answer;
do {
answer = leastUsed[Math.floor(Math.random() * leastUsed.length)];
} while (answer === lastAnswer);
questionMemory.set(norm, { answer, timesAsked: 1 });
usage[answer]++;
lastAnswer = answer;
return answer;
}
// UI logic
const ball = document.querySelector(".eight-ball");
const inner = document.querySelector(".inner");
const answerText = document.getElementById("answerText");
const questionInput = document.getElementById("question");
const askBtn = document.getElementById("askBtn");
askBtn.addEventListener("click", () => {
const question = questionInput.value.trim();
if (!question) {
answerText.textContent = "Ask something!";
return;
}
ball.classList.remove("shake", "spin-3d");
inner.classList.remove("glow");
answerText.classList.remove("fade-in", "thinking");
void ball.offsetWidth;
ball.classList.add("shake", "spin-3d");
answerText.textContent = "Thinking...";
answerText.classList.add("thinking");
setTimeout(() => {
const smartAnswer = getSmartAnswer(question);
answerText.textContent = smartAnswer;
answerText.classList.remove("thinking");
answerText.classList.add("fade-in");
inner.classList.add("glow");
}, 1200);
});