51 for (var i = 0; i < 4; i++) |
51 for (var i = 0; i < 4; i++) |
52 for (var j = 0; j < 4; j++) |
52 for (var j = 0; j < 4; j++) |
53 this.brd[i][j] = brd[i][j]; |
53 this.brd[i][j] = brd[i][j]; |
54 } |
54 } |
55 } |
55 } |
56 BoardArr.prototype.get = function(i, j) { |
56 BoardArr2d.prototype.get = function(i, j) { |
57 return this.brd[i][j]; |
57 return this.brd[i][j]; |
58 } |
58 } |
59 BoardArr.prototype.set = function(i, j, val) { |
59 BoardArr2d.prototype.set = function(i, j, val) { |
60 this.brd[i][j] = val; |
60 this.brd[i][j] = val; |
61 } |
61 } |
62 /* Return and optionally fill 2d board. */ |
62 /* Return and optionally fill 2d board. */ |
63 BoardArr.prototype.exportTo = function(brd) { |
63 BoardArr2d.prototype.exportTo = function(brd) { |
64 brd = brd || [[],[],[],[]]; |
64 brd = brd || [[],[],[],[]]; |
65 for (var i = 0; i < 4; i++) |
65 for (var i = 0; i < 4; i++) |
66 for (var j = 0; j < 4; j++) |
66 for (var j = 0; j < 4; j++) |
67 brd[i][j] = this.brd[i][j]; |
67 brd[i][j] = this.brd[i][j]; |
68 return brd; |
68 return brd; |
71 brd = brd || new BoardArr2d(); |
71 brd = brd || new BoardArr2d(); |
72 for (var i = 0; i < 4; i++) |
72 for (var i = 0; i < 4; i++) |
73 for (var j = 0; j < 4; j++) |
73 for (var j = 0; j < 4; j++) |
74 brd.brd[i][j] = this.brd[i][j]; |
74 brd.brd[i][j] = this.brd[i][j]; |
75 return brd; |
75 return brd; |
|
76 } |
|
77 BoardArr2d.prototype.score = function() { |
|
78 var score = 0; |
|
79 for (var i = 0; i < 4; i++) { |
|
80 for (var j = 0; j < 4; j++) { |
|
81 var v = this.brd[i][j]; |
|
82 if (v > 0) |
|
83 score += (v-1)*Math.pow(2, v); |
|
84 } |
|
85 } |
|
86 return score; |
76 } |
87 } |
77 |
88 |
78 BoardArr2d.prototype.canRight = function() { |
89 BoardArr2d.prototype.canRight = function() { |
79 for (var i = 0; i < 4; i++) { |
90 for (var i = 0; i < 4; i++) { |
80 var f0 = this.brd[i][0], f1 = this.brd[i][1], f2 = this.brd[i][2], f3 = this.brd[i][3]; |
91 var f0 = this.brd[i][0], f1 = this.brd[i][1], f2 = this.brd[i][2], f3 = this.brd[i][3]; |
223 } |
234 } |
224 } |
235 } |
225 } |
236 } |
226 } |
237 } |
227 |
238 |
228 BoardArr2d.prototype.shiftLeft_mostly_unrolled = function(brd) { |
239 BoardArr2d.prototype.shiftRight_mostly_unrolled = function(brd) { |
|
240 var updated = false; |
229 var from = this.brd, to = brd.brd; |
241 var from = this.brd, to = brd.brd; |
230 for (var i = 3; i >= 0; i--) { |
242 for (var i = 0; i < 4; i++) { |
|
243 var moved = true; |
231 var f0 = from[i][0], f1 = from[i][1], f2 = from[i][2], f3 = from[i][3]; |
244 var f0 = from[i][0], f1 = from[i][1], f2 = from[i][2], f3 = from[i][3]; |
232 if (f3 === 0) { |
245 if (f3 === 0) { |
233 if (f2 === 0) { |
246 if (f2 === 0) { |
234 if (f1 === 0) { // a 0 0 0 |
247 if (f1 === 0) { // a 0 0 0 |
|
248 if (f0 === 0) |
|
249 moved = false; |
235 f3 = f0; |
250 f3 = f0; |
236 f2 = 0; |
251 f2 = 0; |
237 } else { // a b 0 0 |
252 } else { // a b 0 0 |
238 f3 = f1; |
253 f3 = f1; |
239 f2 = f0; |
254 f2 = f0; |
240 } |
255 } |
241 f1 = 0; |
256 f1 = 0; |
242 } else { // f2 !== 0 && f3 === 0 |
257 } else { // f2 !== 0 && f3 === 0 |
243 if (f1 === 0) { // a 0 b 0 |
258 if (f1 === 0) { // a 0 b 0 |
244 f3 = f2; |
259 f3 = f2; |
245 f2 = f0; |
260 f2 = f0; |
246 } else { // a b c 0 |
261 } else { // a b c 0 |
247 f3 = f2; |
262 f3 = f2; |
248 f2 = f1; |
263 f2 = f1; |
249 f1 = f0; |
264 f1 = f0; |
250 } |
265 } |
251 } |
266 } |
252 f0 = 0; |
267 f0 = 0; |
253 } else { // f3 !== 0 |
268 } else { // f3 !== 0 |
254 if (f2 === 0) { |
269 if (f2 === 0) { |
255 if (f1 === 0) { // a 0 0 b |
270 if (f1 === 0) { // a 0 0 b |
|
271 if (f0 === 0) |
|
272 moved = false; |
256 f2 = f0; |
273 f2 = f0; |
257 } else { // a b 0 c |
274 } else { // a b 0 c |
258 f2 = f1; |
275 f2 = f1; |
259 f1 = f0; |
276 f1 = f0; |
260 } |
277 } |
261 f0 = 0; |
278 f0 = 0; |
262 } else { // f2 !== 0 && f3 !== 0 |
279 } else { // f2 !== 0 && f3 !== 0 |
263 if (f1 === 0) { // a 0 b c |
280 if (f1 === 0) { // a 0 b c |
|
281 if (f0 === 0) |
|
282 moved = false; |
264 f1 = f0; |
283 f1 = f0; |
265 f0 = 0; |
284 f0 = 0; |
266 } // else: a b c d |
285 } else { // else: a b c d |
267 } |
286 moved = false; |
268 } |
287 } |
|
288 } |
|
289 } |
|
290 updated = updated || moved; |
269 if (f2 === 0) { |
291 if (f2 === 0) { |
270 to[i][0] = 0; |
292 to[i][0] = 0; |
271 to[i][1] = 0; |
293 to[i][1] = 0; |
272 to[i][2] = 0; |
294 to[i][2] = 0; |
273 to[i][3] = f3; |
295 to[i][3] = f3; |
296 to[i][2] = f1; |
320 to[i][2] = f1; |
297 } |
321 } |
298 } else { |
322 } else { |
299 to[i][3] = f3; |
323 to[i][3] = f3; |
300 if (f1 === f2) { |
324 if (f1 === f2) { |
|
325 updated = true; |
301 to[i][0] = 0; |
326 to[i][0] = 0; |
302 to[i][1] = f0; |
327 to[i][1] = f0; |
303 to[i][2] = f2 + 1; |
328 to[i][2] = f2 + 1; |
304 } else { |
329 } else { |
|
330 if (f0 === f1) { |
|
331 updated = true; |
|
332 to[i][0] = 0; |
|
333 to[i][1] = f1+1; |
|
334 to[i][2] = f2; |
|
335 } else { |
|
336 to[i][0] = f0; |
|
337 to[i][1] = f1; |
|
338 to[i][2] = f2; |
|
339 } |
|
340 } |
|
341 } |
|
342 } |
|
343 return updated; |
|
344 } |
|
345 BoardArr2d.prototype.shiftDown_mostly_unrolled = function(brd) { |
|
346 var updated = false; |
|
347 var from = this.brd, to = brd.brd; |
|
348 for (var j = 0; j < 4; j++) { |
|
349 var moved = true; |
|
350 var f0 = from[0][j], f1 = from[1][j], f2 = from[2][j], f3 = from[3][j]; |
|
351 if (f3 === 0) { |
|
352 if (f2 === 0) { |
|
353 if (f1 === 0) { // a 0 0 0 |
|
354 if (f0 === 0) |
|
355 moved = false; |
|
356 f3 = f0; |
|
357 f2 = 0; |
|
358 } else { // a b 0 0 |
|
359 f3 = f1; |
|
360 f2 = f0; |
|
361 } |
|
362 f1 = 0; |
|
363 } else { // f2 !== 0 && f3 === 0 |
|
364 if (f1 === 0) { // a 0 b 0 |
|
365 f3 = f2; |
|
366 f2 = f0; |
|
367 } else { // a b c 0 |
|
368 f3 = f2; |
|
369 f2 = f1; |
|
370 f1 = f0; |
|
371 } |
|
372 } |
|
373 f0 = 0; |
|
374 } else { // f3 !== 0 |
|
375 if (f2 === 0) { |
|
376 if (f1 === 0) { // a 0 0 b |
|
377 if (f0 === 0) |
|
378 moved = false; |
|
379 f2 = f0; |
|
380 } else { // a b 0 c |
|
381 f2 = f1; |
|
382 f1 = f0; |
|
383 } |
|
384 f0 = 0; |
|
385 } else { // f2 !== 0 && f3 !== 0 |
|
386 if (f1 === 0) { // a 0 b c |
|
387 if (f0 === 0) |
|
388 moved = false; |
|
389 f1 = f0; |
|
390 f0 = 0; |
|
391 } else { // else: a b c d |
|
392 moved = false; |
|
393 } |
|
394 } |
|
395 } |
|
396 updated = updated || moved; |
|
397 if (f2 === 0) { |
|
398 to[0][j] = 0; |
|
399 to[1][j] = 0; |
|
400 to[2][j] = 0; |
|
401 to[3][j] = f3; |
|
402 continue; |
|
403 } |
|
404 if (f1 === 0) { |
|
405 to[0][j] = 0; |
|
406 to[1][j] = 0; |
|
407 if (f2 === f3) { |
|
408 to[2][j] = 0; |
|
409 to[3][j] = f3 + 1; |
|
410 updated = true; |
|
411 } else { |
|
412 to[2][j] = f2; |
|
413 to[3][j] = f3; |
|
414 } |
|
415 continue; |
|
416 } |
|
417 if (f2 === f3) { |
|
418 updated = true; |
|
419 to[0][j] = 0; |
|
420 to[3][j] = f3 + 1; |
|
421 if (f0 === f1) { |
|
422 to[1][j] = 0; |
|
423 to[2][j] = f1 + 1; |
|
424 } else { |
|
425 to[1][j] = f0; |
|
426 to[2][j] = f1; |
|
427 } |
|
428 } else { |
|
429 to[3][j] = f3; |
|
430 if (f1 === f2) { |
|
431 updated = true; |
|
432 to[0][j] = 0; |
|
433 to[1][j] = f0; |
|
434 to[2][j] = f2 + 1; |
|
435 } else { |
|
436 if (f0 === f1) { |
|
437 updated = true; |
|
438 to[0][j] = 0; |
|
439 to[1][j] = f1+1; |
|
440 to[2][j] = f2; |
|
441 } else { |
|
442 to[0][j] = f0; |
|
443 to[1][j] = f1; |
|
444 to[2][j] = f2; |
|
445 } |
|
446 } |
|
447 } |
|
448 } |
|
449 return updated; |
|
450 } |
|
451 BoardArr2d.prototype.shiftLeft_mostly_unrolled = function(brd) { |
|
452 var updated = false; |
|
453 var from = this.brd, to = brd.brd; |
|
454 for (var i = 0; i < 4; i++) { |
|
455 var moved = true; |
|
456 var f0 = from[i][0], f1 = from[i][1], f2 = from[i][2], f3 = from[i][3]; |
|
457 if (f0 === 0) { |
|
458 if (f1 === 0) { |
|
459 if (f2 === 0) { // 0 0 0 a |
|
460 if (f3 === 0) |
|
461 moved = false; |
|
462 f0 = f3; |
|
463 f1 = 0; |
|
464 } else { // 0 0 a b |
|
465 f0 = f2; |
|
466 f1 = f3; |
|
467 } |
|
468 f2 = 0; |
|
469 } else { // f1 !== 0 && f0 === 0 |
|
470 if (f2 === 0) { // 0 a 0 b |
|
471 f0 = f1; |
|
472 f1 = f3; |
|
473 } else { // 0 a b c |
|
474 f0 = f1; |
|
475 f1 = f2; |
|
476 f2 = f3; |
|
477 } |
|
478 } |
|
479 f3 = 0; |
|
480 } else { // f0 !== 0 |
|
481 if (f1 === 0) { |
|
482 if (f2 === 0) { // a 0 0 b |
|
483 if (f3 === 0) |
|
484 moved = false; |
|
485 f1 = f3; |
|
486 } else { // a 0 b c |
|
487 f1 = f2; |
|
488 f2 = f3; |
|
489 } |
|
490 f3 = 0; |
|
491 } else { // f1 !== 0 && f0 !== 0 |
|
492 if (f2 === 0) { // a b 0 c |
|
493 if (f3 === 0) |
|
494 moved = false; |
|
495 f2 = f3; |
|
496 f3 = 0; |
|
497 } else { // else: a b c d |
|
498 moved = false; |
|
499 } |
|
500 } |
|
501 } |
|
502 updated = updated || moved; |
|
503 if (f1 === 0) { // a 0 0 0 |
|
504 to[i][3] = 0; |
|
505 to[i][2] = 0; |
|
506 to[i][1] = 0; |
|
507 to[i][0] = f0; |
|
508 continue; |
|
509 } |
|
510 if (f2 === 0) { |
|
511 to[i][3] = 0; |
|
512 to[i][2] = 0; |
|
513 if (f1 === f0) { // a a 0 0 |
|
514 updated = true; |
|
515 to[i][1] = 0; |
|
516 to[i][0] = f0 + 1; |
|
517 } else { // a b 0 0 |
|
518 to[i][1] = f1; |
305 to[i][0] = f0; |
519 to[i][0] = f0; |
|
520 } |
|
521 continue; |
|
522 } |
|
523 if (f1 === f0) { |
|
524 updated = true; |
|
525 to[i][3] = 0; |
|
526 to[i][0] = f0 + 1; |
|
527 if (f3 === f2) { // a a b b |
|
528 to[i][2] = 0; |
|
529 to[i][1] = f2 + 1; |
|
530 } else { // a a b c |
|
531 to[i][2] = f3; |
|
532 to[i][1] = f2; |
|
533 } |
|
534 } else { |
|
535 to[i][0] = f0; |
|
536 if (f2 === f1) { // a b b c |
|
537 updated = true; |
|
538 to[i][3] = 0; |
|
539 to[i][2] = f3; |
|
540 to[i][1] = f1 + 1; |
|
541 } else { |
306 to[i][1] = f1; |
542 to[i][1] = f1; |
307 to[i][2] = f2; |
543 if (f2 === f3) { // a b c c |
308 } |
544 updated = true; |
309 } |
545 to[i][3] = 0; |
310 } |
546 to[i][2] = f2+1; |
311 } |
547 } else { // a b c d |
|
548 to[i][3] = f3; |
|
549 to[i][2] = f2; |
|
550 } |
|
551 } |
|
552 } |
|
553 } |
|
554 return updated; |
|
555 } |
|
556 BoardArr2d.prototype.shiftUp_mostly_unrolled = function(brd) { |
|
557 var updated = false; |
|
558 var from = this.brd, to = brd.brd; |
|
559 for (var j = 0; j < 4; j++) { |
|
560 var moved = true; |
|
561 var f0 = from[0][j], f1 = from[1][j], f2 = from[2][j], f3 = from[3][j]; |
|
562 if (f0 === 0) { |
|
563 if (f1 === 0) { |
|
564 if (f2 === 0) { // 0 0 0 a |
|
565 if (f3 === 0) |
|
566 moved = false; |
|
567 f0 = f3; |
|
568 f1 = 0; |
|
569 } else { // 0 0 a b |
|
570 f0 = f2; |
|
571 f1 = f3; |
|
572 } |
|
573 f2 = 0; |
|
574 } else { // f1 !== 0 && f0 === 0 |
|
575 if (f2 === 0) { // 0 a 0 b |
|
576 f0 = f1; |
|
577 f1 = f3; |
|
578 } else { // 0 a b c |
|
579 f0 = f1; |
|
580 f1 = f2; |
|
581 f2 = f3; |
|
582 } |
|
583 } |
|
584 f3 = 0; |
|
585 } else { // f0 !== 0 |
|
586 if (f1 === 0) { |
|
587 if (f2 === 0) { // a 0 0 b |
|
588 if (f3 === 0) |
|
589 moved = false; |
|
590 f1 = f3; |
|
591 } else { // a 0 b c |
|
592 f1 = f2; |
|
593 f2 = f3; |
|
594 } |
|
595 f3 = 0; |
|
596 } else { // f1 !== 0 && f0 !== 0 |
|
597 if (f2 === 0) { // a b 0 c |
|
598 if (f3 === 0) |
|
599 moved = false; |
|
600 f2 = f3; |
|
601 f3 = 0; |
|
602 } else { // else: a b c d |
|
603 moved = false; |
|
604 } |
|
605 } |
|
606 } |
|
607 updated = updated || moved; |
|
608 if (f1 === 0) { // a 0 0 0 |
|
609 to[3][j] = 0; |
|
610 to[2][j] = 0; |
|
611 to[1][j] = 0; |
|
612 to[0][j] = f0; |
|
613 continue; |
|
614 } |
|
615 if (f2 === 0) { |
|
616 to[3][j] = 0; |
|
617 to[2][j] = 0; |
|
618 if (f1 === f0) { // a a 0 0 |
|
619 updated = true; |
|
620 to[1][j] = 0; |
|
621 to[0][j] = f0 + 1; |
|
622 } else { // a b 0 0 |
|
623 to[1][j] = f1; |
|
624 to[0][j] = f0; |
|
625 } |
|
626 continue; |
|
627 } |
|
628 if (f1 === f0) { |
|
629 to[3][j] = 0; |
|
630 to[0][j] = f0 + 1; |
|
631 if (f3 === f2) { // a a b b |
|
632 updated = true; |
|
633 to[2][j] = 0; |
|
634 to[1][j] = f2 + 1; |
|
635 } else { // a a b c |
|
636 to[2][j] = f3; |
|
637 to[1][j] = f2; |
|
638 } |
|
639 } else { |
|
640 to[0][j] = f0; |
|
641 if (f2 === f1) { // a b b c |
|
642 updated = true; |
|
643 to[3][j] = 0; |
|
644 to[2][j] = f3; |
|
645 to[1][j] = f1 + 1; |
|
646 } else { |
|
647 to[1][j] = f1; |
|
648 if (f2 === f3) { // a b c c |
|
649 updated = true; |
|
650 to[3][j] = 0; |
|
651 to[2][j] = f2+1; |
|
652 } else { // a b c d |
|
653 to[3][j] = f3; |
|
654 to[2][j] = f2; |
|
655 } |
|
656 } |
|
657 } |
|
658 } |
|
659 return updated; |
|
660 } |
|
661 |
|
662 BoardArr2d.prototype.left = BoardArr2d.prototype.shiftLeft_mostly_unrolled; |
|
663 BoardArr2d.prototype.right = BoardArr2d.prototype.shiftRight_mostly_unrolled; |
|
664 BoardArr2d.prototype.up = BoardArr2d.prototype.shiftUp_mostly_unrolled; |
|
665 BoardArr2d.prototype.down = BoardArr2d.prototype.shiftDown_mostly_unrolled; |
312 |
666 |
313 |
667 |
314 |
668 |
315 //////////////////////////////////////////////////////////////// |
669 //////////////////////////////////////////////////////////////// |
316 // Board as properties. |
670 // Board as properties. |