-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrover.js
422 lines (368 loc) · 18.4 KB
/
rover.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
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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
//as partes mais novas do codigo estao bem baguncadas e sem muitos comentarios, no futuro talvez eu organize tudo
//definicao de variaveis
let currentPosition = 0;
let array = [];
let left = -1;
let right = 1;
let forward = -4;
let backward = 4;
let firstprint = true;
let canGoRight = true;
let canGoLeft = false;
let rightBorder = [3, 7, 11, 15];
let mode = false;
let delay = false;
let delaytime = undefined;
let dateDifferenceSeconds = 0;
let delaySeconds;
let delayKilometers;
let delayValue = 5;
//le o cache do navegador para ver se o usuario ja usou o site antes, caso tenha usado, "lembra" de qual modo o usuario usou por ultimo e tambem lembra da ultima posicao do rover
mode = localStorage.mode;
delay = localStorage.delay;
delaytime = parseInt(localStorage.delayTime);
currentPosition = parseInt(localStorage.currentPosition);
let newDate = new Date();
let oldDate = localStorage.oldDate;
function bodyOnLoad(){
updateDelaySecondsInitial();
closehelpDelay();
setmode();
updateList();
if(delay == "true"){
dateDifference();
applyDateDifference();
}
else{
return;
}
}
//executa a funcao beforeClose() quando o usuario fecha a aba
window.onbeforeunload = function beforeClose(){
oldDate = new Date();
localStorage.setItem("oldDate", oldDate);
localStorage.setItem("delayTime", delaytime);
//o return null evita que um pop-up seja aberto e acabe impedindo com que o usuario feche a aba
return null;
}
//descobre a diferenca entre duas datas em segundos
function dateDifference(){
dateDifferenceSeconds =(Date.parse(oldDate) - Date.parse(newDate))/1000
}
function applyDateDifference(){
delaytime = delaytime + dateDifferenceSeconds;
buttonDisable();
enviardelay();
}
function updateList(){
array = JSON.parse(localStorage.array);
for(let i = 0; i<array.length; i++){
let temp = array[i];
if(i!=0){
document.getElementById("historico").innerHTML += ", ";
}
switch (temp){
case 1:
document.getElementById("historico").innerHTML += "Direita";
break;
case -1:
document.getElementById("historico").innerHTML += "Esquerda";
break;
case 4:
document.getElementById("historico").innerHTML += "Tras";
break;
case -4:
document.getElementById("historico").innerHTML += "Frente";
break;
}
}
}
//funcao visual, ela apenas mostra ao usuario qual modo esta selecionado, se o cache do navegador indicar que o modo deve ser o B, o switch que tem na tela vai automaticamente para a posicao B
function setmode(){
mode = localStorage.mode
if(delay == "true"){
document.getElementById("delayswitch").checked = true;
}
else{
document.getElementById("delayswitch").checked = false;
}
if(mode == "true"){
document.getElementById("modeswitch").checked = true;
mode = true;
console.log(mode)
}
else{
document.getElementById("modeswitch").checked = false;
mode = false;
console.log(mode)
}
//verifica se e a primeira vez que o usuario acessa o site, se for, a posicao sera 0
if(Number.isInteger(currentPosition) !== true){
currentPosition = 0;
}
//chama a funcao que atualiza a posicao do rover baseado no cache do navegador
positionUpdate()
}
//funcao que envia o comando "mover para esquerda" para a lista de comandos a serem executados, as proximas 3 funcoes seguem a mesma formatacao
function esquerda(){
//envia a variavel "left" para a lista de comandos a serem executados. Ou seja, envia o valor -1 para uma array de nome "array"
array.push(left);
//o IF serve para adicionar uma virgula na lista de comandos pendentes caso NAO SEJA a primeira palavra, desse jeito, a lista so tem virgula DEPOIS de cada palavra
if(firstprint == false){
document.getElementById("historico").innerHTML += ", ";
}
//adiciona a palavra "Esquerda" na lista de comandos pendentes, essa lista serve apenas para auxiliar o usuario e nao tem nenhum impacto no funcionamento
document.getElementById("historico").innerHTML += "Esquerda";
//torna a variavel "firstprint" falsa, essa variavel foi e sera utilizada no IF para adicionar virgulas na lista de comandos pendentes
firstprint = false;
}
//funcao que envia o comando "mover para direita" para a lista de comandos a serem executados, as proximas 2 funcoes seguem a mesma formatacao
function direita(){
//envia a variavel "right" para a lista de comandos a serem executados. Ou seja, envia o valor 1 para uma array de nome "array"
array.push(right);
//o IF serve para adicionar uma virgula na lista de comandos pendentes caso NAO SEJA a primeira palavra, desse jeito, a lista so tem virgula DEPOIS de cada palavra
if(firstprint == false){
document.getElementById("historico").innerHTML += ", ";
}
//adiciona a palavra "Direita" na lista de comandos pendentes, essa lista serve apenas para auxiliar o usuario e nao tem nenhum impacto no funcionamento
document.getElementById("historico").innerHTML += "Direita";
//torna a variavel "firstprint" falsa, essa variavel foi e sera utilizada no IF para adicionar virgulas na lista de comandos pendentes
firstprint = false;
}
//funcao que envia o comando "mover para frente" para a lista de comandos a serem executados, as proxima funcao segue a mesma formatacao
function frente(){
//envia a variavel "forward" para a lista de comandos a serem executados. Ou seja, envia o valor -4 para uma array de nome "array"
array.push(forward);
//o IF serve para adicionar uma virgula na lista de comandos pendentes caso NAO SEJA a primeira palavra, desse jeito, a lista so tem virgula DEPOIS de cada palavra
if(firstprint == false){
document.getElementById("historico").innerHTML += ", ";
}
//adiciona a palavra "Frente" na lista de comandos pendentes, essa lista serve apenas para auxiliar o usuario e nao tem nenhum impacto no funcionamento
document.getElementById("historico").innerHTML += "Frente";
//torna a variavel "firstprint" falsa, essa variavel foi e sera utilizada no IF para adicionar virgulas na lista de comandos pendentes
firstprint = false;
}
//funcao que envia o comando "mover para tras" para a lista de comandos a serem executados
function tras(){
//envia a variavel "backward" para a lista de comandos a serem executados. Ou seja, envia o valor 4 para uma array de nome "array"
array.push(backward);
//o IF serve para adicionar uma virgula na lista de comandos pendentes caso NAO SEJA a primeira palavra, desse jeito, a lista so tem virgula DEPOIS de cada palavra
if(firstprint == false){
document.getElementById("historico").innerHTML += ", ";
}
//adiciona a palavra "Tras" na lista de comandos pendentes, essa lista serve apenas para auxiliar o usuario e nao tem nenhum impacto no funcionamento
document.getElementById("historico").innerHTML += "Tras";
//torna a variavel "firstprint" falsa, essa variavel foi e sera utilizada no IF para adicionar virgulas na lista de comandos pendentes
firstprint = false;
}
function buttonDisable(){
document.getElementById("enviar").disabled=true;
document.getElementById("frente").disabled=true;
document.getElementById("tras").disabled=true;
document.getElementById("esquerda").disabled=true;
document.getElementById("direita").disabled=true;
}
function buttonEnable(){
document.getElementById("enviar").disabled=false;
document.getElementById("frente").disabled=false;
document.getElementById("tras").disabled=false;
document.getElementById("esquerda").disabled=false;
document.getElementById("direita").disabled=false;
}
function preenviar(){
if(delay=="true" || delay==true){
localStorage.setItem("array", JSON.stringify(array));
buttonDisable();
//tempo do delay em segundos. (o timer nao e muito confiavel, ele acerta o tempo com uma margen de -+30s)
delaytime = delayValue;
enviardelay()
}
else{
enviar();
}
}
function enviardelay(){
if(delaytime>1){
delaytime--;
document.getElementById("enviartext").textContent = minutify(delaytime);
setTimeout(enviardelay, 1000);
}
else{
enviar();
buttonEnable();
}
}
//transforma em minutos e segundos
function minutify(input){
let minutes = parseInt(input/60);
let minutesstring = minutes.toString();
let seconds = input%60;
let secondsstring = seconds.toString();
return (minutesstring.padStart(2, "0") + ":" + secondsstring.padStart(2, "0"))
}
//funcao que move o rover utilizando uma lista de comandos criada pelas 4 funcoes anteriores
function enviar(){
//cria um backup da posicao atual
let positionBackup = currentPosition;
for(let i = 0; i<array.length; i++){
//faz com que o valor de movimento seja igual ao movimento a ser executado, ou seja, igual a algum valor da lista (array) de movimentos a serem executados
let movementValue = parseFloat(array[i]);
//testa a posicao para garantir que o rover nao saia da matriz a seguir:
//00-01-02-03
//04-05-06-07
//08-09-10-11
//12-13-14-15
let positionTest = currentPosition + movementValue;
//um IF ELSE que move o rover caso o teste de posicao de um resultado entre 0 e 15 ou mantem o rover na mesma posicao em caso de algum outro resultado
//tambem checa se o rover esta em alguma borda da matriz, caso esteja, nao deixa usar o movimento lateral para ir para a linha de baixo ou de cima
if(positionTest<0 || positionTest>15 || canGoRight == false && movementValue == 1 || canGoLeft == false && movementValue == -1){
//se estiver no modo true modo, ou seja, modo A, cancela TODOS os movimentos APOS o movimento invalido
if(mode==true || mode=="true"){
i = array.length + 1;
}
//se estiver no modo false, ou seja, modo A, cancela APENAS o movimento invalido
else{
movementValue = positionBackup
}
}
else{
currentPosition = currentPosition + movementValue;
}
//IF ELSE que verifica se a posicao atual esta em alguma borda da matriz e muda as bools que definem se o rover esta em uma borda ou nao de acordo, caso esteja em uma borda, nao deixa o rover realizar movimentos verticais usando movimentos laterais, ou seja, nao deixa ir da posicao 3 para a 4 usando o movimento "direita"
//caso a posicao seja 0 OU a posicao seja divisil por 4, ja que os unicos numeros divisiveis por 4 sao os da borda esquerda, nota-se que 0/4=infinidade, e o metodo isInteger considera inifinidade um int, logo, o codigo acaba considerando 0 divisivel por 4
if(Number.isInteger(currentPosition/4)){
canGoLeft = false;
canGoRight = true;
}
//caso a posicao esteja em uma array de posicoes, sabe-se que ela esta na borda direita, tentei usar operacoes matematicas aqui mas nao cheguei em nenhuma que desse um resultado para 3, 7, 11 e 15 e outro para os demais numeros da matriz
else if(rightBorder.includes(currentPosition)){
canGoLeft = true;
canGoRight = false;
}
//se chegar ate esse else significa que nao esta em nenhuma das bordas
else{
canGoLeft = true;
canGoRight = true;
}
}
//muda a imagem do mapa para o mapa correspondente a posicao atual
document.getElementById("map").src="images/map"+currentPosition+".png";
//atualiza o texto de posicao para mostrar a posicao do rover
document.getElementById("position").innerHTML = "Posicao = " + currentPosition;
//limpa a lista de movimentos pendentes, lembrando que essa lista server apenas para auxiliar o usuario
document.getElementById("historico").innerHTML = "Movimentos pendentes: ";
//limpa a lista de movimentos a serem executados
array = [];
//volta a variavel "firstprint" para true, desse jeito, o proximo movimento na lista de movimentos pendentes NAO tera uma virgula antes
firstprint = true;
//envia a posicao atual do rover para o cache do navegador, dessa forma, o rover continuara na mesma posicao quando o usuario abrir o site novamente
localStorage.setItem("currentPosition", currentPosition);
document.getElementById("enviartext").innerHTML = "Enviar";
array = [];
localStorage.setItem("array", array);
}
//fucao que atualiza a posicao do rover baseado no cache do navegador
function positionUpdate(){
//muda a imagem do mapa para o mapa correspondente a posicao atual
document.getElementById("map").src="images/map"+currentPosition+".png";
//atualiza o texto de posicao para mostrar a posicao do rover
document.getElementById("position").innerHTML = "Posicao = " + currentPosition;
//IF ELSE que verifica se a posicao atual esta em alguma borda da matriz e muda as bools que definem se o rover esta em uma borda ou nao de acordo, caso esteja em uma borda, nao deixa o rover realizar movimentos verticais usando movimentos laterais, ou seja, nao deixa ir da posicao 3 para a 4 usando o movimento "direita"
//caso a posicao seja 0 OU a posicao seja divisil por 4, ja que os unicos numeros divisiveis por 4 sao os da borda esquerda, nota-se que 0/4=infinidade, e o metodo isInteger considera inifinidade um int, logo, o codigo acaba considerando 0 divisivel por 4
if(Number.isInteger(currentPosition/4)){
canGoLeft = false;
canGoRight = true;
}
//caso a posicao esteja em uma array de posicoes, sabe-se que ela esta na borda direita, tentei usar operacoes matematicas aqui mas nao cheguei em nenhuma que desse um resultado para 3, 7, 11 e 15 e outro para os demais numeros da matriz
else if(rightBorder.includes(currentPosition)){
canGoLeft = true;
canGoRight = false;
}
//se chegar ate esse else significa que nao esta em nenhuma das bordas
else{
canGoLeft = true;
canGoRight = true;
}
}
//funcao que muda a bool "mode" dependendo do switch que tem em cima do mapa, o valor "true" corresponde ao modo B e o valor "false" corresponde ao modo A
//tambem envia o modo selecionado para o cache do navegador, dessa forma, o modo continuara igual quando o usuario abrir o site novamente
function modeswitch(){
if(document.getElementById("modeswitch").checked){
localStorage.setItem("mode", true);
mode = true;
}
else{
localStorage.setItem("mode", false);
mode = false;
}
}
function delayswitch(){
if(document.getElementById("delayswitch").checked){
localStorage.setItem("delay", true);
delay = true;
}
else{
localStorage.setItem("delay", false);
delaytime = 0;
delay = false;
}
}
//funcao que abre o pop-up que explica os modos
function openhelp(){
document.getElementById("helpcontainer").style.visibility = "visible";
document.getElementById("buttoncontainer").style.visibility = "hidden";
}
//funcao que fecha o pop-up que explica os modos
function closehelp(){
document.getElementById("helpcontainer").style.visibility = "hidden";
document.getElementById("buttoncontainer").style.visibility = "visible";
}
function openhelpDelay(){
document.getElementById("helpcontainerDelay").style.visibility = "visible";
document.getElementById("buttoncontainer").style.visibility = "hidden";
}
function closehelpDelay(){
document.getElementById("helpcontainerDelay").style.visibility = "hidden";
document.getElementById("buttoncontainer").style.visibility = "visible";
}
function updateDelaySecondsInitial(){
delaySeconds = parseInt(localStorage.delaySeconds);
document.getElementById("delaySeconds").value = delaySeconds;
if(isNaN(delaySeconds)){
delaySeconds = 1200;
document.getElementById("delaySeconds").value = delaySeconds;
}
updateDelaySeconds();
}
function updateDelaySeconds(){
//mantem o input no range desejado
if(parseInt(document.getElementById("delaySeconds").value) > 3600){
document.getElementById("delaySeconds").value = 3600;
}
if(parseInt(document.getElementById("delaySeconds").value) < 5 || document.getElementById("delaySeconds").value === ""){
document.getElementById("delaySeconds").value = 5;
}
//transforma de float para int caso necessario
delaySeconds = parseInt(document.getElementById("delaySeconds").value);
document.getElementById("delaySeconds").value = delaySeconds;
localStorage.setItem("delaySeconds", delaySeconds);
delayValue = delaySeconds;
//multiplica o tempo em segundos pela velocidade da luz para descobrir a distancia e divide por 2000 pois: divide por 1000 para transformar de metros em KM, divide por 2 para descobrir apenas a distancia de ida.
delayKilometers = Math.trunc((delaySeconds * 299792458)/2000);
document.getElementById("delayKilometers").value = delayKilometers;
}
function updateDelayKilometers(){
//mantem o input no range desejado
if(parseInt(document.getElementById("delayKilometers").value) > 539626424){
document.getElementById("delayKilometers").value = 539626424;
}
if(parseInt(document.getElementById("delayKilometers").value) < 749481 || document.getElementById("delayKilometers").value === ""){
document.getElementById("delayKilometers").value = 749481;
}
//transforma de float para int caso necessario
delayKilometers = parseInt(document.getElementById("delayKilometers").value);
document.getElementById("delayKilometers").value = delayKilometers;
delaySeconds = Math.trunc(((delayKilometers*2000)/299792458)+1);
delayValue = delaySeconds;
document.getElementById("delaySeconds").value = delaySeconds;
}