ITI0011:HW02 Droptris

Allikas: Kursused
Mine navigeerimisribale Mine otsikasti

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

Viited