(function() { function euklidinenEtäisyysNeliö(x1, y1, x2, y2) { return Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2); } function euklidinenEtäisyys(x1, y1, x2 = 0, y2 = 0) { return Math.sqrt(euklidinenEtäisyysNeliö(x1, y1, x2, y2)); } function ympyränPiste(r, alfa) { return [r * Math.cos(alfa), r * Math.sin(alfa)]; } // Ohjelma async-funktiona. Älä vaihda funktion nimeä! async function ohjelma(input, output) { // Tervehdys. output("Reisille JavaScript"); const tervehdys = await input(); if (tervehdys == "ping" || tervehdys != "2019-kuurupiilo") { return; } // Pelin asetukset ja esteet. const asetusrivi = await input(); const asetukset = asetusrivi.split(" ").map(s => +s); const pelaajia = asetukset[0], numero = asetukset[1]; const esteet = [], pelaajat = []; for (let i = 3; i < asetukset.length; i += 3) { esteet.push({x: asetukset[i], y: asetukset[i+1], r: asetukset[i+2]}); } // Alustetaan pelaajien tiedot. for (let i = 0; i < pelaajia; ++i) { pelaajat.push({x: 0, y: 0, r: 32, kohdeX: 0, kohdeY: 0, nähtynä: 0, päivitetty: 0, etsijä: i < 3}); } const itse = pelaajat[numero - 1]; // Ajetaan peliä. for (let kierros = itse.etsijä ? 200 : 0;; ++kierros) { // Kierroksen syöte: näkyvien pelaajien sijainnit. const rivi = await input(); if (!rivi || rivi == "0") { break; } const luvut = rivi.split(" ").map(s => +s); for (let i = 1; i < luvut.length; i += 6) { const n = luvut[i] - 1; pelaajat[n].x = luvut[i+1]; pelaajat[n].y = luvut[i+2]; pelaajat[n].kohdeX = luvut[i+3]; pelaajat[n].kohdeY = luvut[i+4]; pelaajat[n].nähtynä = luvut[i+5]; pelaajat[n].päivitetty = kierros; } if (itse.etsijä) { nähdyt = pelaajat.filter(p => !p.etsijä && p.päivitetty >= kierros - 50 && p.nähtynä < 50); if (nähdyt.length > 0) { let etäisyydet = nähdyt.map(p => euklidinenEtäisyysNeliö(itse.x, itse.y, p.x, p.y)); let lähinIndeksi = etäisyydet.indexOf(Math.min.apply(null, etäisyydet)); let lähin = nähdyt[lähinIndeksi]; let muutosX = lähin.kohdeX - lähin.x; let muutosY = lähin.kohdeY - lähin.y; let pituus = euklidinenEtäisyys(muutosX, muutosY) || 1; let pituuskerroin = 0.5; let ennuste = pituuskerroin * euklidinenEtäisyys(itse.x, itse.y, lähin.x, lähin.y); itse.kohdeX = lähin.x + ennuste * muutosX / pituus; itse.kohdeY = lähin.y + ennuste * muutosY / pituus; } else { let muutosX = itse.kohdeX - itse.x; let muutosY = itse.kohdeY - itse.y; if (muutosX == 0 && muutosY == 0) { [muutosX, muutosY] = ympyränPiste(128, 2 * Math.PI * Math.random()); } else { let pituus = euklidinenEtäisyys(muutosX, muutosY); muutosX = 128 * muutosX / pituus; muutosY = 128 * muutosY / pituus; } let [ympyräX, ympyräY] = ympyränPiste(16, 2 * Math.PI * Math.random()); itse.kohdeX = itse.x + muutosX + ympyräX; itse.kohdeY = itse.y + muutosY + ympyräY; } } else { let muutosX = itse.kohdeX - itse.x; let muutosY = itse.kohdeY - itse.y; if (muutosX == 0 && muutosY == 0) { [muutosX, muutosY] = ympyränPiste(128, 2 * Math.PI * Math.random()); } else { let pituus = euklidinenEtäisyys(muutosX, muutosY); muutosX = 128 * muutosX / pituus; muutosY = 128 * muutosY / pituus; } let [ympyräX, ympyräY] = ympyränPiste(16, 2 * Math.PI * Math.random()); itse.kohdeX = itse.x + muutosX + ympyräX; itse.kohdeY = itse.y + muutosY + ympyräY; } itse.kohdeX = Math.trunc(Math.min(1080, Math.max(-1080, itse.kohdeX))); itse.kohdeY = Math.trunc(Math.min(1080, Math.max(-1080, itse.kohdeY))); output(itse.kohdeX + " " + itse.kohdeY); // Pienennetään esteitä, jos on sen aika. if (kierros % 4800 == 4799) { for (let e of esteet) { e.r = Math.trunc(e.r * 3 / 4); if (e.r <= 8) { // Merkitään säde nollaksi, jos este poistuu. e.r = 0; } } } } } // ÄLÄ VÄLITÄ NÄISTÄ: // Ohjelman suoritus. if (typeof window == "undefined") (async function run() { let finished = false, lines = [], promises = []; const exit = s => { try { process.exit(s) } catch (ex) {} try { quit(s) } catch (ex) {} }; const output = s => { try { process.stdout.write(s + "\n") } catch (ex) {} try { print(s) } catch (ex) {} }; const addInput = s => { if (promises.length) { promises.shift()(s); } else { lines.push(s); } }; const input = () => { if (finished) return; try { addInput(readline()); } catch (ex) {} if (lines.length) return lines.shift(); return new Promise(r => promises.push(r)); }; try { require("readline").createInterface({input: process.stdin}).on("line", addInput).on("close", () => finished = true); } catch (ex) { } try { await ohjelma(input, output); exit(0); } catch (ex) { output("ERROR: " + ex); console.error(ex); exit(1); } })(); return ohjelma; }())