// const API_URL = "http://127.0.0.1:8000/intelli-snake-2/" const API_URL = "https://intelli-snake-2-api.herokuapp.com/intelli-snake-2/" let loaded_infos = [] interval_var_fast = 0 let start_auto = 1 let mult = 1 // WRITING IN A FILE let file_writing = 0 let content = '' let data_line class Game { constructor () { // initializing constants and variables this.game_items = document.getElementsByClassName("game-item") this.info = { "map_type": "none", "map": 0, "parts": 2, "evade_bite": 0, "allowcollisions": 0, "score": 0, "fouls": 0, "interval_var": 0, "cache_dir": null, "prev_dir": null, "second_pref_count": 0, "mode": "paused", "steps": 0, "steps_limit": 60, "slow_time": 600, "fast_time": 200, "time": 200, "automated_infos_count": 50, "automated_time_update_freq": 1, "overflow_infos": 0, } // intializing the game this.get_map("fixed") btn_pause_auto.innerText = "Automate" } set_game_interval(func) { clearInterval(this.info.interval_var) this.info.interval_var = setInterval(func, this.info.time) } auto_key_move() { if (this.info.cache_dir != null) { if(game.move(this.info.cache_dir)) {this.info.prev_dir = this.info.cache_dir} else {game.move(this.info.prev_dir)} } } move(dir) { if (file_writing) {data_line = "\n" + JSON.stringify(this.info.map)} let h = this.info.map.indexOf(3) let n = 31*28 if (dir == 0) { n = h - cols } else if (dir == 1) { n = h - 1 } else if (dir == 2) { n = h + cols } else if (dir == 3) { n = h + 1 } // IF FOOD IS EATEN if (this.info.map[n] == 2) { this.info.score++ this.info.parts++ this.info.steps = 0 if (this.info.map_type == "random" && file_writing) { // LOADING NEW RANDOM MAP AFTER EATEN this.pause_game() this.get_map("random") return true } this.info.map[n] = this.info.parts+3 let r = Math.floor(Math.random() * (31*28)) while (this.info.map[r] != 0) { r = Math.floor(Math.random() * (31*28)) } this.info.map[r] = 2 this.pause_game() } // CHECKING FOR FOUL WHEN HIT THE WALL if (this.info.map[n] == 1 && this.info.allowcollisions) { this.info.fouls++ } // IF SNAKE HITS THE BODY if (this.info.map[n] > 4 && this.info.map[n] != this.info.parts+3 && !this.info.evade_bite) { let parts_to_remove = (this.info.parts+3) - this.info.map[n] for (let i=0; i this.info.steps_limit) { btn_replace.click();this.info.steps=0;this.info.fouls++ } if (file_writing) { data_line += "," + String(dir) content += data_line } return true } else {return false} } can_move(next_step, dir) { let next_item = this.info.map[next_step] // IF SNAKE GOES OUT OF BOUNDARIES if (next_step < 0 || next_step > 31*28-1) {return false} if (dir == 1 && next_step % 28 == 27) {return false} if (dir == 3 && next_step % 28 == 0) {return false} // ILLEGAL STEP INSIDE THE BOUNDARIES switch (next_item) { case 0: return true case 1: if (this.info.allowcollisions) {return true} return false case 2: return true case 3: return false case 4: return false default: return true; } } automate_faster(time) { clearInterval(interval_var_fast) interval_var_fast = setInterval(() => { if (loaded_infos.length > 1) { this.info = loaded_infos[0] this.update_map() loaded_infos.shift() } else { console.log('\n ==== OUT OF INFOS ==== \n') } }, time); } load_automated_infos() { let time_i = Date.now() fetch(API_URL + `automate_faster-${JSON.stringify(loaded_infos[loaded_infos.length-1])}`) .then(response => response.json()) .then(data => { let returned_infos = JSON.parse(data) if (btn_fast_automation.innerText == "Fast Automation") {if(btn_guide.innerText == "Guide"){btn_fast_automation.disabled = false};return} loading.style.setProperty("visibility", "hidden") // adding more infos if (loaded_infos.length < 200 || this.info['overflow_infos']) {loaded_infos = loaded_infos.concat(returned_infos)} console.log("ADDED NEW INFOS") console.table(`infos count: ${loaded_infos.length}`) // Finding optimal time for interval let time_f = Date.now() let fast_time = (time_f - time_i)/(this.info.automated_infos_count*mult) if (this.info.automated_time_update_freq) { game.automate_faster(fast_time) } else {if (start_auto == 1) {game.automate_faster(fast_time); start_auto=0;}} console.log(`FAST TIME: ${fast_time}`) console.log("\n") this.load_automated_infos() }); } automate() { fetch(API_URL + `automate-${JSON.stringify(this.info)}`) .then(response => response.json()) .then(data => { let pred_dirs = JSON.parse(data) // predicted directions sorted by preference for (let i=0; i<4; i++) { if (this.move(pred_dirs[i])) { this.info.second_pref_count += i; break } } }); } get_map(map_type) { // getting the maps loading.style.setProperty("visibility", "visible") this.info.map_type = map_type this.info.steps = 0 fetch(API_URL + `map-${JSON.stringify(this.info)}`) .then(response => response.json()) .then(data => { this.info = JSON.parse(data) loading.style.setProperty("visibility", "hidden") this.update_map() }); } update_map() { // APPLYING LIST TO VISUAL GRID for (let i=0; i { // writing in a file if (event.key == 'Backspace' && file_writing) { content = '' } if (event.key == 'Enter' && file_writing) { fetch(API_URL + `write-${content}`) .then(response => response.json()) .then(data => { content = '' return }); } // controls if (event.key == 'ArrowRight') { game.info.cache_dir = 3 } if (event.key == 'ArrowLeft') { game.info.cache_dir = 1 } if (event.key == 'ArrowUp') { game.info.cache_dir = 0 } if (event.key == 'ArrowDown') { game.info.cache_dir = 2 } if (event.key == ' ') { game.pause_game(); return } if (game.info.mode == "paused") { // PLAY THE GAME WITH KEYS game.set_game_interval(()=>{ game.auto_key_move() }) game.info.mode = "key" } } // SWIPE EVENTS document.addEventListener('swiped-up', function(e) { document.onkeydown({key: 'ArrowUp'})} ); document.addEventListener('swiped-left', function(e) { document.onkeydown({key: 'ArrowLeft'})} ); document.addEventListener('swiped-down', function(e) { document.onkeydown({key: 'ArrowDown'})} ); document.addEventListener('swiped-right', function(e) { document.onkeydown({key: 'ArrowRight'})} ); // BUTTONS btn_fast_automation.onclick = ()=>{ if (btn_fast_automation.innerText == "Fast Automation") { game.pause_game() btn_fast_automation.innerText = "Pause" // FAST AUTOMATE loading.style.setProperty("visibility", "visible") loaded_infos = loaded_infos.concat(game.info) game.load_automated_infos(); btn_next_map.disabled = true btn_speeder.disabled = true btn_collide.disabled = true btn_replace.disabled = true } else { game.pause_game(); btn_fast_automation.disabled = true } } btn_pause_auto.onclick = () => { if (btn_pause_auto.innerText == "Automate") { if (btn_fast_automation.innerText == "Pause") {btn_fast_automation.disabled = true} game.pause_game() // AUTOMATE THE GAME btn_pause_auto.innerText = "Pause" game.set_game_interval(()=>{ game.automate() }) game.info.mode = "automated" btn_speeder.disabled = true } else {game.pause_game()} } btn_next_map.onclick = ()=>{ game.info.steps = 0 game.info.score = 0 game.info.fouls = 0 if (btn_next_map.innerText == "Random Map") { // GETTING RANDOM MAP game.get_map("random") btn_next_map.innerText = 'Fixed Map' btn_collide.innerText = 'Disable Collision' btn_collide.click() btn_collide.disabled = true } else { // GETTING FIXED MAP game.get_map("fixed") btn_next_map.innerText = 'Random Map' btn_collide.disabled = false } game.pause_game() } btn_speeder.onclick = () => { if (btn_speeder.innerText == 'Slower') { // SLOW IT game.info.time = game.info.slow_time btn_speeder.innerText = 'Faster' } else { // FAST IT game.info.time = game.info.fast_time btn_speeder.innerText = 'Slower' } if (game.info.mode == "automated") { game.pause_game() btn_pause_auto.click() } else if (game.info.mode == "key") { game.pause_game() } } btn_collide.onclick = () => { if (btn_collide.innerText == 'Enable Collision') { // Enable Collision game.info.allowcollisions = 1 btn_collide.innerText = 'Disable Collision' } else { // Disable Collision game.info.allowcollisions = 0 btn_collide.innerText = 'Enable Collision' } } btn_replace.onclick = () => { game.info.map[game.info.map.indexOf(2)] = 0 let r = Math.floor(Math.random() * (31*28)) while (game.info.map[r] != 0) { r = Math.floor(Math.random() * (31*28)) } game.info.map[r] = 2 game.update_map() } btn_guide.onclick = ()=>{ game.pause_game() if (btn_guide.innerText == "Guide") { // SHOWING GUIDE ins.style.setProperty('display', 'block') btn_guide.innerText = "Close" btn_fast_automation.disabled = true btn_pause_auto.disabled = true btn_next_map.disabled = true btn_speeder.disabled = true btn_collide.disabled = true btn_replace.disabled = true } else { // CLOSING GUIDE ins.style.setProperty('display', 'none') btn_guide.innerText = "Guide" btn_fast_automation.disabled = false } } document.querySelector("body").style.setProperty("height", `${window.innerHeight}px`) document.querySelector(":root").style.setProperty( "--win_size", `${(win_size/100) * ((window.innerHeight < window.innerWidth)? window.innerHeight: window.innerWidth)}px` ) window.addEventListener("resize", () => { document.querySelector("body").style.setProperty("height", `${window.innerHeight}px`) document.querySelector(":root").style.setProperty( "--win_size", `${(win_size/100) * ((window.innerHeight < window.innerWidth)? window.innerHeight: window.innerWidth)}px` ) });