Erinevus lehekülje "ITI0011:HW02 Droptris" redaktsioonide vahel
(Uus lehekülg: 'Tagas ITI0011 lehele. == Info == Ülesande kaitsmised: 21. - 25. märts 2016<br /> Kaust gitis: HW01 == Ülesanne == Iga-aastane galaktikatevaheline festival "KnownFlying...') |
|||
(ei näidata sama kasutaja 26 vahepealset redaktsiooni) | |||
1. rida: | 1. rida: | ||
− | Tagas [[ITI0011]] lehele. | + | Tagas [[ITI0011]] lehele.<br /> |
+ | Vaata lahendamise juhendit: [[ITI0011:HW02_Droptris_Juhend]]<br /> | ||
+ | Vaata ühenduse kirjeldust: [[#Suhtlemine_serveriga]]<br /> | ||
+ | Tõmba teek (vaid põhiosa jaoks): [[Meedia:Droptris_connection_v0.1.zip]]<br /> | ||
+ | https://cs.ttu.ee/games/droptris<br /> | ||
+ | Viiteid: [[#Viited]] | ||
== Info == | == Info == | ||
− | Ülesande kaitsmised: | + | Ülesande kaitsmised: 28. - 29. märts 2016<br /> |
− | Kaust gitis: | + | Kaust gitis: HW02 |
== Ülesanne == | == Ülesanne == | ||
30. rida: | 35. rida: | ||
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. | 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). | ||
+ | |||
+ | [http://mercurymasterpunk.ca/images/tetris.jpg Vaata värvilist pilti kujundiest]. Loe pööramisest täpsemalt altpoolt. | ||
+ | |||
+ | ==== O ==== | ||
+ | <pre> | ||
+ | rot:0 | ||
+ | (2x2) | ||
+ | ** | ||
+ | ** | ||
+ | </pre> | ||
+ | Kujund on igasuguse pööramise korral täpselt samasugune. | ||
+ | |||
+ | ==== I ==== | ||
+ | <pre> | ||
+ | rot: 0 rot: 1 | ||
+ | (4x1) (1x4) | ||
+ | * **** | ||
+ | * | ||
+ | * | ||
+ | * | ||
+ | </pre> | ||
+ | Mõõtmed (kõrgus x laius): 4 x 1 | ||
+ | |||
+ | ==== J ==== | ||
+ | <pre> | ||
+ | rot: 0 rot: 1 rot: 2 rot: 3 | ||
+ | (3x2) (2x3) (3x2) (2x3) | ||
+ | * * ** *** | ||
+ | * *** * * | ||
+ | ** * | ||
+ | </pre> | ||
+ | |||
+ | ==== L ==== | ||
+ | <pre> | ||
+ | rot: 0 rot: 1 rot: 2 rot: 3 | ||
+ | (3x2) (2x3) (3x2) (2x3) | ||
+ | * *** ** * | ||
+ | * * * *** | ||
+ | ** * | ||
+ | </pre> | ||
+ | |||
+ | ==== T ==== | ||
+ | <pre> | ||
+ | rot: 0 rot: 1 rot: 2 rot: 3 | ||
+ | (2x3) (3x2) (2x3) (3x2) | ||
+ | * * *** * | ||
+ | *** ** * ** | ||
+ | * * | ||
+ | </pre> | ||
+ | |||
+ | ==== Z ==== | ||
+ | <pre> | ||
+ | rot: 0 rot: 1 | ||
+ | (2x3) (3x2) | ||
+ | ** * | ||
+ | ** ** | ||
+ | * | ||
+ | </pre> | ||
+ | |||
+ | ==== S ==== | ||
+ | <pre> | ||
+ | rot: 0 rot: 1 | ||
+ | (2x3) (3x2) | ||
+ | ** * | ||
+ | ** ** | ||
+ | * | ||
+ | </pre> | ||
+ | |||
+ | == 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): | ||
+ | <pre> | ||
+ | { | ||
+ | "uniid": "mati.gaal", | ||
+ | "seed": 12345678, | ||
+ | "level": 1, | ||
+ | "lookahead": 0 | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | lookahead 0 = can’t see what you get next, 1 = see 1 next block etc. | ||
+ | |||
+ | Server vastab näiteks: | ||
+ | <pre> | ||
+ | { | ||
+ | "message": "Game is starting! Good luck!", # or whatever else message "Unknown message!", | ||
+ | "code": 200 | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | === 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 <code>readLine()</code>, mis tagastab tulemuse json kujul (vt socketi näidet). | ||
+ | |||
+ | ==== Kasutades socketit ==== | ||
+ | |||
+ | Server saadab info kujul: | ||
+ | <pre> | ||
+ | { | ||
+ | "block": "I", | ||
+ | "next": ["J", "L", "O"] # nii mitu kui algselt lookaheadiga sai määratud | ||
+ | } | ||
+ | </pre> | ||
+ | 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 <code>sendAction(json)</code>, kus json on samasugune jsoni String nagu socketi näites allpool. | ||
+ | |||
+ | ==== Kasutades socketit ==== | ||
+ | |||
+ | <pre> | ||
+ | { | ||
+ | "column": 4, | ||
+ | "rotation": 1 | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | === Mängu skoor === | ||
+ | |||
+ | Aktiivse ühenduse puhul on teil võimalus küsida hetke punktiseisu. | ||
+ | |||
+ | ==== Kasutades teeki ==== | ||
+ | |||
+ | Kasutage meetodit <code>readScoreData()</code>, mis tagastab tulemuse json kujul (vt socketi näidet). | ||
+ | |||
+ | ==== Kasutades socketit ==== | ||
+ | |||
+ | Serverisse tuleb saata järgmine päring: | ||
+ | <pre> | ||
+ | { | ||
+ | "parameter": "score" | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | Server tagastab: | ||
+ | <pre> | ||
+ | {"value": 1200, "parameter": "score"} | ||
+ | </pre> | ||
+ | |||
+ | === Mänguseis === | ||
+ | |||
+ | Teil on võimalus pärida, mis on antud hetkel mänguseis. Mänguseis tagastatakse 20x10 maatriksina. | ||
+ | <pre> | ||
+ | { | ||
+ | "parameter": "state" | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | Server tagastab: | ||
+ | <pre> | ||
+ | {"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"} | ||
+ | </pre> | ||
+ | |||
+ | === Mängu staatus === | ||
+ | |||
+ | <pre> | ||
+ | { | ||
+ | "parameter": "status" | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | == Mall koos koodinäitega == | ||
+ | |||
+ | Configuration.java | ||
+ | <source lang="java"> | ||
+ | /** | ||
+ | * Configuration for HW02 Droptris. | ||
+ | */ | ||
+ | public class Configuration { | ||
+ | /** | ||
+ | * Game level (indicates which pieces are used). | ||
+ | */ | ||
+ | private int level; | ||
+ | /** | ||
+ | * How many pieces ahead are visible. | ||
+ | */ | ||
+ | private int lookahead; | ||
+ | /** | ||
+ | * Seed number (for random). | ||
+ | */ | ||
+ | private int seed; | ||
+ | /** | ||
+ | * Student uni-id. | ||
+ | */ | ||
+ | private final String uniid = "UNIID"; | ||
+ | |||
+ | /** | ||
+ | * Default constructor. | ||
+ | * @param level Level to play. | ||
+ | * @param lookahead Lookahead to use. | ||
+ | * @param seed Seed to use. | ||
+ | */ | ||
+ | public Configuration(int level, int lookahead, int seed) { | ||
+ | this.level = level; | ||
+ | this.lookahead = lookahead; | ||
+ | this.seed = seed; | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | public String toString() { | ||
+ | return "todo"; | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | HW02.java | ||
+ | <source lang="java"> | ||
+ | import java.io.IOException; | ||
+ | |||
+ | /** | ||
+ | * Homework 02 - Droptris AI. | ||
+ | * https://courses.cs.ttu.ee/pages/ITI0011:HW02_Droptris | ||
+ | */ | ||
+ | public class HW02 { | ||
+ | /** | ||
+ | * The main method. You can use this to initialize the game. | ||
+ | * Tester will not execute the main method. | ||
+ | * @param args Arguments from command line | ||
+ | */ | ||
+ | public static void main(String[] args) { | ||
+ | Configuration c = new Configuration(1, 1, 1); | ||
+ | run(c.toString()); | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Optional setup. This method will be called | ||
+ | * before the game is started. You can do some | ||
+ | * precalculations here if needed. | ||
+ | * | ||
+ | * If you don't need to precalculate anything, | ||
+ | * just leave it empty. | ||
+ | */ | ||
+ | public static void setup() { | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * The method to execute your AI. | ||
+ | * @param connectionString JSON-formatted connection string. | ||
+ | * If you implement Socket connection yourself | ||
+ | * you should use this string directly when connecting. | ||
+ | * If you use DroptrisConnection, you can ignore that. | ||
+ | * @return The final score. You should read the score from the server. | ||
+ | */ | ||
+ | public static int run(String connectionString) { | ||
+ | try { | ||
+ | // false - only "O" blocks are sent | ||
+ | DroptrisConnection conn = new DroptrisConnection("ago.luberg", false); | ||
+ | String line; | ||
+ | // read "welcome" line from connection | ||
+ | line = conn.readLine(); | ||
+ | System.out.println(line); | ||
+ | // read block | ||
+ | line = conn.readLine(); | ||
+ | System.out.println(line); | ||
+ | // 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(); | ||
+ | System.out.println(line); | ||
+ | conn.sendAction("{\"column\": 8, \"rotation\": 1}"); | ||
+ | line = conn.readLine(); | ||
+ | System.out.println(line); | ||
+ | conn.sendAction("{\"column\": 4, \"rotation\": 0}"); | ||
+ | line = conn.readLine(); | ||
+ | System.out.println(line); | ||
+ | conn.sendAction("{\"column\": 2, \"rotation\": 1}"); | ||
+ | line = conn.readLine(); | ||
+ | System.out.println(line); | ||
+ | conn.sendAction("{\"column\": 6, \"rotation\": 1}"); | ||
+ | line = conn.readLine(); | ||
+ | System.out.println(line); | ||
+ | conn.sendAction("{\"column\": 1, \"rotation\": 0}"); | ||
+ | line = conn.readLine(); | ||
+ | System.out.println(line); | ||
+ | if (line == null) { | ||
+ | // in this example, we still get blocks | ||
+ | // as the game is not over, but in general | ||
+ | // if connection readLine returns null, | ||
+ | // there are no more blocks | ||
+ | System.out.println("no more blocks!"); | ||
+ | } | ||
+ | |||
+ | System.out.println(conn.readScoreData()); | ||
+ | System.out.println("game over!"); | ||
+ | // you should implement score parsing | ||
+ | // here we just return 400 | ||
+ | return 400; | ||
+ | } catch (IOException e) { | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | return 0; | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | == Mängu näide == | ||
+ | |||
+ | Programm saadab serverile (mängu näide ei vasta etteantud seed väärtusele): | ||
+ | <pre> | ||
+ | { | ||
+ | "uniid": "mati.gaal", | ||
+ | "seed": 12345678, | ||
+ | "level": 1, | ||
+ | "lookahead": 0 | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | Server vastab: | ||
+ | <pre> | ||
+ | {"code": 200, "message": "Game is starting! Good luck!"} | ||
+ | </pre> | ||
+ | |||
+ | Server saadab kujundi info. | ||
+ | <pre> | ||
+ | {"block": "Z", "next": ["O"]} | ||
+ | </pre> | ||
+ | |||
+ | Programm otsustab selle kujundi paigutada vasakule äärde ilma pööramata. | ||
+ | |||
+ | Programm saadab serverile: | ||
+ | <pre> | ||
+ | {"column": 0, "rotation": 0} | ||
+ | </pre> | ||
+ | |||
+ | Tekib järgmine seis: | ||
+ | <pre> | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | |11 | | ||
+ | | 11 | | ||
+ | -------------- | ||
+ | </pre> | ||
+ | |||
+ | Mäng jätkub, server saadab uue kujundi: | ||
+ | <pre> | ||
+ | {"block": "O", "next": ["Z"]} | ||
+ | </pre> | ||
+ | |||
+ | Programm otsustab selle panna eelmise kujundi kõrvale: | ||
+ | <pre> | ||
+ | {"column": 3, "rotation": 0} | ||
+ | </pre> | ||
+ | |||
+ | Tekib seis: | ||
+ | <pre> | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | |11 11 | | ||
+ | | 1111 | | ||
+ | -------------- | ||
+ | </pre> | ||
+ | |||
+ | Mäng jätkub, server saadab uue kujundi: | ||
+ | <pre> | ||
+ | {"block": "Z", "next": ["I"]} | ||
+ | </pre> | ||
+ | |||
+ | Programm otsustab selle panna eelmise kujundi kõrvale: | ||
+ | <pre> | ||
+ | {"column": 5, "rotation": 0} | ||
+ | </pre> | ||
+ | |||
+ | Tekib seis: | ||
+ | <pre> | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | |11 1111 | | ||
+ | | 1111 11 | | ||
+ | -------------- | ||
+ | </pre> | ||
+ | |||
+ | Mäng jätkub, server saadab uue kujundi: | ||
+ | <pre> | ||
+ | {"block": "I", "next": ["T"]} | ||
+ | </pre> | ||
+ | |||
+ | Programm otsustab selle panna eelmise kujundi kõrvale püstiselt (ehk tuleb pöörata) | ||
+ | <pre> | ||
+ | {"column": 8, "rotation": 1} | ||
+ | </pre> | ||
+ | |||
+ | Tekib seis: | ||
+ | <pre> | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | 1 | | ||
+ | | 1 | | ||
+ | |11 1111 1 | | ||
+ | | 1111 111 | | ||
+ | -------------- | ||
+ | </pre> | ||
+ | |||
+ | jne | ||
+ | |||
+ | == Viited == | ||
+ | |||
+ | * https://www.youtube.com/watch?v=t7mxKN797V8 | ||
+ | * https://codemyroad.wordpress.com/2013/04/14/tetris-ai-the-near-perfect-player/ |
Viimane redaktsioon: 22. märts 2016, kell 08:01
Tagas ITI0011 lehele.
Vaata lahendamise juhendit: ITI0011:HW02_Droptris_Juhend
Vaata ühenduse kirjeldust: #Suhtlemine_serveriga
Tõmba teek (vaid põhiosa jaoks): Meedia:Droptris_connection_v0.1.zip
https://cs.ttu.ee/games/droptris
Viiteid: #Viited
Info
Ülesande kaitsmised: 28. - 29. märts 2016
Kaust gitis: HW02
Ü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" }
Mall koos koodinäitega
Configuration.java <source lang="java"> /**
* Configuration for HW02 Droptris. */
public class Configuration {
/** * Game level (indicates which pieces are used). */ private int level; /** * How many pieces ahead are visible. */ private int lookahead; /** * Seed number (for random). */ private int seed; /** * Student uni-id. */ private final String uniid = "UNIID";
/** * Default constructor. * @param level Level to play. * @param lookahead Lookahead to use. * @param seed Seed to use. */ public Configuration(int level, int lookahead, int seed) { this.level = level; this.lookahead = lookahead; this.seed = seed; }
@Override public String toString() { return "todo"; }
} </source>
HW02.java <source lang="java"> import java.io.IOException;
/**
* Homework 02 - Droptris AI. * https://courses.cs.ttu.ee/pages/ITI0011:HW02_Droptris */
public class HW02 {
/** * The main method. You can use this to initialize the game. * Tester will not execute the main method. * @param args Arguments from command line */ public static void main(String[] args) { Configuration c = new Configuration(1, 1, 1); run(c.toString()); }
/** * Optional setup. This method will be called * before the game is started. You can do some * precalculations here if needed. * * If you don't need to precalculate anything, * just leave it empty. */ public static void setup() { }
/** * The method to execute your AI. * @param connectionString JSON-formatted connection string. * If you implement Socket connection yourself * you should use this string directly when connecting. * If you use DroptrisConnection, you can ignore that. * @return The final score. You should read the score from the server. */ public static int run(String connectionString) { try { // false - only "O" blocks are sent DroptrisConnection conn = new DroptrisConnection("ago.luberg", false); String line; // read "welcome" line from connection line = conn.readLine(); System.out.println(line); // read block line = conn.readLine(); System.out.println(line); // 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(); System.out.println(line); conn.sendAction("{\"column\": 8, \"rotation\": 1}"); line = conn.readLine(); System.out.println(line); conn.sendAction("{\"column\": 4, \"rotation\": 0}"); line = conn.readLine(); System.out.println(line); conn.sendAction("{\"column\": 2, \"rotation\": 1}"); line = conn.readLine(); System.out.println(line); conn.sendAction("{\"column\": 6, \"rotation\": 1}"); line = conn.readLine(); System.out.println(line); conn.sendAction("{\"column\": 1, \"rotation\": 0}"); line = conn.readLine(); System.out.println(line); if (line == null) { // in this example, we still get blocks // as the game is not over, but in general // if connection readLine returns null, // there are no more blocks System.out.println("no more blocks!"); }
System.out.println(conn.readScoreData()); System.out.println("game over!"); // you should implement score parsing // here we just return 400 return 400; } catch (IOException e) { e.printStackTrace(); } return 0; }
} </source>
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