ITI0011:HW02 Droptris
Tagas ITI0011 lehele.
Info
Ülesande kaitsmised: 21. - 25. märts 2016
Kaust gitis: HW01
Ülesanne
Iga-aastane galaktikatevaheline festival "KnownFlyingObject 2016" leiab peagi aset. Osalejaid tuleb palju, erinevatest, khm, galaktikatest. Sulle on antud ülesanne korraldada külaliste sõiduvahendite parkimine. Toimumiskohas on väga piiratud ala: ühel teljel on parkimisala mõõt 10 universumimõõtühikut, teisel teljel 20 sedasamaühikut, kolmanda telje osas täpne info puudub. Sa teed natuke taustauuringut ja selgub, et külaliste liikumisvahendid on õnneks kõik ühel teljel piisavalt väikese mõõduga, mis sobituvad kindlasti parkimisala kolmanda mõõdu sisse ära. Kuna sõidukeid lähtuvalt galaktikatevahelistest nõuetest igal teljel teineteise vastu/otsa/külge ei tohi panna, teed sa järgmised eeldused oma probleemile:
- parkimisala olulised mõõdud on kaks mõõtu: pikkus ja laius
- sõidukite olulised mõõdud on samamoodi kaks mõõtu: pikkus ja laius
- nii parkimisala kui ka sõidukite kolmas telg ei ole oluline, seega võib sõidukite paigutust teostada tasapinnal
Sõltuvalt oma ametiastmest, antakse sulle ka erinev vastutusala. Loe nendest täpsemalt edasi.
Põhiosa: Külalised Oomegalt (2p)
Sa alles alustad oma karjääri. Sinu hoolitseda jääb parkimis"plats" Oomega galaktika külalistele. Nende tehnoloogiaarengud on jõudnud niikaugele, et kõik nende liikumisvahendid on kandilised. Ehk siis sõiduki laius ja pikkus mõlemad on 2 universumis kasutatavat mõõteühikut.
Lisaosa: Külalised Ipad galaktikast (2p)
Sa ei saanudki täpselt aru, mis nende galaktika omadustest põhjustas selle, et neil kõik asjad on piklikud (aga see-eest hea disainiga). Igal juhul külaliste nimekirja lisanduvad sõidukid, mille üks mõõde on 4 ühikut, teine mõõde on 1 ühik.
Parkimine
Parkimisplats asub tähel, kus kehtivad (mõne jaoks) imelikud "füüsika"seadused. Nimelt toimub suurel osal tähe pinnal liikumine vaid sirgjooneliselt - keerata ei ole võimalik. Festivali raames loodi parkimisplatsi sisendalasse eraldi tsoon, milles on võimalik sõidukit keerata ja ümber paigutada. Selles alas tuleb sõiduk õigesti positsioneerida ning vajadusel ka keerata. Peale seda liigub sõiduk sirgjoones platsi teise serva, kuni kas platsi serv või mõni muu sõiduk selle peatab.
Tehniline info
Teil on kasutada Droptrise API, mis annab teile infot olukorra kohta. Teie eesmärk on kirjutada loogika, mis paigutaks API poolt etteantud kujundid võimalikult hästi platsile.
Kujundid
Kujundid tähistatakse ühe tähega. Igat kujundit saab keerata 90 kraadi. Rotatsioon märgitakse numbriga, mitu korda tehakse 90-kraadist pööret paremale. Allpool on toodud ära kõikide kujundite kõikvõimalikud rotatsioonid (rot) ja igaks juhuks kogu kujundi mõõtmed kõrgus x laius(millest osa ruute on tühjad).
Vaata värvilist pilti kujundiest. Loe pööramisest täpsemalt altpoolt.
O
rot:0 (2x2) ** **
Kujund on igasuguse pööramise korral täpselt samasugune.
I
rot: 0 rot: 1 (4x1) (1x4) * **** * * *
Mõõtmed (kõrgus x laius): 4 x 1
J
rot: 0 rot: 1 rot: 2 rot: 3 (3x2) (2x3) (3x2) (2x3) * * ** *** * *** * * ** *
L
rot: 0 rot: 1 rot: 2 rot: 3 (3x2) (2x3) (3x2) (2x3) * *** ** * * * * *** ** *
T
rot: 0 rot: 1 rot: 2 rot: 3 (2x3) (3x2) (2x3) (3x2) * * *** * *** ** * ** * *
Z
rot: 0 rot: 1 (2x3) (3x2) ** * ** ** *
S
rot: 0 rot: 1 (2x3) (3x2) ** * ** ** *
Suhtlemine serveriga
Serveriga suhtlemiseks on kaks varianti: kasutada teile etteantud teeki (ei võimalda kõiki päringuid teha) või kirjutada ise socket-ühendus (lisaosa). Järgnevalt on kirjeldatud erinevad teated, mida on vaja serveriga suhtlemiseks.
Etteantud teek: Meedia:Droptris_connection_v0.1.zip
Teegi kirjeldus
<source lang="java">
/** * Creates a connection to Droptris service. * @param uniid UNI-ID to use for connection. * @param i Whether I blocks will be sent. If false * only O blocks are sent. * @throws IOException In case the connection fails */ public DroptrisConnection(String uniid, boolean i) throws IOException {}
/** * Tries to read one line (one output) from the connection. * @return String with data (unmodified, json format). * @throws IOException In case the connection fails. */ public String readLine() throws IOException {}
/** * Reads score data from the connection. * @return String with connection json data. * @throws IOException In case the connection fails. */ public String readScoreData() throws IOException {}
/** * Send action (move) to the connection. * @param action String (json) with the action */ public void sendAction(String action) {}
</source>
Konstruktor võtab ette kaks argumenti:
- String uniid - teie uniid (kõik väikesed tähed)
- boolean i - kui true, siis saadetakse serverist teile nii "O" kui "I" kujundeid (4p ülesane). Kui false, siis saadetakse vaid "O" kujundeid (2p ülesanne).
Teegi kasutamine projektis
Paki zip-faili sisu (üks jar fail) lahti näiteks projekti all olevasse "lib" kausta (pead kausta ise looma).
IntelliJ-s toimi järgmiselt:
- File -> Project structure
- Avanenud dialoogis vasakult: Modules
- Näete projektiga seotud mooduleid. Kui te pole mooduleid lisanud, peaksite nägema ühte moodulit, mis on projekti nimega. Kui te kasutate mooduleid (alam-projekte), valige teid huvitav moodul, näiteks HW02.
- Aktiivse mooduli puhul valige dialoogi paremast osast sakk "Dependencies". Seal loetletakse ära kõik antud mooduli jaoks vajalikud teegid. Arvatavasti on teil seal loetelus Java ja Module source.
- Loetelu paremal ääres on "+" märk, vajutage seda. Valige "JARs or directories"
- Avaneb failisirvimise dialoog. Otsige salvestatud jar-fail, märgistage ja vajutage "OK".
Nüüdsest peaks Droptris klass teile antud projektis kättesaadav olema.
Ühenduse loomine
Ühenduse loomiseks tuleb serverile saata uue mängu parameetrid.
Kasutades teeki
<source lang="java"> DroptrisConnection conn = new DroptrisConnection("uniid", false); </source>
Kasutades socketit
Ühendus tuleb luua aadressil nisu.cs.ttu.ee kasutades porti 13131.
Mängu alustamiseks tuleb saata järgmine sõnum (json):
{ "uniid": "mati.gaal", "seed": 12345678 "level": 1 "lookahead": 0 }
lookahead 0 = can’t see what you get next, 1 = see 1 next block etc.
Server vastab näiteks:
{ "message": "Game is starting! Good luck!", # or whatever else message "Unknown message!" "code": 200 }
Kujundiinfo
Kui ühendus on loodud, hakkab server teatud aja tagant saatma kujundite infot. Selleks peab teie programm lugema serverist infot.
Kasutades teeki
Eelnevalt loodud ühenduse puhul kasutada meetodit readLine()
, mis tagastab tulemuse json kujul (vt socketi näidet).
Kasutades socketit
Server saadab info kujul:
{ "block": "I" "next": ["J", "L", "O"] # nii mitu kui algselt lookaheadiga sai määratud }
Sellele sõnumile vastama ei pea.
Käigutegemine
Käigu puhul tuleb saata serverile veeru indeks (näitab kujundi kõige vasakpoolsema serve veeru indeksit) ja rotatsioon (vt eelnevalt kujundite sektsiooni).
Kasutades teeki
Kasuta meetodit sendAction(json)
, kus json on samasugune jsoni String nagu socketi näites allpool.
Kasutades socketit
{ "column": 4 "rotation": 1 }
Mängu skoor
Aktiivse ühenduse puhul on teil võimalus küsida hetke punktiseisu.
Kasutades teeki
Kasutage meetodit readScoreData()
, mis tagastab tulemuse json kujul (vt socketi näidet).
Kasutades socketit
Serverisse tuleb saata järgmine päring:
{ "parameter": "score" }
Server tagastab:
{"value": 1200, "parameter": "score"}
Mänguseis
Teil on võimalus pärida, mis on antud hetkel mänguseis. Mänguseis tagastatakse 20x10 maatriksina.
{ "parameter": "state" }
Server tagastab:
{"value": [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ..., [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]], "parameter": "state"}
Mängu staatus
{ "parameter": "status" }
Mängu tase
{ "parameter": "level" }
Server tagastab:
{"value": "12", "parameter": "level"}
Mall koos koodinäitega
Configuration.java <source lang="java"> public class Configuration {
private int level; private int lookahead; private int seed; private final String uniid = "UNIID"; public Configuration(int level, int lookahead, int seed) { this.level = level; this.lookahead = lookahead; this.seed = seed; }
public String toString() { return "todo"; }
} </source>
HW02.java <source lang="java"> public class HW02 {
public static void main(String[] args) { Configuration c = new Configuration(1, 1, 1); run(c.toString()); } // you don't need to use that public static void setup() { }
public static int run(String connectionString) { try { // false - only "O" blocks are sent DroptrisConnection conn = new DroptrisConnection("UNIID", false); String line; // read "welcoe" line from connection line = conn.readLine(); System.out.println(line); // read block line = conn.readLine(); // parse line.., get the block // send column index and rotation conn.sendAction("{\"column\": 0, \"rotation\": 1}"); // read next line, the next block information line = conn.readLine(); conn.sendAction("{\"column\": 8, \"rotation\": 1}"); line = conn.readLine(); conn.sendAction("{\"column\": 4, \"rotation\": 0}"); line = conn.readLine(); conn.sendAction("{\"column\": 2, \"rotation\": 1}"); line = conn.readLine(); conn.sendAction("{\"column\": 6, \"rotation\": 1}"); line = conn.readLine(); conn.sendAction("{\"column\": 1, \"rotation\": 0}"); line = conn.readLine();
System.out.println(conn.readScoreData()); System.out.println("game over!"); return 400; } catch (IOException e) { e.printStackTrace(); } return 0; }
} </source>
Klassis HW02
peab olema meetod public static int run(String connectionString)
.
Mängu näide
Programm saadab serverile (mängu näide ei vasta etteantud seed väärtusele):
{ "uniid": "mati.gaal", "seed": 12345678 "level": 1 "lookahead": 0 }
Server vastab:
{"code": 200, "message": "Game is starting! Good luck!"}
Server saadab kujundi info.
{"block": "Z", "next": ["O"]}
Programm otsustab selle kujundi paigutada vasakule äärde ilma pööramata.
Programm saadab serverile:
{"column": 0, "rotation": 0}
Tekib järgmine seis:
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |11 | | 11 | --------------
Mäng jätkub, server saadab uue kujundi:
{"block": "O", "next": ["Z"]}
Programm otsustab selle panna eelmise kujundi kõrvale:
{"column": 3, "rotation": 0}
Tekib seis:
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |11 11 | | 1111 | --------------
Mäng jätkub, server saadab uue kujundi:
{"block": "Z", "next": ["I"]}
Programm otsustab selle panna eelmise kujundi kõrvale:
{"column": 5, "rotation": 0}
Tekib seis:
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |11 1111 | | 1111 11 | --------------
Mäng jätkub, server saadab uue kujundi:
{"block": "I", "next": ["T"]}
Programm otsustab selle panna eelmise kujundi kõrvale püstiselt (ehk tuleb pöörata)
{"column": 8, "rotation": 1}
Tekib seis:
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 | | 1 | |11 1111 1 | | 1111 111 | --------------
jne