diff --git a/.gitignore b/.gitignore index 277dc9b..c16f33d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -src/countries.json +src/countries.js *.swp diff --git a/Makefile b/Makefile index 0b32738..67bdd19 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ -all: src/countries.json +all: src/countries.js -src/countries.json: - python scripts/generate_countries_list.py countries/countries.json > src/countries.json +src/countries.js: + python scripts/generate_countries_list.py countries/countries.json > src/countries.js clean: - rm -rf src/countries.json + rm -rf src/countries.js diff --git a/scripts/generate_countries_list.py b/scripts/generate_countries_list.py index d2eb28c..814c133 100755 --- a/scripts/generate_countries_list.py +++ b/scripts/generate_countries_list.py @@ -21,11 +21,16 @@ def main(args): r = {} for country in countries: - if len(country['capital']) < 1 or country['capital'][0] is None: + if len(country['capital']) < 1 or country['capital'][0] == "" or not country['independent']: continue - r[country['name']['common']] = country['capital'][0] + r[country['name']['common']] = { + 'capital': country['capital'][0], + 'regions': [country['region'], + 'subregion': country['subregion'], + 'languages': country['languages'] + } - print('capitals = ', end='') + print('countries = ', end='') print(json.dumps(r)) return 0 diff --git a/src/favicon.ico b/src/favicon.ico new file mode 100644 index 0000000..c12b7c6 Binary files /dev/null and b/src/favicon.ico differ diff --git a/src/game.js b/src/game.js index e68a272..ebe7c5f 100644 --- a/src/game.js +++ b/src/game.js @@ -1,57 +1,90 @@ "use strict"; var question_list = null; -const capitals_list = Object.values(capitals); +const capitals_list = Object.values(countries).map(country => country.capital); +const regionList = [...new Set(Object.values(countries).map(country => country.region))] + .concat([...new Set(Object.values(countries).map(country => country.subregion))]); const date = new Date(); -var state = {"score": 0, "start_time": 0, "end_time": 0, "finishedGame": true}; +var selectorMatches = [] -var answersHTML = document.getElementById('answers'); -var answerAHTML = document.getElementById('answer_a'); -var answerBHTML = document.getElementById('answer_b'); -var answerCHTML = document.getElementById('answer_c'); -var answerDHTML = document.getElementById('answer_d'); -var scoreHTML = document.getElementById('score'); -var questionHTML = document.getElementById('question'); +const answersHTML = document.getElementById('answers'); +const answerAHTML = document.getElementById('answer_a'); +const answerBHTML = document.getElementById('answer_b'); +const answerCHTML = document.getElementById('answer_c'); +const answerDHTML = document.getElementById('answer_d'); +const bodyHTML = document.getElementsByTagName('body')[0] +const scoreHTML = document.getElementById('score'); +const settingsHTML = document.getElementById('settings'); +const selectorHTML = document.getElementById('region_selector'); +const selectorResultsHTML = document.getElementById('selector_results'); +const questionHTML = document.getElementById('question'); + +var state = { + "score": 0, + "max_score": 0, + "start_time": 0, + "end_time": 0, + "finishedGame": true, +}; function init() { // reset states list, score, end_time; start timer for game; - question_list = Object.keys(capitals).sort(() => Math.random()-0.5); + var regex; + if (selectorHTML.value === "") { + regex = new RegExp(".*"); + } else { + regex = new RegExp(selectorHTML.value, 'gi'); + } + question_list = Object.keys(countries) + .filter(c => countries[c].region.match(regex) || countries[c].subregion.match(regex)) + .sort(() => Math.random()-0.5); + state.maxScore = question_list.length; answersHTML.style.display = ""; + settingsHTML.style.display = "none"; state.finishedGame = false; state.score = 0; state.end_time = 0; state.start_time = date.getTime(); + questionHTML.onclick = deinit; updateState(); updateScreen(); } +function deinit() { + answersHTML.style.display = "none"; + settingsHTML.style.display = ""; + questionHTML.innerHTML = "tap here or press enter to start"; + questionHTML.onclick = init; + scoreHTML.innerHTML = "score"; +} + function updateState() { // check if game is over - if (question_list.length == 0) { - state.finishedGame = true; - return; - } + if (question_list.length == 0) { state.finishedGame = true; return; } // set up new question + console.log(1); var newQuestion = question_list.pop(); + console.log(newQuestion); + console.log(2); var options = [] while (options.length < 4) { var c = capitals_list[Math.floor(Math.random()*capitals_list.length)]; - if (c !== capitals[newQuestion] && !options.includes(c)){ + if (c !== countries[newQuestion].capital && !options.includes(c)){ options.push(c); } } console.log(options) - options[Math.floor(Math.random()*4)] = capitals[newQuestion]; + options[Math.floor(Math.random()*4)] = countries[newQuestion].capital; console.log(options) state.question = newQuestion; state.options = options; - state.answer = capitals[newQuestion]; + state.answer = countries[newQuestion].capital; } function updateScreen(){ - scoreHTML.innerHTML = state.score; + scoreHTML.innerHTML = state.score + "/" + state.maxScore; if (state.finishedGame) { questionHTML.innerHTML = "you finishedeededede!!! tap here or press space to restart"; answers.style.display = "none"; @@ -65,23 +98,70 @@ function updateScreen(){ } function processClick(answer) { + console.log("got click: " + answer); + if (state.finishedGame) return; + console.log(1); // check if answer to previous question was correct state.score += 1 ? state.options[answer] == state.answer : 0; + console.log(state.options[answer] == state.answer ? 'correct' : 'incorrect') + bodyHTML.classList.add(state.options[answer] == state.answer ? 'correct' : 'incorrect') + setTimeout(() => bodyHTML.classList = [], 200) console.log("got click: " + answer); updateState(); updateScreen(); } + +function setSelectorMatches(value){ + const regex = new RegExp(selectorHTML.value, 'gi'); + selectorMatches = regionList + .filter(region => region.match(regex)) + displaySelectorMatches(); +} + +function displaySelectorMatches(){ + selectorResultsHTML.innerHTML = selectorMatches + .map(region => { + return `
${region}
` + }) + .join(''); +} + +function setSelectorValue(value) { + selectorHTML.value = value; +} + answerAHTML.addEventListener('click', () => processClick(0)); answerBHTML.addEventListener('click', () => processClick(1)); answerCHTML.addEventListener('click', () => processClick(2)); answerDHTML.addEventListener('click', () => processClick(3)); -questionHTML.addEventListener('click', () => init()); -document.addEventListener('keydown', e => { +document.addEventListener('keyup', e => { if (e.code == "Digit1") processClick(0); if (e.code == "Digit2") processClick(1); if (e.code == "Digit3") processClick(2); if (e.code == "Digit4") processClick(3); - if (e.code == "Space") init(); + if (e.code == "Enter" && document.activeElement !== selectorHTML) init(); }); + +selectorHTML.addEventListener('change', setSelectorMatches); +selectorHTML.addEventListener('keyup', e => { + console.log(e.code); + var topResult = document.getElementsByClassName('selector_result')[0] + if (e.code == "Enter" && selectorHTML.value === "") { + init(); + return; + } + if (e.code == "Enter" && selectorHTML.value === topResult.innerHTML.trim()) { + init(); + return; + } + if (e.code == "Enter") + selectorHTML.value = topResult.innerHTML.trim(); + + setSelectorMatches(); +}); + +deinit(); +selectorHTML.focus(); +setSelectorMatches(); diff --git a/src/game_styles.css b/src/game_styles.css index 8e68664..b1ae889 100644 --- a/src/game_styles.css +++ b/src/game_styles.css @@ -6,6 +6,26 @@ --question-country-color: var(--teal); } +.correct { + animation: correct .2s; +} + +.incorrect { + animation: incorrect .2s; +} + +@keyframes correct { + 0% { background: var(--default-bg); } + 50% { background: var(--green); } + 100% { background: var(--default-bg); } +} + +@keyframes incorrect { + 0% { background: var(--default-bg); } + 50% { background: var(--red); } + 100% { background: var(--default-bg); } +} + #game #toprow { display: flex; justify-content: space-between; @@ -70,3 +90,27 @@ span#questionCountry { background-color: var(--question-country-color); } + +#settings #region_selector { + width: 100%; + max-width: 100%; + background: var(--dark-bg); + font-size: 1.5em; + padding: 1em; + border: none; + border-radius: 0.25em; + box-sizing: border-box; +} + +#settings { + width: 100% +} + +#settings #selector_results { + display: flex; + flex-wrap: wrap; +} + +#settings .selector_result { + padding: 1em; +} diff --git a/src/index.html b/src/index.html index 96e0824..c04434a 100644 --- a/src/index.html +++ b/src/index.html @@ -12,9 +12,13 @@
-

tap here or press space to start

+

you need javascript enabled to play this

score

+
- + diff --git a/src/styles.css b/src/styles.css index b6f175e..1e59a0e 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1,5 +1,6 @@ :root { --default-bg: #fefefe; + --dark-bg: #b8b8b8; --selected-bg:#383838; --default-fg: #454545; --red: #ab4642;