-
Notifications
You must be signed in to change notification settings - Fork 0
/
equations.js
148 lines (130 loc) · 5.1 KB
/
equations.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
(function(){
if (typeof ExplodingNumbers === "undefined") {
window.ExplodingNumbers = {};
}
// The difficulty will be passed into each new equation
var Equation = ExplodingNumbers.Equation = function(difficulty, hashOfNumbers, xPosition, operations){
this.difficulty = Math.round(difficulty);
this.largestNumber = Math.pow(10, this.difficulty);
this.operations = operations;
this.equationGenerationTries = 0;
this.xPosition = xPosition;
this.createEquation(hashOfNumbers);
};
// The main function, called when a new equation is needed
Equation.prototype.createEquation = function(hashOfNumbers) {
var operationIndex = ExplodingNumbers.Util.randomNumber(this.operations.length - 1);
var operation = this.operations[operationIndex];
var equationText = "";
try {
switch(operation) {
case '+':
this.getRandomAnswer(hashOfNumbers);
var addend1 = this.getRandomNumber(this.answer),
addend2 = this.answer - addend1;
equationText = addend1 + ' + ' + addend2;
this.equation = this.generateEquationObject(equationText);
break;
case "-":
var minuend = this.getRandomNumber() + 1,
subtrahend = this.getOtherNumberInEquation(hashOfNumbers, minuend, operation);
equationText = minuend + ' - ' + subtrahend;
this.equation = this.generateEquationObject(equationText);
break;
case '*':
this.getRandomAnswer(hashOfNumbers);
var multiplicand = this.getRandomNumber(),
multiplier = this.answer / multiplicand;
// Only use integers!
while (multiplicand * multiplier !== this.answer || !Number.isInteger(multiplier)){
multiplicand = this.getRandomNumber();
multiplier = this.answer / multiplicand;
}
equationText = multiplicand + ' x ' + multiplier;
this.equation = this.generateEquationObject(equationText);
break;
case '/':
var dividend = this.getRandomNumber() + 1,
divisor = this.getOtherNumberInEquation(hashOfNumbers, dividend, operation);
equationText = dividend + ' / ' + divisor;
this.equation = this.generateEquationObject(equationText);
break;
}
}
// Catch instances when there is no equation with answers on the screen for given starting number
catch(error){
this.equationGenerationTries = 0;
this.createEquation(hashOfNumbers);
}
return this.equation;
};
// Make equation into a fabric object
Equation.prototype.generateEquationObject = function (text) {
return new fabric.Text("What is " + text + "?", {
fontSize: 20,
fontStyle: 'bold',
fill: 'white',
top: 0,
left: this.xPosition,
selectable: false,
});
};
// For addition and multiplication problems, the answer will be dependent on difficulty
// So get a random answer from numbers on the board first
Equation.prototype.getRandomAnswer = function (hashOfNumbers) {
do {
if(this.equationGenerationTries > 20) throw "infiniteloop"; //Recognize infinite loops and make createEquation start again
this.equationGenerationTries++;
this.answer = this.getRandomNumber();
}
while (!this.answerInNumbersHash(hashOfNumbers));
return this.answer;
};
// for subtraction and division problem, a random number is generated for number left of operator
// The other number will be randomly generated so that the answer is in the numbersHash
Equation.prototype.getOtherNumberInEquation = function (hashOfNumbers, total, operation) {
var response = null;
do {
if(this.equationGenerationTries > 20) throw "infiniteloop";
this.equationGenerationTries++;
switch(operation) {
case "-":
do {
response = this.getRandomNumber();
this.answer = total - response;
} while (this.answer < 0);
break;
case "/":
do {
response = this.getRandomNumber();
this.answer = Math.round(total / response);
} while (this.answer * response !== total);
break;
}
}
while (!this.answerInNumbersHash(hashOfNumbers));
return response;
};
// An equation to test whether the answer can be created
// from answers on the board
Equation.prototype.answerInNumbersHash = function (hashOfNumbers) {
var included = true;
var answerString = this.answer.toString();
var answerHash = {};
for (var i = 0; i < answerString.length; i++) {
answerHash[parseInt(answerString[i])] = answerHash[parseInt(answerString[i])] + 1 || 1;
}
for (var number in answerHash) {
if (!hashOfNumbers[number] || answerHash[number] > hashOfNumbers[number]) {
included = false;
}
}
return included;
};
// Get a random number, convert it to a string
// If a maximum number is not specified, use the largestNumber based on the difficulty
Equation.prototype.getRandomNumber = function (maximumNumber) {
maximumNumber = maximumNumber ? maximumNumber : this.largestNumber;
return ExplodingNumbers.Util.randomNumber(maximumNumber);
};
})();