Skip to content

Instantly share code, notes, and snippets.

@jakwuh
Last active November 23, 2017 21:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jakwuh/f56047dfb0dc3a375a59178417a246d5 to your computer and use it in GitHub Desktop.
Save jakwuh/f56047dfb0dc3a375a59178417a246d5 to your computer and use it in GitHub Desktop.
Akinator
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Akinator</title>
</head>
<body>
<span id="question"></span>
<br>
<button id="firstButton" type="button" name="button"></button>
<button id="secondButton" type="button" name="button"></button>
<script src="./index.js" charset="utf-8"></script>
</body>
</html>
let $$question = document.querySelector('#question');
let $$firstButton = document.querySelector('#firstButton');
let $$secondButton = document.querySelector('#secondButton');
function ask(question, [first, second]) {
$$question.innerHTML = question;
$$firstButton.innerHTML = first;
$$secondButton.innerHTML = second;
return new Promise((resolve) => {
$$firstButton.onclick = () => resolve(first);
$$secondButton.onclick = () => resolve(second);
});
}
let parseFeatures = lines => {
return lines.split('\n').map(line => {
let [name, question, ...options] = line.split(';');
return {name, question, options};
}).reduce((memo, current) => {
return Object.assign(memo, {[current.name]: current});
}, {})
}
let splitConditions = conditions => conditions.split(';').reduce((memo, current) => {
let [name, answer] = current.split(' ');
return Object.assign(memo, {[name]: answer});
}, {})
let parseRules = lines => lines.split('\n').map(line => {
let [conditions, conclusion] = line.split('!');
return {
ifs: splitConditions(conditions),
thens: splitConditions(conclusion)
}
})
let featuresLines = `студент;;Андрей;Кун;Влад;Дима;Антон;Ира;Наташа;Вика;Оля;Маша
балл;Средний балл больше 7?;да;нет
работа;Человек работает?;да;нет
общага;Человек живёт в общаге?;да;нет
пол;Человек - девочка?;да;нет
стажировка;Человек уезжал на стажировку?;да;нет
успех;;да;нет`;
let rulesLines = `балл да;работа да!успех да
балл нет!успех нет
работа нет!успех нет
общага да;пол да;стажировка нет;успех да!студент Наташа
общага нет;пол да;стажировка нет;успех да!студент Маша
общага да;пол да;стажировка нет;успех нет!студент Оля
общага нет;пол да;стажировка нет;успех нет!студент Вика
общага нет;пол да;стажировка да;успех нет!студент Ира
общага да;пол нет;стажировка да;успех да!студент Дима
общага нет;пол нет;стажировка нет;успех да!студент Антон
общага нет;пол нет;стажировка да;успех да!студент Влад
общага нет;пол нет;стажировка нет;успех нет!студент Кун
общага да;пол нет;стажировка нет;успех нет!студент Андрей`;
let rules = parseRules(rulesLines);
let features = parseFeatures(featuresLines);
function log(object) {
for (let key of Object.getOwnPropertyNames(object)) {
console.log(`${key}: `, object[key]);
}
}
async function solve() {
let target = await ask('Выберите цель', ['успех', 'студент']);
let targets = [target];
let context = {};
while (targets.length) {
let currentTarget = targets[targets.length - 1];
log({targets, currentTarget, context});
if (currentTarget in context) {
targets.pop();
continue;
}
let currentRuleIndex = rules.length - 1 - rules.slice().reverse().findIndex(rule => currentTarget in rule.thens);
let currentRule = rules[currentRuleIndex];
log({currentRule});
if (!currentRule) {
let feature = features[currentTarget];
if (feature.question) {
log({feature});
context[currentTarget] = await ask(feature.question, feature.options);
} else {
break;
}
} else {
let nextTarget, isValid = true;
for (let key of Object.keys(currentRule.ifs).sort()) {
if (key in context) {
if (context[key] !== currentRule.ifs[key]) {
isValid = false;
break;
}
} else {
nextTarget = nextTarget || key;
}
}
rules.splice(currentRuleIndex, 1);
log({isValid});
if (isValid) {
if (nextTarget) {
log({nextTarget});
targets.push(nextTarget);
rules.push(currentRule);
} else {
context = Object.assign(context, currentRule.thens);
}
}
}
}
if (target in context) {
alert(`${target}: ${context[target]}`);
} else {
alert(`Couldn't find solution :(`);
}
}
solve().catch(console.error);
python -m SimpleHTTPServer 8000
# Now open localhost:8000 in a browser
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment