PageSourceSearch

https://svitlobot.in.ua/js/snake/snake-logic.js

js svitlobot.in.ua collected 2026-10-08 13:53:39 UTC 9,836 bytes, 396 lines download raw bytes

1function viv() {
2    let s = ".\n";
3    for (let i in arr) {
4        for (let j in arr[i]) {
5            s += arr[i][j] + " ";
6        }
7        s = s.trim() + "\n";
8    }
9    console.log(s);
10}
11
12let snake_length_start = 4;
13let snake_length = snake_length_start;
14let snake_direction = 0; // 0 = right, 1 = down, 2 = left, 3 = up
15var game_interval = null;
16var game_ended_time = null;
17var game_speed_start = 350;
18var game_speed_min = 100;
19var game_speed = game_speed_start;
20var last_game_loop = null;
21
22function rnd(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }
23
24
25function generateSnake() {    
26    let start_pos_j = rnd(2, (arr[0].length / 3));
27    let start_pos_i = rnd(2, 3);
28    if (start_pos_i == 3) start_pos_i = 4;    
29    
30
31    for (let i = 0; i < snake_length; i++) {
32        arr[start_pos_i][start_pos_j + i] = i + 1;
33    }  
34}
35
36function getMaxBelow1000() {
37    let maxVal = 0;
38    for (let i = 0; i < arr.length; i++) {
39        for (let j = 0; j < arr[i].length; j++) {
40            if (arr[i][j] < 1000 && arr[i][j] > maxVal) {
41                maxVal = arr[i][j];
42            }
43        }
44    }
45    return maxVal;
46}
47
48function printText(text) {
49    $("#label_for_table").html(text);
50}
51
52function printTextOnScreen(text) {
53    clearTextFromScreen();
54    var el = $("<div id='onscreentext'></div>");
55    el.css({
56        'font-size': '40px',
57        'text-align': 'center',
58        'width': '100%',
59        'position': 'absolute',
60        'top': '330px',
61        'z-index': '999'
62    });
63    var el_text = $("<span>" + text + "</span>");
64    el_text.css({
65        "text-shadow": "rgba(0, 0, 0, 0.2) 2px 2px 10px"
66    });
67    el.append(el_text);
68    $("body").append(el);
69    $("#inside_container").css({
70        "opacity": "0.35",
71        "pointer-events": "none",
72    });
73}
74
75function clearTextFromScreen() {
76    $("#onscreentext").remove();  
77    $("#inside_container").css({
78        "opacity": "1",
79        "pointer-events": "auto",
80    });  
81}
82
83function getScore() {
84    return snake_length - snake_length_start;
85}
86
87function printScore() {
88    printText("Отримано світла: " + getScore());
89}
90
91function sendScoreToLeaderboard(score) {
92    let query = "https://api.svitlobot.in.ua/snakeGame/gameOverScore?score=" + score;
93    $.get(query);
94}
95
96function gameOver() {
97    let score = getScore();
98    sendScoreToLeaderboard(score);
99    printText("Отримано світла: " + score);
100    printTextOnScreen("Game Over!<br>Натисніть WASD або ↑ ← → ↓");
101    clearInterval(game_interval);
102    game_interval = null;
103    game_ended_time = new Date().getTime();
104    printTable();
105    viv();  
106}
107
108function moveSnake() {
109    let head;
110    let tail;
111
112    let maxSnakeVal = getMaxBelow1000();
113
114    // Find the head and the tail of the snake
115    for (let i = 0; i < arr.length; i++) {
116        for (let j = 0; j < arr[i].length; j++) {
117            if (arr[i][j] === 1) {
118                tail = [i, j];
119            } else if (arr[i][j] === maxSnakeVal) {
120                head = [i, j];
121            }
122        }
123    }
124
125    // Determine the new head position based on the direction
126    let newHead = [...head];
127    switch (snake_direction) {
128        case 0:
129            newHead[1]++;
130            break;
131        case 1:
132            newHead[0]++;
133            break;
134        case 2:
135            newHead[1]--;
136            break;
137        case 3:
138            newHead[0]--;
139            break;
140    }
141
142    if (newHead[0] >= arr.length) newHead[0] = 0;
143    if (newHead[0] < 0) newHead[0] = arr.length - 1;
144    if (newHead[1] >= arr[0].length) newHead[1] = 0;
145    if (newHead[1] < 0) newHead[1] = arr[0].length - 1;
146    
147
148    let isAppleEaten = false;
149
150    // Check for apple
151    if (arr[newHead[0]][newHead[1]] === 1000) {
152        // Add apple consumption logic here, e.g., increase snake length
153        // For now, let's just reset the apple
154        snake_length++;
155        isAppleEaten = true;
156        game_speed = getGameSpeed(getScore());
157    }
158
159    if (!isAppleEaten) {
160        // Move the snake by incrementing all body parts
161        for (let i = 0; i < arr.length; i++) {
162            for (let j = 0; j < arr[i].length; j++) {
163                if (arr[i][j] > 0 && arr[i][j] < 1000) {
164                    arr[i][j]--;
165                }
166            }
167        }
168    }
169
170    if (!isAppleEaten && arr[newHead[0]][newHead[1]] > 0) {
171        arr[newHead[0]][newHead[1]] = -100;
172        gameOver();
173        return;
174    }
175
176    // Place the new head
177
178    
179    arr[newHead[0]][newHead[1]] = snake_length;
180
181}
182
183function spawnApple() {
184    let applePlaced = false;
185
186    while (!applePlaced) {
187        let i = rnd(0, arr.length - 1);
188        let j = rnd(0, arr[0].length - 1);
189
190        let maxSnakeVal = getMaxBelow1000();
191        let head = [];
192
193        // Find the head of the snake
194        for (let x = 0; x < arr.length; x++) {
195            for (let y = 0; y < arr[x].length; y++) {
196                if (arr[x][y] === maxSnakeVal) {
197                    head = [x, y];
198                }
199            }
200        }
201
202        let distance = Math.abs(head[0] - i) + Math.abs(head[1] - j);
203
204        // Check if the position is valid
205        if (arr[i][j] === 0 && distance > 5 && distance < 20) {
206            arr[i][j] = 1000;
207            applePlaced = true;
208        }
209    }
210}
211
212function checkApple() {
213   for (let i = 0; i < arr.length; i++) {
214        for (let j = 0; j < arr[i].length; j++) {
215            if (arr[i][j] == 1000) return;
216        }
217    }    
218    spawnApple();
219}
220
221let last_key_press = 0;
222let movementInputArray = [];
223
224function changeDirection(new_direction) {
225
226    if (!game_interval) {
227        startGame();
228    }
229
230    let t = new Date().getTime();
231    let diff = t - last_key_press;
232    let trs = game_speed;
233
234    if (diff < trs) {
235        movementInputArray.push(new_direction);
236    } else {
237        movementInputArray = [new_direction];
238    }
239    last_key_press = t;
240}
241
242function setButtonListeners() {
243
244    for (let i = 0; i < 4; i++) {
245        $("#btn_control_" + i).on("click", function(){
246            changeDirection(i);    
247        });    
248    }
249
250      
251}
252
253function keyboardListener(event) {    
254    switch (event.key) {
255        case 'ArrowUp':
256        case 'w':
257        case 'W':
258        case 'ц':
259        case 'Ц':
260            changeDirection(3);
261            break;
262        case 'ArrowDown':
263        case 's':
264        case 'S':
265        case 'ы':
266        case 'Ы':
267            changeDirection(1);
268            break;
269        case 'ArrowLeft':
270        case 'a':
271        case 'A':
272        case 'ф':
273        case 'Ф':
274            changeDirection(2);
275            break;
276        case 'ArrowRight':
277        case 'd':
278        case 'D':
279        case 'в':
280        case 'В':
281            changeDirection(0);
282            break;
283    }
284}
285
286function handleMovementInput() {
287    if (!movementInputArray || movementInputArray.length == 0) return;
288
289    let direction = movementInputArray[0];
290    if (Math.abs(snake_direction - direction) == 2 && movementInputArray.length != 2) {        
291      movementInputArray.shift();      
292      return; // opposite movement
293    }
294    if (movementInputArray.length > 1 && (Math.abs(snake_direction - direction) == 2 || snake_direction == direction)) {  
295      //swap
296      
297      if (Math.abs(movementInputArray[1] - snake_direction) != 2) snake_direction = movementInputArray[1];
298      movementInputArray[1] = direction;
299      movementInputArray.shift();
300      return;
301    }
302
303    snake_direction = direction;
304    movementInputArray.shift();
305}
306
307function getGameSpeed(score) {
308    const max_score = 25;
309
310    if (score < 0) {
311        throw new Error("Score must be a positive number.");
312    }
313
314    var max_speed = game_speed_start * 0.7;
315
316    // Calculate the speed factor (linear decrease)
317    const speedFactor = (max_speed - game_speed_min) / max_score;
318    
319    // Calculate the new speed
320    let newSpeed = max_speed - (score * speedFactor);
321
322    // Ensure the speed doesn't go below the minimum speed
323    if (score >= max_score) {
324        newSpeed = game_speed_min;
325    }
326
327    return newSpeed;
328}
329
330function gameLoop() {
331    
332
333    /* let s = "";
334    for (let i = 0; i < movementInputArray.length; i++) {
335        s += movementInputArray[i];
336        if (i != movementInputArray - 1) s += ", ";
337    }
338    printText("Moves: " + s); */
339
340    let t = new Date().getTime();
341    if (last_game_loop) {
342        if (t - last_game_loop < game_speed) return;
343    }
344    last_game_loop = t;
345
346    handleMovementInput();
347
348    moveSnake();
349    if (!game_interval) return;
350    //viv();
351    printTable();
352    checkApple();    
353    printScore();
354
355
356
357    
358}
359
360function initGameState() {
361    //clear array
362    for (let i = 0; i < arr.length; i++) {
363        for (let j = 0; j < arr[0].length; j++) {
364            arr[i][j] = 0;
365        }
366    }  
367     
368    movementInputArray = []
369    snake_length = snake_length_start;
370    snake_direction = 0; 
371    game_speed = game_speed_start;  
372
373    generateSnake();
374    spawnApple(); 
375    printTable();
376}
377
378function startGame() {
379    if (game_ended_time) {
380        if (new Date().getTime() - game_ended_time < 400) return;
381        initGameState();           
382    }    
383
384    game_interval = setInterval(gameLoop, 10);
385    clearTextFromScreen();
386}
387
388function initGame() {
389    setButtonListeners();
390    initGameState();   
391
392    document.addEventListener('keydown', keyboardListener);
393
394    printTextOnScreen("Натисніть WASD або ↑ ← → ↓");
395    
396}

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.