1const actualMoveId = 'actualMove'; 2const targetMovesId = 'targetMoves'; 3const bestMovesId = 'bestMoves'; 4const packNameId = 'packName'; 5const currentLevelId = 'currentLevel'; 6 7class LevelProgress { 8 constructor (mode=STAR_MODE, pack=0, currentLevel=0, hints, bestMoves=0) { 9 this.mode = mode; 10 this.pack = pack; 11 this.currentLevel = currentLevel; 12 this.hints = hints; 13 this.started = false; 14 this.targetMoves = hints.length; 15 this.bestMoves = bestMoves; 16 17 this.startTime = seconds() 18 this.duration = 0 19 20 this.moves = { 21 current: 0, 22 target: 0, 23 best: 0 24 }; 25 26 this.stars = { 27 current: 0, 28 best: 0 29 }; 30 31 this.undoList = []; 32 33 this.initUI = this.initUI.bind(this); 34 this.nextMove = this.nextMove.bind(this); 35 this.nextHint = this.nextHint.bind(this); 36 this.starCollected = this.starCollected.bind(this); 37 this.refreshBest = this.refreshBest.bind(this); 38 this.getLevelState = this.getLevelState.bind(this); 39 this.refreshHints = this.refreshHints.bind(this); 40 this.betterThanExpected = this.betterThanExpected.bind(this); 41 this.addUndo = this.addUndo.bind(this); 42 this.undo = this.undo.bind(this); 43 this.starsEarned = this.starsEarned.bind(this) 44 45 this.initUI(); 46 }; 47 48 initUI() { 49 let packName = levels[this.mode][this.pack].name 50 get(packNameId).innerHTML = packName.length > 10 ? packName.substring(0, 10) + '...' : packName; 51 get(currentLevelId).innerHTML = this.currentLevel+1; 52 get(actualMoveId).innerHTML = '0'; 53 get(targetMovesId).innerHTML = '' + this.targetMoves; 54 get(bestMovesId).innerHTML = '' + this.bestMoves; 55 56 this.refreshHints(); 57 58 this.starsEarned(0) 59 get('boardScreen').classList.remove(UNDO); 60 } 61 62 starsEarned (amount) { 63 let curAmount = get(BOARD_STARS_ID).getAttribute('earned') 64 if (curAmount) get(BOARD_STARS_ID).classList.remove('earned' + curAmount) 65 66 get(BOARD_STARS_ID).setAttribute('earned', amount) 67 get(BOARD_STARS_ID).classList.add('earned' + amount) 68 } 69 70 nextMove(increment=1) { 71 this.moves.current += increment; 72 get(actualMoveId).innerHTML = '' + this.moves.current; 73 } 74 75 nextHint() { 76 if (this.hints) { 77 if (this.hints.length > 0) { 78 let hintAfterStart = this.hints[0].distance > 0; 79 80 if (hintAfterStart && !this.started) { 81 this.started = true; 82 return new Hint().fromElementsPosition(['boardFooter', 'startGame']); 83 } else { 84 return new Hint().fromCellMove(this.hints.shift()); 85 } 86 } else { 87 if (!this.started) { 88 this.started = true; 89 return new Hint().fromElementsPosition(['boardFooter', 'startGame']); 90 } 91 } 92 } else { 93 return null; 94 } 95 } 96 97 refreshHints() { 98 get(BOARD_HINT_BTN_HINTS_ID).innerHTML = state.hints; 99 get(BOARD_HINT_BTN_HINTS_ID).classList.remove(TRIPPLE); 100 get(BOARD_HINT_BTN_HINTS_ID).classList.add(state.hints > 99 ? TRIPPLE : ""); 101 } 102 103 starCollected() { 104 ++this.stars.current 105 this.starsEarned(this.stars.current) 106 } 107 108 refreshBest() { 109 if (this.moves.current < this.moves.best) { 110 this.moves.best = this.moves.current; 111 } 112 } 113 114 getLevelState (calculateDuration = false) { 115 if (calculateDuration) { 116 this.duration = seconds() - this.startTime 117 } 118 return new LevelState(this.mode, this.pack, this.currentLevel, this.targetMoves, this.moves.current, this.stars.current, this.duration); 119 } 120 121 betterThanExpected() { 122 return this.stars.current === 3 && this.moves.current < this.targetMoves; 123 } 124 125 undo() { 126 if (this.undoList.length == 0) { 127 return null; 128 } 129 130 this.nextMove(-1) 131 const answer = this.undoList.pop() 132 133 if (this.undoList.length == 0) { 134 get('boardScreen').classList.remove(UNDO); 135 } 136 137 return answer 138 } 139 140 addUndo(newUndo) { 141 if (this.undoList.length == 0) { 142 get('boardScreen').classList.add(UNDO); 143 } 144 this.undoList.push(newUndo) 145 } 146}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.