ITV0110 2. töö 2015: CSS, javascript

Allikas: Lambda
Battleship



Mida tuleb teha

Sinu ülesandeks on kirjutada laevade pommitamise mängu brauseris töötav lihtsustatud eriversioon, kasutades ainult html-i, css-i ja javascripti.

Loe kõigepealt läbi ülevaade wikipediast ja mängi katseks standardset täisversiooni siin või siin või siin: see on hea insipiratsioon sinu enda mängu tegemiseks.

Ühe mängija asemel mängib sinu programmis arvuti, st programmi kasutaja mängib arvuti vastu.

Valmis töö tuleb riputada üles ülikooli serverisse dijkstra (vaata altpoolt). Ehk, arvestatakse ainult dijkstra-s olevaid töid.

Selles praksis teed arvuti vastu mängimise variandi, aga kolmandas praktikumis tuleb samale mängule lisada serveripoolset funktsionaalsust, näiteks tulemuste salvestamine ja vaatamine ja statistika, samuti mäng kahe inimese vahel, mis toimub siis serverirakenduse vahendusel.

Detailid

Meie praksiülesande detailid ja erisused standardsest laevade pommitamisest on järgmised:

  • Lihtsustus: kasutame ainult ühte tüüpi laeva: kahene horisontaalpaigutusega laev. Ehk, alati kaks kõrvuti horisontaalset ruutu.
  • Neid standardse pommitamise reegleid tuleb järgida:
    • Laevad ei tohi olla üksteisega külgepidi/otsapidi koos. Diagonaali ehk nurgaga puudutamine on ok.
    • Lui sina või masin on mõnda ruutu pommitanud, aga läks mööda, peab sinna ilmuma nähtav märge.
    • Lui oled laevaruudule pihta saanud, peab sinna ilmuma teistsugune nähtav märge, millest saab aru, et said pihta.
    • Kui sina või masin saab laevaruudule pihta, saab ta kohe uuesti pommitada, kuni ta kas võidab või pommitab mööda: alles siis antakse käik teisele üle.
  • Sina mängid arvuti vastu, seejuures on ok, kui arvuti käib lihtsalt juhuslikult, kuid ta ei tohi pommitada kohti, mida ta on juba varem pommitanud.
  • Mängu alguses pead saama valida maatriksi suuruse: konkreetselt kas 3x3, 4x4, ... või 10x10 ruudustik.
  • Mängu alguses peab saama valida laevade arvu: kas 1, 2, 3, ..., 10 laeva. Laevade arv ei tohi olla suurem, kui valitud maatriksi küljepikkus miinus üks: näiteks 4x4 ruudustikul võib olla maksimaalselt kolm laeva. Kui sul ei õnnestu kõiki laevu maatriksile paigutada, siis pole hullu, kui paigutad ühe vähem.
  • Laevade algse paigutuse nii sinu maatriksil kui tema enda maatriksil määrab arvuti juhuslikult, arvestades seejuures, et laevad ei tohi külgepidi ega otsapidi kokku puutuda. NB! Juhusliku paigutamise meetodid ja piirangud võid ise valida. Ei pea olema nö "täiesti juhuslik", peaasi, et nö mõistlik juhuslikkus oleks sees. Kui sul praksis kõik nõutud osad valmis, võid lisaks realiseerida ka enda laevade ise-paigutamise: see ei ole kohustuslik ja annab ühe punkti võimalikust 12-st.
  • Lehel peab olema nupp mängu alustamiseks, mida võib vajutada ka käimasoleva mängu korral: sel juhul mäng katkestatakse ja alustatakse nullist uut, koos uute maatriksisuuruse ja laevade arvu valikuga.
  • Mängu alustab ehk esimese pommi tulistab inimene.
  • Mängu lõppedes pead kuvama, kes võitis ja mitu pommitamist tegid sina ja mitu masin.
  • Pead salvestama ja lehel pidevalt kuvama viimase kümne mängu tulemusi ridade kaupa, igal real selline info: maatriksi suurus, laevade arv, sinu pommitamiste arv, masina pommitamiste arv. Vabatahtliku lisana mängu aeg sekundites: see ei ole kohustuslik ja annab ühe punkti 12-st.
  • Kujunduslikud ja tehnoloogilised nõuded:
    • Kujundus ei tohi olla väga kole. Hea mõte on lähtuda sellest juhendist.
    • Erinevad elemendid lehel peavad mängu käigus püsima stabiilsed, ei tohi ringi nihkuda.
    • Lehel peavad olema sinu maatriks ja masina maatriks sama suured ja horisontaalis kõrvuti. Mobiilivariandis (kui selle teed) peab masina maatriks aga olema sinu maatriksi kohal.
    • Ei tohi kasutada canvast, svg-d, flashi ega java applette. Maatriksi jaoks kasuta kas div-e või tabelit koos css-i ja javascriptiga.
    • Nii laevade maatriksi kui seniste tulemuste tabeli võid teha tabeli või div tagidega, aga mujal ei tohi tabeli tagi kasutada.

Kõiki eeltoodud nõudeid tuleb järgida, klassikaline laevade pommitamine praksilahenduseks ei sobi.

Kohustuslikud ja mittekohustuslikud osad ja punktiarvestus

Eeltoodud nõuete punktid peavad arvestamiseks olema täidetud, nad annavad kokku 6 punkti. Lisaks - kuni maksimaalse 12ni - saad teha järgmised osad:

  • Kuvad oma laevasid pildina, mitte lihtsalt märgendatud ruutudega: 1 punkt.
  • Mõõdad ja kuvad tulemuste tabelis mängu peale kulunud aega: 1 punkt.
  • Laevade ise-paigutamine mängu alguses: 1 punkt (see on veidi keerulisem ja jäta viimaseks!)
  • Mobiilivariant, mis näeb hea välja ja on mugavalt mängitav: 3 punkti. Selleks pead mobiilivariandis saavutama:
    • Sisse zoomida ei ole vaja ja parem, kui ei saagi.
    • Paremale-vasakule scrollida ei saa, kõik scrollimine on ülevalt alla.
    • Maatriks on enamvähem lehe vasakust äärest parema ääreni.
    • Suure display variant ja mobiilivariant on sama lähtekoodiga, mitte kaks täiesti erinevat lehte.
    • Suure display paigutus (tavapaigutus) on teistsugune, kui mobiilipaigus, kindlasti ses mõttes, et tavapaigutuses ei raisata liiga palju ruumi, nupud, fondid jne pole liiga suured, maatriksid on kõrvuti (mobiilis üksteise all) ja scrollida pole üldse vaja, ka mitte üles-alla.

Koodist arusaamine ja plagiaadikontroll

Kogu esitatud kood peab jääma prax2 alamkataloogi alles kuni kursuse lõpuni.

Teiste inimeste - ka õppejõu - kirjutatud lahendusi aluseks võtta ei ole OK. Kui juhendaja tuvastab, et sinu koodil on väga suured sarnasused mõne teise koodiga, siis pead töö uuesti kirjutama. Järelkontrollid toimuvad ka pärast töö esitamist.

Kõigist osadest oma koodis pead ise hästi aru saama ja suutma neid juhendajale selgitada, kui ta küsib. Ei ole OK võtta võrgust juppe, mille funktsioneerimisest sa aru ei saa (ehk, kui võtad mõne jupi, siis tee endale kõigepealt selgeks, mida see jupp täpselt teeb).

Css-i ja javascripti teegid ja erivariandid javascriptist

Väliste teekide, ntx Jquery või Bootstrap kasutamine on ok, aga siis sa pead hästi aru saama, mida sinu tehtavad teegi-callid või stiilid teevad. Reaalselt on see praks piisavalt lihtne selleks, et teekide kasutamine vajalik ei oleks. Kui otsustad siiski teeki kasutada, siis väga soovitav on valida jquery kui suhteliselt lihtne ja domineerivalt populaarseim javascripti teek, kujunduse jaoks aga Bootstrap.

Kogu javascript peab olema esitatud minimiseerimata ja nö normaalse taandega, et oleks kergesti loetav.

Ei ole OK kasutada süsteeme nagu typescript, mis kompileerivad sinu lähtekoodi javascriptiks: see muudaks juhendajate töö liiga raskeks.

Soovitusi htmli ja cssi osas

Hea mõte on algul jagada lehekülg mitmeks horisontaalseks reaks ja vertikaalseks kõrvuti tulbaks. Kõige lihtsam - ja selle rakenduse jaoks piisav - on seada ridadele ja tulpadele fikseeritud laiused ja kõrgused. NB! Selline fiks laiuste/kõrguste lähenemine ei ole enamiku harilike veebisaitide jaoks päris hea mõte, ja on hoopis halb mobiilile sobiva saidi tegemisel.

Siit ja siit leiad tsentreerimise õpetused (point: margin-left: auto; margin-right: auto;)

Tulpade tegemine tabeliga on lihtne, aga puhtalt div-dega ei ole päris triviaalne. Vaata seda ja seda või seda seletust põhimõtete osas. Kogu värgi lehekülje keskele panekuks, headeri ja footeri lisamiseks jne pakuvad ideid ja näiteid need õpetused, alates lihtsamast ja lõpetades põhjalikuga:

Täiendavate ideede ja juhatuste jaoks vaata lihtsalt kursuse lehelt viidatud materjale CSS bloki alt.

Moblale sobiva lehe põhimõtete kohta tasub lugeda neid lihtsaid suuniseid Applelt

Soovitusi javascripti osas

Kui sa ei kasuta mõnda javascripti teeki nagu jquery (algajale mittesoovitav, kuna tekitab lisakeerukusi!) siis on hea mõte töö lihtsustamiseks teha ise väikeseid abifunktsioone, näiteks function gid(x) {return document.getElementById(x); } et ei peaks kogu aeg pikalt välja kirjutama.

Debugimiseks on kõige lihtsam panna koodi sisse alert(...), aga mugavam ja parem on kasutada funktsiooni console.log(...) mille võid omakorda panna oma abifunktsiooni a la function debug(x) { console.log(x) }. console.log trükib tulemuse brauseri debugeri konsooli (Firefoxis käivita (ja enne installi!) firebug ja vaata firebugi aknast "console" tabi alt, Chromes otsi developer tools või javascript console).

Täiendavate ideede ja juhatuste jaoks vaata lihtsalt kursuse lehelt viidatud materjale javascripti bloki alt.

Näitekood laevade paigutamiseks

Laevade juhuslikul paigutusel ei ole rangeid nõudeid "juhuslikkuse" osas: lihtsalt paigutus peaks igakord "juhuslikult" muutuma, laevad ei tohi olla kõrvuti ja otsapidi koos, suuremal laual peaks olema rohkem laevu.

Siin all on veidi poolik kood, mis paigutab randomiga laevu tabelisse laiusega size. Sa ei pea seda üldse kasutama, aga ta võib olla abiks.

Ta eeldab, et sul on juba olemas javascripti array table kujul (näitena küljepikkuse 3 jaoks)

[[0,0,0],[0,0,0],[0,0,0]]

ja muudab selle table sisu, täites laevaruudud numbritega 1, näiteks selliseks:

[[1,1,0],[0,0,0],[0,1,1]]

Seejuures pannakse igale reale üks laev, vaadates, et ta ei sattuks eelmise rea laevaga külgepidi kokku.

Kui 20 randomkatsel rea kohta sobivat positsiooni ei leitud (näiteks kolmese küljepikkusega tabelis ei olegi võimalik teist rida täita!) siis jäetakse see rida lihtsalt tühjaks.

Sul on mõistlik seda koodi edasi arendada selliselt, et:

  • ta ei kasutaks alati arrayd nimega table vaid sa saaksid selle array ehk tabeli nime ise ette anda.
  • sa saaksid ette anda soovitud laevade arvu: kui soovitud laevu on hulga vähem, kui ridu, siis võiks lihtsalt mõned read randomiga vahele jätta: muidugi, soovitud laevade arv peaks kokku tulema.

funktsioon gid on lihtsalt enda tehtud abifunktsioon function gid(x) {return document.getElementById(x); }

function fillBoard(size) {
  var r,c,i,foundok,count;
  size=parseInt(size); 
  // loop over all the rows, to place one ship to each (most) rows    
  for(i=0;i<size;i++) { 
    foundok=false;
    count=0;
    // try different random column positions until OK pos found: 
    // if no position OK during 20 tries, give up and 
    // do not put a ship on this line at all
    while(!foundok && count<20) {
      c=Math.floor(Math.random()*(size-1));
      console.log("try ship for row "+i+" at col "+c);
      if (i>0) {
        if (table[i-1][c]==1) { foundok=false; }
        else if (c>0 && table[i-1][c-1]==1) { foundok=false; }
        else if (c<size-1 && table[i-1][c+1]==1) { foundok=false; } 
        else foundok=true;
      } else {
        foundok=true;
      }  
      count++;
    }  
    if (foundok) {
      console.log("got ship for row "+i+" at col "+c);   
      table[i][c]=1;
      table[i][c+1]=1;
      console.log(table); 
    }      
  }     
}

Järgnev on lihtne näide numbritega 0 ja 1 täidetud andmetabeli (parameeter tbl) kuvamiseks html tabelis, kus iga ruut on id-ga divid+reanr+tulbanr a la "mytable21". Arusaadavalt eeldab see kood, et selliste id-dga html tabel on juba loodud.


function showBoard(tbl,divid) {
  var r,c,place;
  console.log(tbl);
  for(r=0;r<tbl.length;r++) {
    for(c=0;c<tbl.length;c++) {
      console.log((divid+r)+c);
      place=gid((divid+r)+c);
      if (tbl[r][c]==1) {
        place.innerHTML="s"
        place.style.backgroundColor="#666666";
      } else {
        place.innerHTML=""
        place.style.backgroundColor="#eeeeee";
      }      
    }
  }  
}

Dijkstra server

Kodutööde tarbeks on kasutusel server nimega dijkstra: kindlasti loe dijkstra kasutusõpetust.

Kõik kodutööd tuleb riputada Dijkstra serverisse, et õppejõud saaks lähtekoode Dijkstra serveris vaadata ja plagiaadituvastus-tarkvara abil kontrollida.

Nõuded kataloogile/failinimedele:

  • Teine kodutöö tuleb panna sinu kodukataloogi alamkataloogi public_html/prax2 mille pead ise looma.
  • Kodutöö html-põhifaili nimi peab olema index.html.
  • Kodutöö sinu tehtud javascripti-fail fail olgu nimega prax2.js ning sinu tehtud css-fail nimega prax2.css
  • Pildifailide ja mujalt võetud javascripti/css teekide osas mingeid nõudeid ei ole.

Enne failide serverisse riputamist on mõistlik teha kogu süsteem valmis lihtsalt oma arvutis/arvutiklassi arvutis.