-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSuperBase.js
More file actions
189 lines (168 loc) · 5.91 KB
/
SuperBase.js
File metadata and controls
189 lines (168 loc) · 5.91 KB
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
let decreaseVal = 5; // 5 gave no overlap
class SuperBase {
constructor(pos, prev_pos, dist, vals, points) {
this.pos = pos;
this.prev_pos = prev_pos;
this.dist = dist;
this.vals = vals;
this.points = points; // (x, y) coordinates, input for f
// assert that we have proper input (shouldn't go wrong)
if (this.vals.length !== 3) {
throw "Length is not 3";
}
// check type of superbase
if (this.vals.includes(0)) {
// lakesides are next to 0-lakes
this.oftype = "lakeside";
} else {
let n = false; // negative value
let p = false; // positive value
this.vals.forEach(function (item) {
if (item < 0) {
n = true;
} else {
p = true
}
});
if (n && p) {
// rivers have both positive and negative lakes
this.oftype = "river"
} else {
for (let comb of combinations(this.vals)) {
if (Math.abs(comb.d[0]) + Math.abs(comb.d[1]) < Math.abs(comb.s)) {
this.oftype = "normal";
break;
}
}
if (!this.oftype) {
// wells fulfill the above condition for all combinations
this.oftype = "well"
}
}
}
}
prod() {
// product of values (used to check for odd/even amount of negative values)
let p = 1;
for (let v of this.vals) {
p *= v;
}
return p;
}
check() {
// find if we have a solution
for (let i = 0; i < 3; i++) {
let frac;
let x, y;
if (n >= this.vals[i]) {
frac = n / this.vals[i];
x = this.points[i].x * Math.sqrt(frac);
y = this.points[i].y * Math.sqrt(frac);
} else {
frac = this.vals[i] / n;
x = this.points[i].x / Math.sqrt(frac);
y = this.points[i].y / Math.sqrt(frac);
}
if (frac < 0) {
return;
} else if (frac !== 0 && 1/frac !== 0 && Math.round(Math.sqrt(frac))**2 === frac) {
if (Math.round(x) === x && Math.round(y) === y) {
stage = "done";
alert("f(" + x.toString() + "," + y.toString() + ") = " + n);
console.log(n + " FOUND");
return;
}
} else if (n === 0) {
stage = "done";
alert("f(0, 0) = " + n);
return;
}
}
}
max() {
// find the index for the maximum value of this superbase
let m = 0;
let m_i = 0;
for (let i = 0; i < 3; i++) {
if (Math.abs(this.vals[i]) > Math.abs(m)) {
m = this.vals[i];
m_i = i;
}
}
return m_i;
}
move_away(m, p) {
// move away from the value and point specified as arguments, rot is argument to determine the next point in the
// canvas
let other_vals = [];
let other_points = [];
let m_found = false;
let m_i;
// find the other 2 values and points
for (let i = 0; i < 3; i++) {
if (this.vals[i] === m && this.points[i] === p && !m_found) {
m_found = true;
m_i = i;
continue;
}
other_vals.push(this.vals[i]);
other_points.push(this.points[i]);
}
// keep correct value on your left
if (m_i === 0) {
other_vals = other_vals.reverse();
other_points = other_points.reverse();
}
// calculate the next value and the next coordinates of the new superbase
let new_val = 2*(other_vals[0] + other_vals[1]) - m;
let new_point = createVector(
other_points[0].x + other_points[1].x,
other_points[0].y + other_points[1].y);
if (new_point.equals(p) || new_point.equals(createVector(-p.x, -p.y))) {
new_point = createVector(
other_points[0].x - other_points[1].x,
other_points[0].y - other_points[1].y);
}
// create a new superbase
let newPos = createVector(this.pos.x, this.pos.y);
let textPos = createVector(this.pos.x, this.pos.y);
let textSize = baseTextSize / (this.dist + 1);
let diff = createVector(this.pos.x - this.prev_pos.x, this.pos.y - this.prev_pos.y);
diff.mult(decreaseVal / (this.dist + decreaseVal));
console.log(this.vals, m, new_val);
let ang;
switch (m_i) {
case 0:
ang = -45 * (0.5 + 1/(1 + this.dist));
break;
case 1:
ang = 45 * (0.5 + 1/(1 + this.dist));
break;
default:
ang=180;
}
diff = rotateVector(diff, ang);
newPos.add(diff);
diff.mult(1.5);
textPos.add(diff);
textPos.sub(createVector(textSize / 2, 0));
let nxt = new SuperBase(
newPos,
createVector(this.pos.x, this.pos.y),
this.dist + 1,
[...other_vals, new_val],
[...other_points, new_point]
);
// check if we found a solution and return
nxt.check();
return {
"new_val": new_val,
"nxt": nxt,
"text": {
"val": new_val,
"pos": textPos,
"size": textSize
}
}
}
}