Javascript object oriented pirate translator - javascript

I need to make an object oriented pirate translator in javascript for my final, I have an idea and have some code but can't get it to output correctly on my page. I have it set up so you type the english phrase in one box and then in the other box it spits out the pirate version. I will not step through my array of objects. I will post code. Thanks for any help I can get!!!
var $ = function(id) { return document.getElementById(id); }
var Dictionary = [{
Greetings: {
hello:"ahoy",
hi:"yohoho",
pardon_me:"avast",
excuse_me:"arrr"
},
People: {
stranger:"scurvy",
sir:"matey",
madam:"proud beauty",
miss:"comely wench",
officer:"foul blaggart",
enemy:"scallywag"
},
Questions: {
where_is:"whar be",
can_you_help_me_find:"know ye",
is_that:"be that",
how_far_is_it_to:"how many leagues to"
},
Articles: {
the:"th",
a:"a briny",
any:"some godforsaken",
nearby:"broadside",
my:"me",
your:"yer"
},
Adjectives: {
old:"barnacle-covered",
attractive:"comely",
happy:"grog-filled"
},
Places: {
restroom:"head",
restaurant:"galley",
hotel:"fleabag inn",
mall:"market",
pub:"Skull & Scuppers",
bank:"buried trasure"
},
Desires: {
I_would_like_to:"I be needin to",
I_desire:"I have a fierce fire in me belly",
I_wish_I_knew_how_to:"I be hankerin to",
my_mother_told_me_to:"me dear ol mum, bless her black soul, tol me to",
my_companion_would_like_to:"me mate, ol Rumpot, wants to"
},
Actions: {
find:"come across",
take_a_nap:"have a bit of a lie down",
make_a_withdrawal:"seize all yer doubloons",
have_a_cocktail:"swill a pint or two of grog",
kill_him:"blow the man down",
frown:"hang the jib",
take_a_hike:"walk the plank"
},
}];
function Translate(text)
// Returns: a copy of text with English phrases replaced by piratey equivalents
{
for (var i = 0; i < Dictionary.length; i++) {
var toReplace = new RegExp("\\b"+Dictionary[i][0]+"\\b", "i");
var index = text.search(toReplace);
while (index != -1) {
text = text.replace(toReplace, Dictionary[x][y]);
index = text.search(toReplace);
}
}
text = text.replace(/\./g, function() {
return Math.random() < 0.5 ? ". arrrrrrrrr" : "."
});
return text.charAt(0).toUpperCase() + text.substring(1);
}
var clear_click = function() {
$("output1").value = "";
$("output2").value = "";
}
window.onload = function() {
$("clear").onclick = clear_click;
}
/*for (var x in Dictionary) {
for (var y in Dictionary[x])
console.log (y, Dictionary[x][y]);
}*/
HTML:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title> Pirate Translator </title>
<script src="js/test2.js"></script>
<link rel="stylesheet" href="css/normalize.css"/>
<link rel="stylesheet" href="css/styles.css"/>
</head>
<body>
<h1>Jacob's Pirate Translator</h1>
<p>Simply click on the buttons to translate<br />
words and/or phrases from English to pirate talk.
<hr />
<form name="TalkForm">
<table>
<tr><td align="center"><b>English</b>
<td>
<td align="center"><b>Pirate</b>
<tr><td><textarea name="English" id="output1" rows=12 cols=35 wrap="virtual"></textarea> </td>
<td align="center"> <br />
<input type="button" value="Translate --->"
onclick="document.TalkForm.Pirate.value =
Translate(document.TalkForm.English.value);"> </td>
<td><textarea name="Pirate" id="output2" rows=12 cols=35 wrap="virtual"></textarea> </td>
<input type="button" id="clear" value="clear">
</tr>
</table>
</form>
</body>
</html>

