Created
October 11, 2022 18:25
-
-
Save marko-knoebl/be724c96331899caf89ac40765bc9b02 to your computer and use it in GitHub Desktop.
Akinator project where two aspects have been extracted into separate functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* akinator.js | |
* Copyright (C) 2022 Martin Užák uzak+git@mailbox.org | |
* | |
* Distributed under terms of the MIT license. | |
*/ | |
"use strict"; | |
const prompt = require("prompt-sync")(); | |
let positiveAttrs = []; | |
let negativeAttrs = []; | |
let objects = [ | |
{ | |
name: "donkey", | |
attrs: ["animal", "grey"], | |
}, | |
{ | |
name: "horse", | |
attrs: ["animal", "fast", "big"], | |
}, | |
{ | |
name: "wolf", | |
attrs: ["animal", "carnivoure", "grey"], | |
}, | |
{ | |
name: "elephant", | |
attrs: ["animal", "grey", "big"], | |
}, | |
]; | |
while (true) { | |
// main loop | |
// filter objects | |
let matches = []; | |
for (let obj of objects) { | |
let add = true; | |
for (let posAttr of positiveAttrs) { | |
if (!obj.attrs.includes(posAttr)) { | |
add = false; | |
break; | |
} | |
} | |
for (let negAttr of negativeAttrs) { | |
if (obj.attrs.includes(negAttr)) { | |
add = false; | |
break; | |
} | |
} | |
if (add) { | |
matches.push(obj); | |
} | |
} | |
console.log(matches); | |
// TODO: ignore attributes available for all objects | |
// handle matches | |
if (matches.length === 0) { | |
console.info("I'm sorry, I've no idea what you're thinking of"); | |
} else if (matches.length === 1) { | |
console.info(`I think you were you thinking of ${matches[0].name}`); | |
break; // exit main loop | |
} else { | |
// ask another question | |
// first: find all available attributes for asking | |
let availableAttrs = []; | |
for (let match of matches) { | |
for (let attr of match.attrs) { | |
if ( | |
!positiveAttrs.includes(attr) && | |
!negativeAttrs.includes(attr) && | |
!availableAttrs.includes(attr) | |
) { | |
availableAttrs.push(attr); | |
} | |
} | |
} | |
console.log(`availableAttrs: ${availableAttrs}`); | |
if (availableAttrs.length === 0) { | |
console.error("No avail attr. This should not happen"); | |
} | |
// obtain answer | |
let attr = availableAttrs[0]; // choose attr. TODO randomly | |
let answer = promptIfInputIsValid( | |
`Is what you're thinking of '${attr}' [y/n/q-uit]: ` | |
); | |
// process answer | |
processAnswer(answer, attr); | |
} | |
} | |
/** | |
* Prompt the user for an answer. | |
* Check if the answer is "y", "n", "q". | |
* If not, ask again. | |
* Return "y" / "n" / "q" | |
*/ | |
function promptIfInputIsValid(question) { | |
let ans; | |
while (true) { | |
ans = prompt(question); | |
if (!["n", "y", "q"].includes(ans)) { | |
console.log("Please answer 'y' or 'n' or 'q'."); | |
continue; | |
} | |
break; | |
} | |
return ans; | |
} | |
function processAnswer(ans, attr) { | |
if (ans === "q") { | |
process.exit(0); | |
} else if (ans === "y") { | |
positiveAttrs.push(attr); | |
} else if (ans === "n") { | |
negativeAttrs.push(attr); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment