PageSourceSearch

https://ball-labyrinth-game.web.app/js/classes/LevelProgress.js

js ball-labyrinth-game.web.app collected 2026-10-03 12:17:40 UTC 4,460 bytes, 146 lines download raw bytes

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.