/* * [Česky] * Projekt: Robot Karel * Copyright: Viz KOPIROVANI v kořenovém adresáři projektu * * [English] * Project: Karel, the Robot * Copyright: See COPYING in the top level directory */ // JavaScript - základní funkce pro město // =========================================================================== // =~ Globální nastavení ~==================================================== // Čas pro dvojklik v milisekundách // TODO: Nastavení v uživatelském rozhraní nastaveni.dvojklik = 500; // =========================================================================== // =~ Globální proměnné ~===================================================== // Pozice Karla karel = new Object(); // Směr: 0-východ, 1-sever, 2-západ, 3-jih karel.VYCHOD = 0; karel.SEVER = 1; karel.ZAPAD = 2; karel.JIH = 3; karel.smer = karel.VYCHOD; karel.pozice = {x:0, y:0}; karel.nazev_smeru = new Array("vychod", "sever", "zapad", "jih"); karel.nazev_smeru_plny = new Array("východ", "sever", "západ", "jih"); // Pozice domova domov = new Object(); domov.pozice = {x:0, y:0}; // Konstanty pohybu (východ, sever, západ, jih) plus = new Object(); plus.x = new Array(1, 0, -1, 0); plus.y = new Array(0, 1, 0, -1); // Struktura města mesto = new Object(); // Velikost mesto.velikost = {x: 10, y: 10}; // Pole mesto.pole = new Array(); mesto.pole[0] = new Array(); for ( var x = 0; x < mesto.velikost.x; x++ ) { mesto.pole[0].push(0); } for ( var y = 1; y < mesto.velikost.y; y++ ) { mesto.pole[y] = mesto.pole[0].concat(); } // Názvy obrázků mesto.obrazky = new Array(); mesto.obrazky[-1] = "zed"; mesto.obrazky[0] = null; for ( var i = 1; i < 9; i++ ) { // A potom značky mesto.obrazky[i] = "znacka-"+i; } // Objekt pro práci s myší mesto.mys = new Mys(); // Čas posledního kliku (provedení akce) - pro dvojklik mesto.posledni_klik = null; // =========================================================================== // =~ Základní funkce pro aktualizaci města ~================================= // Nastav správné parametry políčka podle města mesto.prekresli_pole = function (pozice) { var element = document.getElementById('pozice_'+pozice.x+'_'+pozice.y); var pole = mesto.pole[pozice.x][pozice.y]; var obrazek = mesto.obrazky[pole]; if ( element.className != obrazek ) { element.className = obrazek; } } // Nastav pozici Karla mesto.pozice_karla = function (pozice) { if ( pozice.x >= 0 && pozice.x < mesto.velikost.x && pozice.y >= 0 && pozice.y < mesto.velikost.y && mesto.pole[pozice.x][pozice.y] >= 0 ) { var element = document.getElementById('pozice_karel'); element.style.left = (pozice.x*32)+"px"; element.style.top = ((mesto.velikost.y - pozice.y - 1)*32)+"px"; karel.pozice = pozice; ladici_vypis(DETAIL, "mesto.pozice_karla", pozice, "Karel umístěn"); return true; } else { ladici_vypis(CHYBA, "mesto.pozice_karla", pozice, "Karla nelze umístit kvůli zdi"); return false; } } // Nastav orientaci Karla mesto.orientace_karla = function (smer) { smer %= karel.nazev_smeru.length; if ( smer < 0 ) smer += karel.nazev_smeru.length; var element = document.getElementById('pozice_karel'); element.className = "karel-"+karel.nazev_smeru[smer]; karel.smer = smer; ladici_vypis(DETAIL, "mesto.orientace_karla", "Karel nasměrován na "+karel.nazev_smeru_plny[smer]); } // Nastav pozici Domova mesto.pozice_domova = function (pozice) { if ( mesto.pole[pozice.x][pozice.y] >= 0 ) { var element = document.getElementById('pozice_domov'); element.style.left = (pozice.x*32)+"px"; element.style.top = ((mesto.velikost.y - pozice.y - 1)*32)+"px"; domov.pozice = pozice; ladici_vypis(DETAIL, "mesto.pozice_domova", pozice, "domov umístěn"); } else { ladici_vypis(CHYBA, "mesto.pozice_domova", pozice, "domov nelze umístit kvůli zdi"); } } // Nahrání celého města mesto.nahraj_mesto = function (karel_pozice, smer, domov_pozice, mesto_pole) { var uzivatel_chce = window.confirm("Opravdu si přejete nahrát město?"); if ( uzivatel_chce ) { mesto.velikost.x = mesto_pole.length; mesto.velikost.y = mesto_pole[0].length; this.pozice_karla(karel_pozice); this.orientace_karla(smer); this.pozice_domova(domov_pozice); for ( var x = 0; x < mesto.pole.length; x++ ) { for ( var y = 0; y < mesto.pole[0].length; y++ ) { if ( mesto.pole[x][y] != mesto_pole[x][y] ) { mesto.pole[x][y] = mesto_pole[x][y]; this.prekresli_pole( {x: x, y: y} ); } } } } } // =========================================================================== // =~ Podmínky pro Karla ~==================================================== mesto.JE_ZED = function () { var pozice = { x: karel.pozice.x+plus.x[karel.smer], y: karel.pozice.y+plus.y[karel.smer] }; return !( pozice.x >= 0 && pozice.x < mesto.velikost.x && pozice.y >= 0 && pozice.y < mesto.velikost.y && mesto.pole[pozice.x][pozice.y] >= 0 ); } mesto.JE_ZNACKA = function () { return mesto.pole[karel.pozice.x][karel.pozice.y] > 0; } mesto.JE_DOMOV = function () { return ( karel.pozice.x == domov.pozice.x && karel.pozice.y == domov.pozice.y ); } mesto.JE_VYCHOD = function () { return karel.smer == karel.VYCHOD; } mesto.JE_SEVER = function () { return karel.smer == karel.SEVER; } mesto.JE_ZAPAD = function () { return karel.smer == karel.ZAPAD; } mesto.JE_JIH = function () { return karel.smer == karel.JIH; } // =========================================================================== // =~ Práce s myší ~========================================================== mesto.mys.prekresli_stav = function (pozice, detail, zvyraznen, stisknut, vybran) { var element = document.getElementById('pozice_vyber'); if ( zvyraznen ) { element.style.visibility = "visible"; element.style.left = (pozice.x*32)+"px"; element.style.top = ((mesto.velikost.y - pozice.y - 1)*32)+"px"; nastroje.zobraz_pozici(pozice); } else if ( !this.je_zvyraznen() ) { element.style.visibility = "hidden"; nastroje.zobraz_pozici(null); } } mesto.mys.proved_zvyrazneni = function(pozice, detail) { return true; } mesto.mys.proved_vyber = function(pozice, detail) { var cas = new Date(); var rychly = ( mesto.posledni_klik != null && (cas-mesto.posledni_klik) < nastaveni.dvojklik ); mesto.posledni_klik = cas; switch ( nastroje.vybrany() ) { case "karel": if ( ! rychly || ! jsou_shodne(pozice, karel.pozice) ) { mesto.pozice_karla(pozice); } else { mesto.proved_vlevo_vbok(); } break; case "domov": mesto.pozice_domova(pozice); break; case "zed": mesto.umisti_zed(pozice); break; case "znacka-plus": mesto.poloz(pozice); break; case "znacka-minus": mesto.zvedni(pozice); break; default: } return false; } // =========================================================================== // =~ Příkazy a funkce pro editaci města ~==================================== mesto.proved_poloz = function (pozice) { var chyba = new Chyba(); if ( pozice == null ) { pozice = {x:karel.pozice.x, y:karel.pozice.y}; } if ( mesto.pole[pozice.x][pozice.y] >= 0 ) { if ( mesto.pole[pozice.x][pozice.y] < 8 ) { mesto.pole[pozice.x][pozice.y]++; ladici_vypis(DETAIL, "mesto.proved_poloz", pozice, "položena značka, aktuální počet: "+mesto.pole[pozice.x][pozice.y]); mesto.prekresli_pole(pozice); } else { ladici_vypis(VAROVANI, "mesto.proved_poloz", pozice, "příliš mnoho značek"); chyba.nastav( true, "Nemohu položit více jak 8 značek." ); } } else { ladici_vypis(CHYBA, "mesto.proved_poloz", pozice, "nelze položit značku kvůli zdi"); } return new Vysledek( chyba, Vysledek.PROVEDL_AKCI ); } mesto.proved_zvedni = function (pozice) { var chyba = new Chyba(); if ( pozice == null ) { pozice = {x:karel.pozice.x, y:karel.pozice.y}; } if ( mesto.pole[pozice.x][pozice.y] >= 0 ) { if ( mesto.pole[pozice.x][pozice.y] > 0 ) { mesto.pole[pozice.x][pozice.y]--; ladici_vypis(DETAIL, "mesto.proved_zvedni", pozice, "zvednuta značka, aktuální počet: "+mesto.pole[pozice.x][pozice.y]); mesto.prekresli_pole(pozice); } else { ladici_vypis(VAROVANI, "mesto.proved_zvedni", pozice, "žádná značka, nelze zvednout"); chyba.nastav( true, "Nemohu zvednout značku. Žádná tam není." ); } } else { ladici_vypis(CHYBA, "mesto.proved_zvedni", pozice, "pouze zeď, nelze zvednout"); } return new Vysledek( chyba, Vysledek.PROVEDL_AKCI ); } mesto.proved_vlevo_vbok = function (pozice) { mesto.orientace_karla(karel.smer+1); return new Vysledek( new Chyba(), Vysledek.PROVEDL_AKCI ); } mesto.proved_krok = function (pozice) { if ( pozice == null ) { pozice = {x:karel.pozice.x, y:karel.pozice.y}; } var nova_pozice = { x:pozice.x+plus.x[karel.smer], y:pozice.y+plus.y[karel.smer] }; var chyba = new Chyba(); if ( ! mesto.pozice_karla( nova_pozice ) ) { chyba.nastav( true, "Nemůžu učinit KROK, přede mnou je zeď." ); } return new Vysledek( chyba, Vysledek.PROVEDL_AKCI ); } mesto.poloz = function (pozice) { var navrat = mesto.proved_poloz(pozice); navrat.chyba.zobraz(); } mesto.zvedni = function (pozice) { var navrat = mesto.proved_zvedni(pozice); navrat.chyba.zobraz(); } mesto.umisti_zed = function (pozice) { var je_karel = jsou_shodne(pozice, karel.pozice); var je_domov = jsou_shodne(pozice, domov.pozice); if ( !je_karel && !je_domov ) { if ( mesto.pole[pozice.x][pozice.y] >= 0 ) { mesto.pole[pozice.x][pozice.y] = -1; ladici_vypis(DETAIL, "mesto.umisti_zed", pozice, "zeď umístěna"); } else { mesto.pole[pozice.x][pozice.y] = 0; ladici_vypis(DETAIL, "mesto.umisti_zed", pozice, "zeď zrušena"); } mesto.prekresli_pole(pozice); } else { var hlaska = ""; if ( je_karel ) { hlaska = "Karlovi a "; } if ( je_domov ) { hlaska += "domovu "; } ladici_vypis(CHYBA, "mesto.umisti_zed", pozice, "nelze umístit zeď kvůli "+hlaska.slice(0,-3)); } } mesto.vymaz_znacky = function () { for ( var x=0; x 0 ) { mesto.pole[x][y] = 0; mesto.prekresli_pole({x:x, y:y}); } } } ladici_vypis(INFORMACE, "mesto.vymaz_znacky", "značky vymazány"); } mesto.vymaz_mesto = function () { var uzivatel_chce = window.confirm("Opravdu chcete vyčistit celé město?"); if ( uzivatel_chce ) { ladici_vypis(INFORMACE, "mesto.vymaz_mesto", "mažu značky"); for ( var x=0; x