EDIT2: I've modified your Dictionary. If you follow the format of my Dictionary you can go as deep of arrays as you want. It should work. I've tested with your examples in all different kinds of orders and with text not found in the dictionary. Feel free to try it out.
And to add to the challenge, I made recursive functions. :D No for/while loops.
DEMO
var Dictionary = {
hello: "ahoy",
hi: "yohoho",
pardon: [1, {
me: "avast"
}],
excuse: [1, {
me: "arrr"
}],
stranger: "scurvy",
sir: "matey",
madam: "proud beauty",
miss: "comely wench",
officer: "foul blaggart",
enemy: "scallywag",
where: [1, {
is: "whar be"
}],
can: [4, {
you_help_me_find: "know ye"
}],
is: [1, {
that: "be that"
}],
how: [4, {
far_is_it_to: "how many leagues to"
}],
the: "th",
a: "a briny",
any: "some godforsaken",
nearby: "broadside",
my: "me",
your: "yer",
old: "barnacle-covered",
attractive: "comely",
happy: "grog-filled",
restroom: "head",
restaurant: "galley",
hotel: "fleabag inn",
mall: "market",
pub: "Skull & Scuppers",
bank: "buried trasure",
would: [1, {
like: "be needin"
}],
I: [
[1, {
desire: "I have a fierce fire in me belly"
}],
[5, {
wish_I_knew_how_to: "I be hankerin to"
}]
],
my: [
[4, {
mother_told_me_to: "me dear ol mum, bless her black soul, tol me to"
}],
[4, {
companion_would_like_to: "me mate, ol Rumpot, wants to"
}]
],
find: "come across",
take: [2, {
a_nap: "have a bit of a lie down"
}],
make: [2, {
a_withdrawal: "seize all yer doubloons"
}],
have: [2, {
a_cocktail: "swill a pint or two of grog"
}],
kill: [1, {
him: "blow the man down"
}],
frown: "hang the jib",
take: [2, {
a_hike: "walk the plank"
}]
};
function translate(text) {
var hop = 1;
var textToReturn = "";
//checking if the text is already split, if not we split
if (typeof text === 'string') {
text = text.split(' ');
}
if (text.length > 0) {
if (typeof Dictionary[text[0]] == 'undefined' || typeof Dictionary[text[0]] === 'string') {
textToReturn = (Dictionary[text[0]] || text[0]);
text = text.slice(hop, text.length);
} else {
var info = recursiveCheck(text, Dictionary[text[0]]);
textToReturn = (info.hop == 1) ? text[0] : info.text;
text = text.splice(info.hop, text.length);
}
if(text.length > 0)
{
textToReturn += ' ' + translate(text);
}
}
return textToReturn;
}
function recursiveCheck(text, arr)
{
var found = {hop:1, text: ''};
if(arr.length > 0)
{
if(typeof parseInt(arr[0]) === 'number' && text.length-1 >= arr[0])
{
var phrase = text.slice(1, arr[0]+1);
if(arr[1][phrase.join('_')])
{
found.hop = arr[0]+1;
found.text = arr[1][phrase.join('_')];
}
}
else
{
found = recursiveCheck(text, arr[0] || []);
if(found.hop == 1 && arr.length > 1)
{
found = recursiveCheck(text, arr.slice(1, arr.length));
}
}
}
return found;
}
var tra = document.getElementById('translate');
var pir = document.getElementById('pirate');
pir.disabled = true;
var eng = document.getElementById('english');
eng.onkeyup = function(){
pir.value = "";
}
tra.onclick = function () {
pir.value = translate(eng.value);
};
HERE is an example of a deep array if you want to go further with the dictionary:
...
I: [
[1, {
desire: [
[1,{ a: "I have a fierce fire in me belly"}],
[1,{ one: "I have one fierce fire in me belly"}]
}],
[5, {
wish_I_knew_how_to: "I be hankerin to"
}]
],
...
Of course I haven't tried it yet, but you can if you actually need it to work. Good luck.
EDIT: The point of this code is to show how to access your list. You don't seem to be using categories in your code, so why have them?
Your list looks a bit complex for a simple translation. Last I checked, dictionaries don't have categories.. Joke aside I've simplified your list.
var Dictionary = {
hello:"ahoy",
hi:"yohoho",
pardon_me:"avast",
excuse_me:"arrr",
stranger:"scurvy",
sir:"matey",
madam:"proud beauty",
miss:"comely wench",
officer:"foul blaggart",
enemy:"scallywag",
where_is:"whar be",
can_you_help_me_find:"know ye",
is_that:"be that",
how_far_is_it_to:"how many leagues to",
the:"th",
a:"a briny",
any:"some godforsaken",
nearby:"broadside",
my:"me",
your:"yer",
old:"barnacle-covered",
attractive:"comely",
happy:"grog-filled",
restroom:"head",
restaurant:"galley",
hotel:"fleabag inn",
mall:"market",
pub:"Skull & Scuppers",
bank:"buried trasure",
I_would_like_to:"I be needin to",
I_desire:"I have a fierce fire in me belly",
I_wish_I_knew_how_to:"I be hankerin to",
my_mother_told_me_to:"me dear ol mum, bless her black soul, tol me to",
my_companion_would_like_to:"me mate, ol Rumpot, wants to",
find:"come across",
take_a_nap:"have a bit of a lie down",
make_a_withdrawal:"seize all yer doubloons",
have_a_cocktail:"swill a pint or two of grog",
kill_him:"blow the man down",
frown:"hang the jib",
take_a_hike:"walk the plank"
};
function translate(text)
{
pir.value = Dictionary[text.split(' ').join('_')] || 'not found';
}
var tra = document.getElementById('translate');
var pir = document.getElementById('pirate');
pir.disabled = true;
var eng = document.getElementById('english');
tra.onclick = function(){ translate(eng.value) };
html:
<input id="english" type="text" placeholder="english"/>
<input id="pirate" placeholder="pirate"/>
<button id="translate">Translate</button>
I've simplified the code (by a lot) so I could get a simple working model.
Working jsfiddle: http://jsfiddle.net/Grimbode/f296h/2/

Related

My javascript code for mapping splits the word by character and doesn't read the whole word in input

I am creating a type of translator in which user enters a specific alphanumeric character or word and the translator shows a pre-defined output against it.
Example:
If someone enters capital A,
it outputs Apple
This works for single character input but if I map a whole word to be replaced with another word, my code is not working properly.
Here is my code:
Input field:
output.innerHTML=finalText.trim()}var outHtml='<div class="text-detail"><div class="row element-inner single-element"><div class="col-md-11 col-10 position-initial heading-main"><div class="font-style-name"><span>Cirlce Outline Text</span></div></div><div class="col-md-1 col-2 button-main"><button class="ml-auto copy-btn btn_cpy col-md-1 col-12 button_copy integration-checklist__copy-button" data-clipboard-text="'+applyCharMap(Ahmad,text)+'" data-clipboard-action="copy"><i class="fas fa-copy"></i>COPY</button></div><div class="col-md-12 col-12 position-initial text-area-outer"><div class="font-pre col-md-12 col-12 signature text-area-inner"><textarea class="text-area-main">'+applyCharMap(Ahmad,text)+'</textarea></div></div></div></div>';output.innerHTML=outHtml}
Code that splits the characters:
function applyCharMap(map, text) {
var out = "";
var _iteratorNormalCompletion = !0;
var _didIteratorError = !1;
var _iteratorError = undefined;
try {
for (var _iterator = text.split("")[Symbol.iterator](), _step;
!(_iteratorNormalCompletion = (_step = _iterator.next()).done);
_iteratorNormalCompletion = !0) {
var c = _step.value;
if (map[c] !== undefined) out += map[c];
else if (map[c.toLowerCase()] !== undefined) out += map[c.toLowerCase()];
else out += c
}
} catch (err) {
_didIteratorError = !0;
_iteratorError = err
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return()
}
} finally {
if (_didIteratorError) {
throw _iteratorError
}
}
}
return out
}
What I want to achieve (first is input and after ":" is output
var Ahmad = {
"you": "yaseelf",
"I": "meseelf",
"to": "yagatue",
"the": "dee",
"a": "nako",
"and": "alakahso",
"that": "dat",
"it": "dating",
"of": "anaufo",
"me": "da-mee",
"what": "waah",
"is": "ugataku",
"in": "uginoko",
"this": "dees",
"know": "ka-noe",
"I'm": "meselpa",
"for": "gafor",
"no": "refuso",
"have": "hanave",
"my": "itake",
"don't": "refusio",
"just": "Kunusti",
"not": "refinaki",
"not": "refinaki",
"do": "gajadoo",
"be": "ukoh",
"on": "skino",
"your": "giorza",
"was": "dasava",
"we": "garnatoupe",
"it's": "itajon",
"with": "witaki",
"so": "yasio",
"but": "bahut",
"all": "alli",
"well": "vaheil",
"are": "majare",
"he": "erono",
"oh": "eeono",
"about": "hajabon",
"right": "gaso",
"you're": "nuer",
"get": "kles"
};
So what will happen is when someone enters "you", it should output "yaseelf"
But, currently it just shows the output for each character instead of the whole replacement.
Hope experts can help solve this problem.
P.S. Similar code example can be found here
Regards,
Ahmad
Well, there are built in functions to split characters and words. You're re-inventing the wheel. Your example doesn't seem complete or at least is hard to work with, so I made a simplified version that should get you going. It uses split and join.
let translator = {
"you": "yaseelf",
"I": "meseelf",
"to": "yagatue",
"the": "dee"
};
var button = document.querySelector('#button');
var input = document.querySelector('#input');
var output = document.querySelector('#output');
button.addEventListener('click', () => {
let words = input.value.split(' ');
let translated = words.map(word => translator[word] || word);
output.innerHTML = translated.join(' ');
})
<input id='input' type=text value='Lets go to the park' />
<button id='button'>translate</button>
<div id='output'></div>

How to display a result in .innerHTML from a chosen answer in an object

I want to make a website which asks some questions and then will generate 3 random locations based on the users answers. The part I am struggling with is getting the end result to output the locations based on the first question in the object which is:
const questions = [
{
"question": "What area of the world are you thinking of discovering next?",
"answer1": "Europe",
"answer1Array": "europeArray",
"answer2": "Asia",
"answer2Array": "asiaArray",
"answer3": "America",
"answer3Array": "americaArray",
"answer4": "Australasia",
"answer4Array": "australasiaArray"
},
let europeArray1 = ['Algarve - Portugal', 'Asturias and Covadonga - Spain', 'Mdina & Zebbug - Malta']
let asiaArray1 = ['Yakushima Island - Japan', 'Mount Wudang Shan - China', 'Bantayan Island - Philippines'] etc...
I have then created a function to give me back a random location:
let finalEuropeArray1 = europeArray1.sort(function() {
return 0.5 - Math.random();
});
and finally a function to output 3 results
function randomHoliday (array) {
if (array == europeArray1) {
return finalEuropeArray1.slice(europeArray1,3);
} else if (array == americaArray1) {
return finalAmericaArray1.slice(americaArray1,3);
} else if (array == asiaArray1 {
return finalAsiaArray1.slice(asiaArray1,3);
} else {
return finalAustralasiaArray1.slice(australasiaArray1,3);
}
I am able to return 3 separate values with a function calling the first element in each:
let resultA = function seperateArrayA (randomHoliday) {
return `1. ${randomHoliday[0]}`;}
let resultB = function seperateArrayB (randomHoliday) {
return `2. ${randomHoliday[1]}`;}
let resultC = function seperateArrayC (randomHoliday) {
return `3. ${randomHoliday[2]}`;}
but I do not know how to output this in my final .innerHTML based on the first question in the questions object. I can only get it to work by putting in a manual entry e.g. ${resultA(australasiaArray1)}
if(currentQuestion == totalQuestions) {
container.style.display = 'none';
result.innerHTML =
`<h1 class="final-score">Our Top 3 Recommendations:</h1>
<div class="summary">
<p><br></br></p>
<p>${resultA(australasiaArray1)}</p>
<p>${resultB(australasiaArray1)}</p>
<p>${resultC(australasiaArray1)}</p>
</div>
<button class="restart">Restart Quiz</button>
`
};
The setup can be simplified by using nested objects for related answers, checkout the demo below:
const questions = [
{
"question": "What area of the world are you thinking of discovering next?",
"answers": {
"Europe": {
"label": "Europe",
"locations": ['Algarve - Portugal', 'Asturias and Covadonga - Spain', 'Mdina & Zebbug - Malta']
},
"Asia": {
"label": "Asia",
"locations": ['Yakushima Island - Japan', 'Mount Wudang Shan - China', 'Bantayan Island - Philippines']
}
}
}
];
let getRandomLocationForAnswer = function (question, answer) {;
const possibleLocations = question.answers[answer].locations;
const randomIndex = Math.floor((Math.random()*possibleLocations.length));
return possibleLocations[randomIndex];
}
let buildSelect = function(questions){
return questions.map((question, index) => {
const possibleAnswers = Object.keys(question.answers);
return`<select class="question" data-question-index="${index}">${possibleAnswers.map(l => `<option value="${l}">${l}</option>`)}</select>`;
}).join('');
}
let showResults = function(questions, questionIndex, answer){
const question = questions[questionIndex];
document.querySelector('#results').innerHTML =
`<h1 class="final-score">Our Top 3 Recommendations:</h1>
<div class="summary">
<p><br></br></p>
<p>${getRandomLocationForAnswer(question, answer)}</p>
<p>${getRandomLocationForAnswer(question, answer)}</p>
<p>${getRandomLocationForAnswer(question, answer)}</p>
</div>
<button class="restart">Restart Quiz</button>
`
}
document.querySelector('#questions').innerHTML += buildSelect(questions);
document.querySelectorAll('.question').forEach(question => {
question.addEventListener('change', e => {
const select = e.currentTarget;
showResults(questions, parseInt(select.dataset.questionIndex), select.value);
});
});
<section id="questions">
</section>
<section id="results">
</section>
resultA, resultB, resultC are functions, not values. if you put them in the template you will get a function reference and not the result of the function. To get the result you need to call the function(which you do in the last code snippet).
in order to get it to work simply define variables and set them to the function result:
if(currentQuestion == totalQuestions) {
container.style.display = 'none';
var l_resultA = resultA(australasiaArray1)
...
result.innerHTML =
`<h1 class="final-score">Our Top 3 Recommendations:</h1>
<div class="summary">
<p><br></br></p>
<p>${l_resultA}</p>
....
</div>
<button class="restart">Restart Quiz</button>`
};

Getting the value of "on" for radio buttons

var allQuestions = [{
question1: "What is 1 + 1?",
choices: ["1", "2", "3", 4],
correctAnswer: ["2"]
}, {
question2: "What is 2 + 2?",
choices: ["6", "2", "3", 4, ],
correctAnswer: ["4"]
}, {
question3: "What is 3 + 3?",
choices: ["3", "6", "9", 12],
correctAnswer: ["6"]
}];
var newArray = shuffleArray(allQuestions);
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
function appendQuestions(number) {
if (newArray == "undefined" || newArray == "null" || newArray.length == 0) {
document.getElementById("questionForm").innerHTML = "Complete!";
} else {
for (i = 0; i < 4; i++) {
$("#questionForm").append("<input name='question' type='radio'>" +
JSON.stringify(newArray[0].choices[i]) + "</input>")
}
}
}
$(function() {
$("#questionList").empty();
appendQuestions();
newArray.shift();
})
function isCorrectAnswer() {
checkedVal = $("input[type=radio][name=question]:checked").val();
if (checkedVal == newArray[0].correctAnswer) {
alert("Correct!");
} else {
alert("Wrong!");
}
alert(checkedVal);
}
$("#submitButton").click(function() {
isCorrectAnswer();
$("#questionForm").empty();
appendQuestions();
newArray.shift();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='container'>
<section id='questions'>
<form id="questionForm">
</form>
<div style='clear:both'></div>
<input id='submitButton' type='button' value='Submit'>
</section>
</div>
First off, sorry for the amount of code pasted. I have no idea if I'm missing some small bug or if I'm just writing the wrong code, so I figured it would be best to post all of it.
I am trying to get the value of a radio button. In the isCorrectAnswer function the first 2 lines are to determine the value of the radio button that is currently checked. The problem is when I alert the value of the radio button, it just says "on". I have searched for the last hour trying to figure out what this means or how to fix it and could not find a thing.
I apologize if this is a stupid question or if it has already been answered.
You have to change this line :
$("#questionForm").append("<input name='question' type='radio'>" +
JSON.stringify(newArray[0].choices[i]) + "</input>");
To :
$("#questionForm").append("<input name='question' type='radio' value='" +
JSON.stringify(newArray[0].correctAnswer[i]) + "' />"+JSON.stringify(newArray[0].choices[i]));
Hope this helps.

How can I merge an Array with an object in javascript

I'm having an array of object
var todos= [
{
id: 1,
name: test,
description: test
}
]
How can I insert an object with properties stored in different variable say
var newTodos={id:2,name:test2,description:test2,purpose:NA}
so that the final arrray looks like
var todos=
[
{
id: 1,
name: test,
description: test
},
id: 2,
name: test2,
description: test2,
purpose: NA
]
var todos= [
{
id: 1,
name: test,
description: test
}
]
var newTodos={id:2,name:test2,description:test2,purpose:NA};
todos.push(newTodos);
The answer you accepted is the right answer to the wrong question.
If you really want to add the properties of newTodos (which is misnamed; it is just a single todo) then you can do what the answer says, or more easily, just do
$.extend (todos, newTodos);
_.extend (todos, newTodos);
Object.assign(todos, newTodos);
or use your other favorite property merging utility.
However, I cannot imagine what you are going to usefully do with such a mutant object, which is an array with a single element which is a todo, and now is sort of a todo itself with the todo properties directly on it.
I'm guessing that what you want to do is add another todo to your array of todos, in which case as others have suggested you can just push it.
todos.push(newTodos)
If you actually mean newTodos to be an array of todos, as its name suggests, in other words, if its format is actually
var newTodos = [ {id:2,name:test2,description:test2,purpose:NA}, ... ];
Then to add it to todos you would concatenate:
todos = todos.concat(newTodos);
This is how you do it:
for (var index in newTodos) {
todos[index] = newTodos[index];
}
You can check the values of your array like this:
for (var index in todos) {
console.log(index + ": " + todos[index]);
}
EDIT: In conform with the asked fiddle, I add the fiddle and code:
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title> - jsFiddle demo</title>
<script type="text/javascript" src="/js/lib/dummy.js"></script>
<link rel="stylesheet" type="text/css" href="/css/result-light.css">
<style type="text/css">
</style>
<script type="text/javascript">//<![CDATA[
var VanillaRunOnDomReady = function() {
var todos= [
{
id: 1,
name: 'test',
description: 'test'
}
];
var newTodos={id:2,name:'test2',description:'test2',purpose:'NA'};
for (var index in newTodos) {
todos[index] = newTodos[index];
}
var output = "";
for (var index in todos) {
if (typeof todos[index] === "object") {
output += index + ": {";
var first = true;
for (var innerIndex in todos[index]) {
if (!first) {
output += ", ";
} else {
first = false;
}
output += innerIndex + ": " + todos[index][innerIndex];
}
output += "}<br>";
} else {
output += index + ": " + todos[index] + "<br>";
}
}
document.getElementById("output").innerHTML = output;
}
var alreadyrunflag = 0;
if (document.addEventListener)
document.addEventListener("DOMContentLoaded", function(){
alreadyrunflag=1;
VanillaRunOnDomReady();
}, false);
else if (document.all && !window.opera) {
document.write('<script type="text/javascript" id="contentloadtag" defer="defer" src="javascript:void(0)"><\/script>');
var contentloadtag = document.getElementById("contentloadtag")
contentloadtag.onreadystatechange=function(){
if (this.readyState=="complete"){
alreadyrunflag=1;
VanillaRunOnDomReady();
}
}
}
window.onload = function(){
setTimeout("if (!alreadyrunflag){VanillaRunOnDomReady}", 0);
}//]]>
</script>
</head>
<body>
<div id="output">a</div>
</body></html>

HTML Javascript Self-assessment quiz/questionnaire

Hi so i got a very basic JavaScript HTML quiz working, however what i want to end up with is an assessment type quiz that has lets say 15 questions based on 3 categories (e.g. Alcoholism, depression, drug abuse) e.g.
How often to you drink alcohol?
- All the time
- Occasionally
- Never
the player answers all 15 questions and at the end depending on how they answered the questions they get assigned a category e.g. your category is Drug Abuse etc.
I'm thinking that maybe each category has its own counter and a value is applied to each of the possible answers e.g. All the time gives a score of 3, occasionally scores a 2 etc. As the player answers the questions, the values get stored in the corresponding category and at the end the scores for each category are added up and the category with the highest score gets assigned to the player?
Any help with this would be appreciated :)
HTML:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h2 id="test_status"></h2>
<div id="test"></div>
</body>
</html>
CSS:
<style>
div#test {
border:#000 1px solid;
padding: 10px 40px 40px 40px;
}
</style>
JS:
<script>
var pos = 0, test, test_status, question, choice, choices, chA, chB, chC, correct = 0;
var questions = [
["How often do you drink?", "All the time", "Often", "Never", "B"],
["Do you ever feel sad for no reason?", "All the time", "Often", "Never", "C"],
["Have you ever tried drugs", "All the time", "Often", "Never", "C"],
["Do you feel uneasy around people", "All the time", "Often", "Never", "C"]
];
function _(x) {
return document.getElementById(x);
}
function renderQuestion () {
test = _("test");
if(pos >= questions.length) {
test.innerHTML = "<h2>Your Category is </h2>";
_("test_status").innerHTML = "Test Completed";
pos = 0;
correct = 0;
return false;
}
_("test_status").innerHTML = "Question "+(pos+1)+" of"+questions.length;
question = questions[pos] [0];
chA = questions[pos] [1];
chB = questions[pos] [2];
chC = questions[pos] [3];
test.innerHTML = "<h3>"+question+"</h3>";
test.innerHTML += "<input type='radio' name='choices' value='A'> "+chA+"<br>";
test.innerHTML += "<input type='radio' name='choices' value='B'> "+chB+"<br>";
test.innerHTML += "<input type='radio' name='choices' value='C'> "+chC+"<br><br>";
test.innerHTML +="<button onclick='checkAnswer()'>submit Answer</button>";
}
function checkAnswer() {
choices = document.getElementsByName("choices");
for (var i=0; i<choices.length; i++) {
if(choices[i].checked) {
choice = choices[i].value;
}
}
if(choice == questions[pos] [4]) {
correct++;
}
pos++;
renderQuestion();
}
window.addEventListener("load", renderQuestion, false);
</script>
The executable Javascript snippet its generated by TypeScript(a public GIT repository is available on this bucket), The quiz its organized by arguments and categories; below you can see the UML diagram.
var __extends = this.__extends || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
__.prototype = b.prototype;
d.prototype = new __();
};
var Categories;
(function (Categories) {
var QuestionCategory = (function () {
function QuestionCategory(value) {
this.Value = value;
}
return QuestionCategory;
})();
Categories.QuestionCategory = QuestionCategory;
var AQuestionCategory = (function (_super) {
__extends(AQuestionCategory, _super);
function AQuestionCategory() {
_super.call(this, 1);
}
return AQuestionCategory;
})(QuestionCategory);
Categories.AQuestionCategory = AQuestionCategory;
var BQuestionCategory = (function (_super) {
__extends(BQuestionCategory, _super);
function BQuestionCategory() {
_super.call(this, 2);
}
return BQuestionCategory;
})(QuestionCategory);
Categories.BQuestionCategory = BQuestionCategory;
var CQuestionCategory = (function (_super) {
__extends(CQuestionCategory, _super);
function CQuestionCategory() {
_super.call(this, 3);
}
return CQuestionCategory;
})(QuestionCategory);
Categories.CQuestionCategory = CQuestionCategory;
})(Categories || (Categories = {}));
var Questions;
(function (Questions) {
var Answer = (function () {
function Answer(text, value) {
this.Text = text;
this.Value = value;
}
return Answer;
})();
Questions.Answer = Answer;
var Question = (function () {
function Question(text, id, category, answers) {
this.Text = text;
this.ID = id;
this.Category = category;
this.Answers = answers;
}
Question.prototype.Render = function () {
var _this = this;
var dContainer = document.createElement("div");
var dQuestion = document.createElement("h3");
dQuestion.innerHTML = this.Text;
dContainer.appendChild(dQuestion);
var dCategory = document.createElement("div");
dCategory.innerHTML = 'Category: ' + this.Category.Value;
dContainer.appendChild(dCategory);
dContainer.appendChild(document.createElement("br"));
var counter = 0;
this.Answers.forEach(function (a) {
var __id = _this.ID + counter;
var dRadio = document.createElement("input");
dRadio.setAttribute('type', 'radio');
dRadio.setAttribute('id', __id);
dRadio.setAttribute('data-category', _this.Category.Value + '');
dRadio.setAttribute('value', a.Value + '');
dRadio.setAttribute('name', _this.ID);
var dLabel = document.createElement("label");
dLabel.innerHTML = a.Text;
dLabel.setAttribute('For', __id);
dContainer.appendChild(dRadio);
dContainer.appendChild(dLabel);
counter++;
});
dContainer.appendChild(document.createElement("hr"));
return dContainer;
};
return Question;
})();
Questions.Question = Question;
var QuestionCollection = (function () {
function QuestionCollection(questions) {
this.Questions = questions;
}
QuestionCollection.prototype.Render = function () {
var div = document.createElement("div");
this.Questions.forEach(function (q) {
div.appendChild(q.Render());
});
return div;
};
return QuestionCollection;
})();
Questions.QuestionCollection = QuestionCollection;
var QuestionArgument = (function () {
function QuestionArgument(name, collection) {
this.Collection = collection;
this.Name = name;
}
QuestionArgument.prototype.Render = function () {
var div = document.createElement("div");
var h1Arg = document.createElement("h1");
h1Arg.innerHTML = this.Name;
div.appendChild(h1Arg);
div.appendChild(document.createElement("hr"));
div.appendChild(this.Collection.Render());
return div;
};
return QuestionArgument;
})();
Questions.QuestionArgument = QuestionArgument;
var QuizManager = (function () {
function QuizManager(hook, arguments) {
this.Arguments = arguments;
this.Hook = hook;
}
QuizManager.prototype.Render = function () {
var _this = this;
this.Arguments.forEach(function (arg) {
_this.Hook.appendChild(arg.Render());
});
var btn = document.createElement('input');
btn.setAttribute('type', 'button');
btn.setAttribute('value', 'Done');
btn.onclick = function (e) {
_this.Compute();
};
this.Hook.appendChild(btn);
};
QuizManager.prototype.Compute = function () {
var _this = this;
var cats = [], dxCat = [], dxCatTotValue = [];
this.Arguments.forEach(function (arg) {
arg.Collection.Questions.forEach(function (q) {
if (cats.length > 0) {
if (cats.indexOf(q.Category) === -1)
cats.push(q.Category);
}
else
cats.push(q.Category);
});
});
cats.forEach(function (c) {
var p = document.querySelectorAll('input[data-category =\'' + c.Value + '\']:checked');
var tv = 0;
for (var i = 0; i < p.length; i++) {
if (parseInt(p[i]['value']) != NaN)
tv += parseInt(p[i]['value']);
}
dxCatTotValue.push({ "Cat": c.Value, "TVal": tv });
});
this.Hook.appendChild(document.createElement("hr"));
var summariH2 = document.createElement("h2");
summariH2.innerHTML = 'Summary';
dxCatTotValue.sort(this.Compare);
dxCatTotValue.forEach(function (catValue) {
var entryDiv = document.createElement("div");
entryDiv.innerHTML = 'Category ' + catValue['Cat'] + ': ' + catValue['TVal'];
_this.Hook.appendChild(entryDiv);
});
this.Hook.appendChild(document.createElement("hr"));
};
QuizManager.prototype.Compare = function (a, b) {
if (a['TVal'] > b['TVal'])
return -1;
if (a['TVal'] < b['TVal'])
return 1;
return 0;
};
return QuizManager;
})();
Questions.QuizManager = QuizManager;
})(Questions || (Questions = {}));
window.onload = function () {
var CCat = new Categories.CQuestionCategory();
var BCat = new Categories.BQuestionCategory();
var ACat = new Categories.AQuestionCategory();
var q1 = new Questions.Question('Do you eat Apples?', 'q1', CCat, [new Questions.Answer('All the time', 1), new Questions.Answer('Occasionally', 2), , new Questions.Answer('Never', 3)]);
var q2 = new Questions.Question('Do you like Pears?', 'q2', BCat, [new Questions.Answer('Yes', 1), new Questions.Answer('No', 2)]);
var fruitsquestions = new Questions.QuestionCollection([q1, q2]);
var fruitsArguments = new Questions.QuestionArgument('Fruits', fruitsquestions);
var q3 = new Questions.Question('Do you eat Onions?', 'q3', ACat, [new Questions.Answer('Yes', 1), new Questions.Answer('No', 2)]);
var q4 = new Questions.Question('Do you like Cucumbers?', 'q4', CCat, [new Questions.Answer('All the time', 1), new Questions.Answer('Occasionally', 2), , new Questions.Answer('Never', 3)]);
var vegetablesQuestions = new Questions.QuestionCollection([q3, q4]);
var vegetablesArguments = new Questions.QuestionArgument('Vegetables', vegetablesQuestions);
var quiz = new Questions.QuizManager(document.getElementById("content"), [fruitsArguments, vegetablesArguments]);
quiz.Render();
};
<div id="content"></div>
The TypeScript source:
module Categories {
export class QuestionCategory {
Value: number;
Text: string;
constructor(value: number) { this.Value = value; }
}
export class AQuestionCategory extends QuestionCategory {
constructor() { super(1); }
}
export class BQuestionCategory extends QuestionCategory {
constructor() { super(2); }
}
export class CQuestionCategory extends QuestionCategory {
constructor() { super(3); }
}
}
module Questions {
import QC = Categories;
export class Answer {
Text: string;
Value: number;
constructor(text: string, value: number) {
this.Text = text;
this.Value = value;
}
}
export class Question {
Category: QC.QuestionCategory;
Answers: Answer[];
Text: string;
ID: string;
constructor(text: string, id: string, category: QC.QuestionCategory, answers: Answer[]) {
this.Text = text;
this.ID = id;
this.Category = category;
this.Answers = answers;
}
Render(): HTMLElement {
var dContainer = document.createElement("div");
var dQuestion = document.createElement("h3")
dQuestion.innerHTML = this.Text;
dContainer.appendChild(dQuestion);
var dCategory = document.createElement("div")
dCategory.innerHTML = 'Category: ' + this.Category.Value;
dContainer.appendChild(dCategory);
dContainer.appendChild(document.createElement("br"));
var counter = 0;
this.Answers.forEach(a => {
var __id = this.ID + counter;
var dRadio = document.createElement("input");
dRadio.setAttribute('type', 'radio');
dRadio.setAttribute('id', __id);
dRadio.setAttribute('data-category', this.Category.Value + '');
dRadio.setAttribute('value', a.Value + '');
dRadio.setAttribute('name', this.ID);
var dLabel = document.createElement("label");
dLabel.innerHTML = a.Text
dLabel.setAttribute('For', __id)
dContainer.appendChild(dRadio);
dContainer.appendChild(dLabel);
counter++;
});
dContainer.appendChild(document.createElement("hr"));
return dContainer;
}
}
export class QuestionCollection {
Questions: Question[];
constructor(questions: Question[]) { this.Questions = questions; }
Render(): HTMLElement {
var div = document.createElement("div");
this.Questions.forEach(q => {
div.appendChild(q.Render());
});
return div;
}
}
export class QuestionArgument {
Name: string;
Collection: QuestionCollection;
constructor(name: string, collection: QuestionCollection) {
this.Collection = collection;
this.Name = name;
}
Render(): HTMLElement {
var div = document.createElement("div");
var h1Arg = document.createElement("h1");
h1Arg.innerHTML = this.Name;
div.appendChild(h1Arg);
div.appendChild(document.createElement("hr"));
div.appendChild(this.Collection.Render());
return div;
}
}
export class QuizManager {
Hook: HTMLElement;
Arguments: QuestionArgument[];
constructor(hook: HTMLElement, arguments: QuestionArgument[]) {
this.Arguments = arguments;
this.Hook = hook;
}
Render() {
this.Arguments.forEach(arg => {
this.Hook.appendChild(arg.Render());
});
var btn = <HTMLButtonElement> document.createElement('input');
btn.setAttribute('type', 'button');
btn.setAttribute('value', 'Done');
btn.onclick = (e) => { this.Compute(); }
this.Hook.appendChild(btn);
}
Compute() {
var cats = [], dxCat = [], dxCatTotValue = [];
this.Arguments.forEach(arg => {
arg.Collection.Questions.forEach(q => {
if (cats.length > 0) {
if (cats.indexOf(q.Category) === -1)
cats.push(q.Category);
}
else
cats.push(q.Category);
});
});
cats.forEach(c => {
var p = document.querySelectorAll('input[data-category =\'' + c.Value + '\']:checked');
var tv = 0;
for (var i = 0; i < p.length; i++)
{
if (parseInt(p[i]['value']) != NaN)
tv += parseInt(p[i]['value']);
}
dxCatTotValue.push({ "Cat": c.Value, "TVal": tv });
})
//this.Hook.appendChild(btn);
this.Hook.appendChild(document.createElement("hr"));
var summariH2 = document.createElement("h2");
summariH2.innerHTML = 'Summary';
dxCatTotValue.sort(this.Compare);
dxCatTotValue.forEach(catValue => {
var entryDiv = document.createElement("div");
entryDiv.innerHTML = 'Category ' + catValue['Cat'] + ': ' + catValue['TVal'];
this.Hook.appendChild(entryDiv);
});
this.Hook.appendChild(document.createElement("hr"));
}
Compare(a, b) {
if (a['TVal'] > b['TVal'])
return -1;
if (a['TVal'] < b['TVal'])
return 1;
return 0;
}
}
}
window.onload = () => {
var CCat = new Categories.CQuestionCategory();
var BCat = new Categories.BQuestionCategory();
var ACat = new Categories.AQuestionCategory();
var q1 = new Questions.Question('Do you eat Apples?', 'q1',
CCat,
[new Questions.Answer('All the time', 1), new Questions.Answer('Occasionally', 2), , new Questions.Answer('Never', 3)]);
var q2 = new Questions.Question('Do you like Pears?', 'q2',
BCat,
[new Questions.Answer('Yes', 1), new Questions.Answer('No', 2)]);
var fruitsquestions = new Questions.QuestionCollection([q1, q2]);
var fruitsArguments = new Questions.QuestionArgument('Fruits', fruitsquestions);
var q3 = new Questions.Question('Do you eat Onions?', 'q3',
ACat,
[new Questions.Answer('Yes', 1), new Questions.Answer('No', 2)]);
var q4 = new Questions.Question('Do you like Cucumbers?', 'q4',
CCat,
[new Questions.Answer('All the time', 1), new Questions.Answer('Occasionally', 2), , new Questions.Answer('Never', 3)]);
var vegetablesQuestions = new Questions.QuestionCollection([q3, q4]);
var vegetablesArguments = new Questions.QuestionArgument('Vegetables', vegetablesQuestions);
var quiz = new Questions.QuizManager(document.getElementById("content"), [fruitsArguments, vegetablesArguments]);
quiz.Render();
};
this quiz maker produces a very simple set of HTML and it's obvious where the total calculation is in order to change it.
You can simply add the numbers of questions relating to each answer, then compare to say which is largest and display the result. It gives you a choice of having radio buttons in a list for each question, or several on one line.
All the questions will display on a single page, rather than having to press Next each time which can be annoying for people doing the quiz. No CSS is needed and hardly any javascript.
Example code for a self-scoring quiz with 1 question of each type (drop-down box, short answer, multiple answers etc). The generator tool in the link above will create something similar, it's pure HTML and javascript with no external scripts to load, no jquery or dependencies.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional/EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../../dkj.css" type="text/css">
<title>Quiz: Sample "Think Again" Quiz</title>
<script type="text/javascript">
<!--
var stuff = new Array (51) // maximum number of questions
var answered = new Array (51) // processing inhibitor for guessers
for(var i = 0; i<=50; i++){stuff[i]=0; answered[i]=0} //initialize arrays// --> </script>
</head>
<body bgcolor ="#ffff88" text="#000000" link="#000088" vlink="purple" alink="#880000" >
<a name="top"></a>
<p align='right'><font size=-1>
Quiz created: 1999/1/31
</font></p>
<center>
<h2><font color="#ff3333">Sample "Think Again" Quiz</font></h2></center>
<noscript>
<p><font color="#880000">
I'm sorry. This page requires that your browser be capable of running JavaScript in order to use the self-correcting feature of the quiz.
In most browsers you can activate JavaScript using a dialog box somewhere under one of the menu bar options. If you are really using a (rare) non-JavaScript-capable browser, you will have to do without the self-grading features of this page.</font></p>
</noscript>
<p>
<b>Instructions: </b>
Answer the multiple choice questions, guessing if necessary,
then click on the "Process Questions" button to see your
score. The program will not reveal which questions you got wrong, only how
many points you have. Go back and change your answers until you get them all
right. (The message box will rejoice at that point and the page will change color in delight.)</p>
<p>
<b>Points to note: </b>
(1) Questions with only one possible answer are one point each.
(2) Questions with <i>one or more</i> possible answers (represented by check boxes)
give a point for each correct answer, but also subtract a point for each wrong answer!
(3) The program will not attempt to score your efforts at all if
you have not tried at least half of the questions.
(4) This practice quiz is for your own use only.
No record of your progress is kept or reported to anyone. </p>
<hr>
<form name="formzSampQuiz">
1. Fog is notorious in
<blockquote>
<input type=radio name=quest1 onClick="stuff[1]=0; answered[1]=1">New York
<input type=radio name=quest1 onClick="stuff[1]=0; answered[1]=1">Chicago
<input type=radio name=quest1 onClick="stuff[1]=1; answered[1]=1">London
<input type=radio name=quest1 onClick="stuff[1]=0; answered[1]=1">Los Angeles
<input type=radio name=quest1 checked onClick="stuff[1]=0; answered[1]=0">No Answer </blockquote>
2. Chicago is in
<blockquote>
<input type=radio name=quest2 onClick="stuff[2]=0; answered[2]=1">Montana
<input type=radio name=quest2 onClick="stuff[2]=0; answered[2]=1">Manitoba
<input type=radio name=quest2 onClick="stuff[2]=0; answered[2]=1">Missouri
<input type=radio name=quest2 onClick="stuff[2]=1; answered[2]=1">Illinois
<input type=radio name=quest2 checked onClick="stuff[2]=0; answered[2]=0">No Answer </blockquote>
3. The famous French Queen Marie Antoinette was married to
<blockquote>
<select name=quest3 size=1 onChange="figureout3()"><option selected>No Answer <option>St. Louis
<option>Louis XVI
<option>Louis DXLVIII
<option>Louis Rukeyser
<option>Louey, brother of Dewey and and Huey
<option>John L. Louis
</select>
<script type="text/javascript"><!-- //Pre-processor for question 3";
function figureout3() {
if (document.formzSampQuiz.quest3.options.selectedIndex == 0)
{stuff[3] = 0; answered[3]=0} // no answer
else if (document.formzSampQuiz.quest3.options.selectedIndex == 2)
{stuff[3] = 1; answered[3]=1} // right answer
else {stuff[3] = 0; answered[3]=1} // wrong answer
} // end function figureout3()
//--></script>
</blockquote>
4. Compared with Elizabeth II, Elizabeth I was
<blockquote>
<input type=radio name=quest4 onClick="stuff[4]=1; answered[4]=1">earlier
<input type=radio name=quest4 onClick="stuff[4]=0; answered[4]=1">later
<input type=radio name=quest4 checked onClick="stuff[4]=0; answered[4]=0">No Answer </blockquote>
5. Which of the Following are saints?
<blockquote>
<script type="text/javascript">
<!-- //Script to pre-process question 5
function figureout5() {
stuff[5]=0; answered[5]=0
if(document.formzSampQuiz.q5p2.checked==true){stuff[5]--; answered[5]=1}
if(document.formzSampQuiz.q5p3.checked==true){stuff[5]++; answered[5]=1}
if(document.formzSampQuiz.q5p4.checked==true){stuff[5]++; answered[5]=1}
if(document.formzSampQuiz.q5p5.checked==true){stuff[5]--; answered[5]=1}
if(document.formzSampQuiz.q5p6.checked==true){stuff[5]--; answered[5]=1}
} //end function figure5
// --></script>
<input type=checkbox name="q5p2" onClick="figureout5()">
Jack-the-Ripper
<input type=checkbox name="q5p3" onClick="figureout5()">
St. Augustine
<input type=checkbox name="q5p4" onClick="figureout5()">
St. Ursula
<input type=checkbox name="q5p5" onClick="figureout5()">
Adolf Hitler
<input type=checkbox name="q5p6" onClick="figureout5()">
Napoleon
</blockquote>
6. Which of the following is <i>not</i> one of the Seven Deadly Sins?
<blockquote>
<select name=quest6 size=1 onChange="figureout6()"><option selected>No Answer <option>pride
<option>lust
<option>envy
<option>stupidity
<option>anger
<option>covetousness
<option>gluttony
<option>sloth
</select>
<script type="text/javascript"><!-- //Pre-processor for question 6";
function figureout6() {
if (document.formzSampQuiz.quest6.options.selectedIndex == 0)
{stuff[6] = 0; answered[6]=0} // no answer
else if (document.formzSampQuiz.quest6.options.selectedIndex == 4)
{stuff[6] = 1; answered[6]=1} // right answer
else {stuff[6] = 0; answered[6]=1} // wrong answer
} // end function figureout6()
//--></script>
</blockquote>
<script type="text/javascript"><!--// Processor for questions 1-6>
function processqzSampQuiz() {
document.bgColor='#ffff88'
var goodguyszSampQuiz=0 // used to calculate score
var inhibitzSampQuiz=0 // used to prevent processing of partially completed forms
for (var i=1; i<=6; i++){
goodguyszSampQuiz=goodguyszSampQuiz + stuff[i]; inhibitzSampQuiz = inhibitzSampQuiz + answered[i];
} // end for
// Prevent display of score if too few questions completed
if (inhibitzSampQuiz < 3){
document.formzSampQuiz.grade.value="You must try at least 3!"
document.formzSampQuiz.score.value= "Secret!";
} // end if
else {
document.formzSampQuiz.score.value=goodguyszSampQuiz;
if (goodguyszSampQuiz==7){
document.formzSampQuiz.grade.value="Hooray!"
document.bgColor="#ff9999"
}else {document.formzSampQuiz.grade.value="Keep Trying!"}
} // end else
} // end function processqzSampQuiz()
function killall(){ //keep final scores from hanging around after reset clears form
goodguys=0; inhibitaa=0;
for (i=0; i<=50; i++){stuff[i]=0; answered[i]=0}
} // end functionl killall()
// --> </script>
<input type=button name=processor value="Process Questions" onClick=processqzSampQuiz()> <input type=reset value="Reset" onClick="killall(); document.bgColor='#ffff88'">
<input type=text name="grade" value="Nothing!" size=25 onFocus="blur()">
Points out of 7:
<input type=text name="score" value="Zip!" size=10 onFocus="blur()">
<br></form>
<p align='right'><font size=-1>
Return to top.</font></p>
<hr>
<!-- You can edit this acknowledgement out if you like. -->
<p align='right'><font size=-1>
This consummately cool, pedagogically compelling, self-correcting, <br>
multiple-choice quiz was produced automatically from <br>
a text file of questions using D.K. Jordan's<br>
<a href="http://anthro.ucsd.edu/~dkjordan/resources/quizzes/quizzes.html">
Think Again Quiz Maker</a> <br>
of October 31, 1998.<br>
</font></p>
</body></html>

Categories

Resources