topical media & game development
game-javascript-math-kennedy-superMathChallenge.htm / htm
<html>
<head>
<title>Mathematics Challenge!!!</title>
<script language="JavaScript">
// constants - DO NOT ASSIGN TO THEM (javascript doesn't have constants)
var kNumberOfProblems = 10;
var kTableIdForProblems = "practiceMathTableProblems";
var kTableIdForAnswers = "practiceMathTableAnswers";
var kTableIdForResults = "practiceMathTableResults";
var kMultiplication = 'x';
var kAddition = '+';
var kSubtraction = '-';
var kDivision = '\367';
var kRandom = '!';
var kNotAnswered = -1;
// global variables
var gStartTime = 0;
var gProblemArray = new Array(); // array of objects that hold the two operands and the operation
// functions
function assert(isTrue, message) { if (!isTrue) { alert(message) } }
function myPop (string){
var generator=window.open('',
'name',
'width=400,height=100,toolbar=0,scrollbars=0,screenX=200,screenY=200,left=200,top=200');
generator.document.write('<html><head><title>Math Challenge!</title></head><body>');
generator.document.write(string);
generator.document.write('<center><a href="javascript:self.close()">Close</a></center>');
generator.document.write('</body></html>');
generator.document.close();
}
function getRandomNumberInRange(rangeStart, rangeEnd){
if (rangeStart==rangeEnd) return rangeStart;
assert((rangeStart<rangeEnd),
"getRandomNumberInRange(" + rangeStart + ", " + rangeEnd + "): Invalid Input");
var randomNumber = Math.round(Math.random()*(rangeEnd-rangeStart));
return (rangeStart+randomNumber);
}
function requestPrintTest(operation){
if (document.getElementById) {
// clear the old answers.
document.practiceMathForm.problem0.value = '';
document.practiceMathForm.problem1.value = '';
document.practiceMathForm.problem2.value = '';
document.practiceMathForm.problem3.value = '';
document.practiceMathForm.problem4.value = '';
document.practiceMathForm.problem5.value = '';
document.practiceMathForm.problem6.value = '';
document.practiceMathForm.problem7.value = '';
document.practiceMathForm.problem8.value = '';
document.practiceMathForm.problem9.value = '';
// clear old dynamically created table stuff.
clearChildNodes(kTableIdForProblems);
clearChildNodes(kTableIdForAnswers);
clearChildNodes(kTableIdForResults);
// assure bug-free redraw in Gecko engine by letting window show cleared table
if (navigator.product && navigator.product == "Gecko") {
setTimeout("printTest("+"'"+operation+"'"+")", 0);
}
else {
printTest(operation);
}
}
else {
alert("Sorry, dynamic table feature works with IE5 or later for Windows, and Netscape 6 or later.");
}
gStartTime = getCurrentTimeInSeconds();
}
function requestPrintResults(){
// disable the "I am finished!" button
document.practiceMathForm.finishedButton.disabled=true;
// this is stupid but...
if ('' != document.practiceMathForm.problem0.value)
gProblemArray[0].theirAnswer = document.practiceMathForm.problem0.value;
else
gProblemArray[0].theirAnswer = kNotAnswered;
if ('' != document.practiceMathForm.problem1.value)
gProblemArray[1].theirAnswer = document.practiceMathForm.problem1.value;
else
gProblemArray[1].theirAnswer = kNotAnswered;
if ('' != document.practiceMathForm.problem2.value)
gProblemArray[2].theirAnswer = document.practiceMathForm.problem2.value;
else
gProblemArray[2].theirAnswer = kNotAnswered;
if ('' != document.practiceMathForm.problem3.value)
gProblemArray[3].theirAnswer = document.practiceMathForm.problem3.value;
else
gProblemArray[3].theirAnswer = kNotAnswered;
if ('' != document.practiceMathForm.problem4.value)
gProblemArray[4].theirAnswer = document.practiceMathForm.problem4.value;
else
gProblemArray[4].theirAnswer = kNotAnswered;
if ('' != document.practiceMathForm.problem5.value)
gProblemArray[5].theirAnswer = document.practiceMathForm.problem5.value;
else
gProblemArray[5].theirAnswer = kNotAnswered;
if ('' != document.practiceMathForm.problem6.value)
gProblemArray[6].theirAnswer = document.practiceMathForm.problem6.value;
else
gProblemArray[6].theirAnswer = kNotAnswered;
if ('' != document.practiceMathForm.problem7.value)
gProblemArray[7].theirAnswer = document.practiceMathForm.problem7.value;
else
gProblemArray[7].theirAnswer = kNotAnswered;
if ('' != document.practiceMathForm.problem8.value)
gProblemArray[8].theirAnswer = document.practiceMathForm.problem8.value;
else
gProblemArray[8].theirAnswer = kNotAnswered;
if ('' != document.practiceMathForm.problem9.value)
gProblemArray[9].theirAnswer = document.practiceMathForm.problem9.value;
else
gProblemArray[9].theirAnswer = kNotAnswered;
if (document.getElementById) {
clearChildNodes(kTableIdForAnswers);
clearChildNodes(kTableIdForResults);
// assure bug-free redraw in Gecko engine by letting window show cleared table
if (navigator.product && navigator.product == "Gecko") {
setTimeout("printResults()", 0);
}
else {
printResults();
}
}
else {
alert("Sorry, dynamic table feature works with IE5 or later for Windows, and Netscape 6 or later.");
}
}
function printTest(operation){
// initialize problem array
initializeMathProblemsArray(operation);
// dynamically generate the appropriate challenge
printChallengeProblems();
enableFinishedButton();
}
function getCurrentTimeInSeconds(){
return Math.round(new Date().valueOf()/1000);
}
function printResults(){
// get stop time
assert((0 != gStartTime), "Corrupt start time.");
var elapsedTimeSecs= getCurrentTimeInSeconds() - gStartTime + 1;
// print results
printAnswersAndResults(elapsedTimeSecs);
// email results?
}
function initializeMathProblemsArray(operation){
var i = 0, op1 = 0, op2 = 0, ans = 0;
var currentOperation = operation;
var kBigOperand = 11, kBiggestOperand = 15;
for (i = 0; i < kNumberOfProblems; i++){
// If random, them determine the operation for this question...
if (kRandom == operation) {
switch (getRandomNumberInRange(0,3)) {
case 0 : currentOperation = kAddition; break;
case 1 : currentOperation = kSubtraction; break;
case 2 : currentOperation = kMultiplication; break;
case 3 : currentOperation = kDivision; break;
default: alert("Random operation failed to get appropriate result.");
}
}
// now fill in the problem info
switch (currentOperation) {
case kAddition :
op1 = getRandomNumberInRange(0, kBiggestOperand);
op2 = getRandomNumberInRange(0, kBiggestOperand);
gProblemArray[i] = {value1:op1, value2:op2, operation:kAddition, answer:(op1+op2), theirAnswer:kNotAnswered};
break;
case kSubtraction :
ans = getRandomNumberInRange(0, kBiggestOperand);
op2 = getRandomNumberInRange(0, kBigOperand);
gProblemArray[i] = {value1:op2+ans, value2:op2, operation:kSubtraction, answer:(ans), theirAnswer:kNotAnswered};
break;
case kMultiplication :
op1 = getRandomNumberInRange(0, kBigOperand);
op2 = getRandomNumberInRange(0, kBigOperand);
gProblemArray[i] = {value1:op1, value2:op2, operation:kMultiplication, answer:(op1*op2), theirAnswer:kNotAnswered};
break;
case kDivision :
if (getRandomNumberInRange(0, 5) <= 1) {
// 0 divided by ...
gProblemArray[i] = {value1:0, value2:getRandomNumberInRange(0, kBiggestOperand), operation:kDivision, answer:0, theirAnswer:kNotAnswered};
}
else {
// the rest....
ans = getRandomNumberInRange(0, kBigOperand);
op2 = getRandomNumberInRange(1, kBigOperand);
gProblemArray[i] = {value1:(op2*ans), value2:op2, operation:kDivision, answer:ans, theirAnswer:kNotAnswered};
}
break;
default:
alert("BUG: hey this ain't cool - bad operation(" + currentOperation + ").");
}
}
assert((gProblemArray.length == kNumberOfProblems), "BUG: hey init'd the array to the incorrect length.");
}
function printChallengeProblems(){
var br, u, tr, td, txt, txtBox, font;
var tbody = document.getElementById(kTableIdForProblems);
// create holder for accumulated tbody elements and text nodes
var frag = document.createDocumentFragment();
// loop through data source
assert((kNumberOfProblems==gProblemArray.length), "printChallengeProblems: array has been corrupted?");
tr = document.createElement("tr");
for (var i = 0; i < kNumberOfProblems; i++) {
td = document.createElement("td");
td.setAttribute("align", "right");
font = document.createElement("font");
//font.setAttribute("size", "-1");
txt = document.createTextNode(gProblemArray[i].value1);
font.appendChild(txt);
td.appendChild(font);
br = document.createElement("br");
td.appendChild(br);
u = document.createElement("u");
font = document.createElement("font");
//font.setAttribute("size", "-1");
txt = document.createTextNode(gProblemArray[i].operation + " " + gProblemArray[i].value2);
font.appendChild(txt);
u.appendChild(font);
td.appendChild(u);
tr.appendChild(td);
}
frag.appendChild(tr);
if (!tbody.appendChild(frag)) {
alert("This browser doesn't support dynamic tables.");
}
}
function enableFinishedButton(){
// enable the "I am finished!" button
document.practiceMathForm.finishedButton.disabled=false;
}
// this function should really be broken into two functions...
function printAnswersAndResults(elapsedTimeInSeconds){
var tbody, tr, td, txt, font, br;
var numRight = 0;
tbody = document.getElementById(kTableIdForAnswers);
// create holder for accumulated tbody elements and text nodes
var frag = document.createDocumentFragment();
// loop through and print the answers
assert((kNumberOfProblems==gProblemArray.length), "printChallengeProblems: array has been corrupted?");
tr = document.createElement("tr");
for (var i = 0; i < kNumberOfProblems; i++){
td = document.createElement("td");
td.setAttribute("align", "right");
br = document.createElement("br");
td.appendChild(br);
font = document.createElement("font");
// did they get it right?
if(gProblemArray[i].theirAnswer == gProblemArray[i].answer) {
numRight++;
}
else {
font = document.createElement("font");
font.setAttribute("size", "-1");
font.setAttribute("color","red");
txt = document.createTextNode(gProblemArray[i].value1 +
gProblemArray[i].operation +
gProblemArray[i].value2 + "=" +
gProblemArray[i].answer);
font.appendChild(txt);
}
td.appendChild(font);
tr.appendChild(td);
}
frag.appendChild(tr);
if (!tbody.appendChild(frag)) {
alert("This browser doesn't support dynamic tables.");
}
// print results
tbody = document.getElementById(kTableIdForResults);
// create holder for accumulated tbody elements and text nodes
frag = document.createDocumentFragment();
assert((kNumberOfProblems>=numRight),"kNumberOfProblems<numRight!!!");
var percent = Math.round((numRight/kNumberOfProblems)*100);
var message;
if (100 == percent)
message = "Perfect! You are so smart!!!";
else if (100 > percent && 80 <= percent)
message = "Iiyaloo! Very Good!";
else if (80 > percent && 70 <= percent)
message = "Good!";
else
message = "Hai ti, you need more practice.";
tr = document.createElement("tr");
td = document.createElement("td");
td.setAttribute("align", "center");
td.setAttribute("colspan", kNumberOfProblems);
font = document.createElement("font");
font.setAttribute("size", "+1");
txt = document.createTextNode(numRight + " right out of " + kNumberOfProblems +
" in " + elapsedTimeInSeconds + " seconds. " + percent + "%! " + message);
font.appendChild(txt);
td.appendChild(font);
tr.appendChild(td);
frag.appendChild(tr);
if (!tbody.appendChild(frag)) {
alert("This browser doesn't support dynamic tables.");
}
}
// Remove existing content of an element
function clearChildNodes(elemID) {
var elem = document.getElementById(elemID);
while (elem.childNodes.length > 0)
{
elem.removeChild(elem.firstChild);
}
}
</script>
</head>
<body onload="requestPrintTest('!');">
<table id="titleBar" width="100%" valign="top" align="center"><tr>
<td align="left"><font size="+2"><b>
<font color="blue">S</font><font color="brown">u</font><font color="red">p</font><font color="green">e</font><font color="purple">r </font>
<font color="orange">M</font><font color="brown">a</font><font color="black">t</font><font color="red">h</font><font color="green">e</font><font color="red">m</font><font color="blue">a</font><font color="green">t</font><font color="black">i</font><font color="purple">c</font><font color="black">s </font>
<font color="green">C</font><font color="red">h</font><font color="blue">a</font><font color="brown">l</font><font color="green">l</font><font color="orange">e</font><font color="red">n</font><font color="blue">g</font><font color="brown">e</font><font color="green">!</font>
</td>
<td><b><a href="javascript:requestPrintTest('+');" style="text-decoration: none">
<font size="+4" color="blue">+</font></a></b></td>
<td><b><a href="javascript:requestPrintTest('-');" style="text-decoration: none">
<font size="+4" color="red">–</font></a></b></td>
<td><b><a href="javascript:requestPrintTest('x');" style="text-decoration: none">
<font size="+4" color="purple">×</font></a></b></td>
<td><b><a href="javascript:requestPrintTest('\367');" style="text-decoration: none">
<font size="+4" color="green">÷</font></a></b></td>
<td><b><a href="javascript:requestPrintTest('!');" style="text-decoration: none">
<font size="+4" color="orange">!</font></a></b></td>
<td align="right">
<font size="-1">
<a href="javascript:myPop('Wrote this for my learners... Tested in IE6 & Safari.');">About</a> |
<a href="mailto:aarontkennedy@gmail.com">Suggestions?</a>
</font>
</td></tr></table><br>
<form name="practiceMathForm">
<table align="center" width="90%" border="0">
<tbody id="practiceMathTableProblems"></tbody>
<tr>
<td align="right" valign="top" width="10%"><input type"text" size="3" name="problem0"></td>
<td align="right" valign="top" width="10%"><input type"text" size="3" name="problem1"></td>
<td align="right" valign="top" width="10%"><input type"text" size="3" name="problem2"></td>
<td align="right" valign="top" width="10%"><input type"text" size="3" name="problem3"></td>
<td align="right" valign="top" width="10%"><input type"text" size="3" name="problem4"></td>
<td align="right" valign="top" width="10%"><input type"text" size="3" name="problem5"></td>
<td align="right" valign="top" width="10%"><input type"text" size="3" name="problem6"></td>
<td align="right" valign="top" width="10%"><input type"text" size="3" name="problem7"></td>
<td align="right" valign="top" width="10%"><input type"text" size="3" name="problem8"></td>
<td align="right" valign="top" width="10%"><input type"text" size="3" name="problem9"></td>
</tr>
<tbody id="practiceMathTableAnswers"></tbody>
</table>
<table align="center" width="90%" border="0">
<tbody id="practiceMathTableResults"></tbody>
</table><br>
<center>
<input name="finishedButton" type="button" value="I am finished!" onClick="requestPrintResults(); return false;">
</center>
</form>
<table width="100%" border="0" valign="bottom" align="center"><tr>
<td valign="center"><font size="+1" color="green">*</font></td>
<td valign="center"><font size="+2" color="purple">*</font></td>
<td valign="center"><font size="+1" color="orange">*</font></td>
<td><b><a href="javascript:requestPrintTest('+');" style="text-decoration: none">
<font size="+4" color="brown">+</font></a></b></td>
<td><b><a href="javascript:requestPrintTest('-');" style="text-decoration: none">
<font size="+4" color="blue">–</font></a></b></td>
<td><b><a href="javascript:requestPrintTest('x');" style="text-decoration: none">
<font size="+4" color="red">×</font></a></b></td>
<td><b><a href="javascript:requestPrintTest('\367');" style="text-decoration: none">
<font size="+4" color="green">÷</font></a></b></td>
<td><b><a href="javascript:requestPrintTest('!');" style="text-decoration: none">
<font size="+4" color="purple">!</font></a></b></td>
<td valign="center"><font size="+1" color="orange">*</font></td>
<td valign="center"><font size="+2" color="black">*</font></td>
<td valign="center"><font size="+1" color="green">*</font></td>
</tr></table>
</body>
</html>
(C) Æliens
20/2/2008
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.