Black Friday Black Friday
Black Friday výprodej! Až 80 % extra bodů zdarma! Více informací zde

Cvičení k 10.-11. lekci Javy

Java Základní konstrukce Cvičení k 10.-11. lekci Javy American English version English version

Unicorn College ONEbit hosting Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

Následující 3 cvičení vám pomohou procvičit znalosti programování v Javě z minulých lekcí. Ve vlastním zájmu se je pokuste vyřešit sami. Pod článkem máte pro kontrolu řešení ke stažení. Ale pozor, jakmile se na něj podíváte bez vyřešení příkladů, ztrácí pro vás cvičení smysl a nic se nenaučíte :)

Pokud si opravdu nebudete vědět rady, podívejte se raději znovu do minulých tutoriálů a pokuste se na to přijít.

Jednoduchý příklad

Vytvořte program, který do konzole vykreslí šachovnici. Pro tmavá pole můžete využít plný obdélník "█" (Alt + 219) nebo kterýkoli jiný znak (např. #), pro světlá pole využijte mezeru.

Ukázka obrazovky programu:

Konzolová aplikace
██  ██  ██  ██
  ██  ██  ██  ██
██  ██  ██  ██
  ██  ██  ██  ██
██  ██  ██  ██
  ██  ██  ██  ██
██  ██  ██  ██
  ██  ██  ██  ██

Pro vykreslení samozřejmě využijte znalosti cyklů. Pro zjištění zda je pole světlé nebo tmavé vám pomůže modulo.

Středně pokročilý příklad

Naprogramujte aplikaci, která simuluje hru piškvorky pro 2 hráče. Aplikace vykresluje hrací plochu do konzole a nechává si střídavě od hráčů zadávat souřadnice, na které pokládají své kameny. Kontrolu výhry můžete zanedbat.

K reprezentaci hrací plochy využijte vícerozměrného pole.

Ukázka obrazovky programu:

Konzolová aplikace
  123456789
1
2
3  X
4
5     O
6
7
8
9

Na řadě je hráč s kolečky
Zadej pozici X kam chceš tahnout:
10
Zadej pozici Y kam chceš tahnout:
2
Neplatná pozice, zadej prosím znovu.
Zadej pozici X kam chceš tahnout:
3
Zadej pozici Y kam chceš tahnout:
2

Cvičení si vyzkoušejte ve vašem IDE. Níže v bonusovém příkladu piškvorky doděláme a budete mít možnost celou hru odevzdat.

Pokročilý příklad

Pomocí goniometrické funkce sinus vykreslete do konzole jednu periodu sinusoidy (grafu této funkce). Konzole má standardně velikost 80x25 znaků.

Protože je vypisování pouze jednosměrné (co napíšeme již nelze vzít zpět) a lineární (musíme zapisovat znaky, jak jdou po sobě), používá se u úloh podobného typu tzv. buffer. Buffer je pole znaků v paměti, kde si připravíme jak chceme obrazovku vykreslit a teprve až je vše jak potřebujeme, vykreslíme vše naráz. V tomto případě si vytvoříme buffer podle rozměrů, které si nastavíme (bude se jednat o 2D pole). Do tohoto bufferu zaneseme jednotlivé body sinu. Až budeme mít celý výpočet hotový, teprve poté celý buffer vykreslíme do konzole.

Ukázka obrazovky programu:

Konzolová aplikace



                                                     █████████
                                                 ████        ████
                                               ███              ███
                                             ██                    ██
                                           ██                       ███
                                          ██                          ██
                                        ██                              ██
                                       ██                                ██
██                                   ██                                    █
 ██                                 ██
  ███                             ██
    ██                          ███
      ██                       ██
       ███                   ██
          ██              ███
           ████        ████
               █████████

Perioda funkce sinus je 2 PI. Začněte vykreslením této křivky v poměru 1:1, sice bude malá, ale bude v konzoli vidět. Abyste dosáhli výsledku jako na obrázku, musíte ji pronásobit, aby se roztáhla. Jednotlivé souřadnice bodů vypočítávejte v desetinných číslech, výsledné souřadnice teprve zaokrouhlíte na celé znaky. Typicky vypočítáte mnohem více bodů, než kolik jich je vidět, protože pozice se zaokrouhlí.

Bonus: Rozšíření středně pokročilého příkladu

Jelikož máme konec našeho kurzu se základy, dotáhněme piškvorky do konce, ať si odtud něco odnesete :) Do piškvorek doimplementujte kontrolu konce hry. Mohou nastat tyto případy:

  • Výhra 5ti symboly v řadě
  • Výhra 5ti symboly ve sloupci
  • Výhra pěti symboly diagonálně
  • Zaplnění hrací plochy

Diagonální kontrola je poměrně komplikovaná, ostatní kontroly by vám neměly činit problémy.

V programu použijte následující texty:

  • Při výhře: "Vyhrál hráč s kolečky" / "Vyhrál hráč s křížky".
  • Při zaplnění hrací plochy: "Remíza."
  • Při zadání neceločíselné hodnoty: "Zadej prosím celé číslo"
  • Při zadání pozice mimo hrací plochu: "Neplatná pozice, zadej ji prosím znovu."

Program lze z důvodu dynamického počtu vstupů pouze odevzdat k ohodnocení.

Ukázka obrazovky programu:

Konzolová aplikace
  123456789
1
2  XXXX
3
4
5     O
6      O
7       O
8        O
9         O
Vyhrál hráč s kolečky

Začněte vykreslením aktuální (prázdné) hrací plochy, následně požádejte o vstup a poté opakujte.



 

Stáhnout

Staženo 147x (49.43 kB)
Aplikace je včetně zdrojových kódů v jazyce java

 

 

Článek pro vás napsal David Čápka
Avatar
Jak se ti líbí článek?
3 hlasů
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor sítě se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity (11)

 

 

Komentáře
Zobrazit starší komentáře (12)

Avatar
Lubor Pešek
Člen
Avatar
Lubor Pešek:10. července 17:40

No nevím... když to právě vypočítávám, tak mi z toho vyjde takový paskvil....
PS: na tom ukázkovém obrázku není sinusoida:) První dva kvadranty jsou kladné:)

public static void main(String[] args) {
        String[][] sinusoida = new String[80][21];
        for (int i = 0; i < sinusoida.length; i++) {
            for (int j = 0; j < sinusoida[i].length; j++) {
                sinusoida[i][j] = " ";
            }
        }
        for (int i = 0; i <= 360; i += 5) {
            sinusoida[i / 5][10 - (int) (Math.sin(Math.toRadians(i)) * 10)] = "█";
        }
        for (int i = 0; i < sinusoida[0].length; i++) {
            for (int j = 0; j < sinusoida.length; j++) {
                System.out.print(sinusoida[j][i]);
            }
            System.out.println();
        }
    }
Odpovědět 10. července 17:40
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
zitekv
Člen
Avatar
zitekv:18. října 18:43

Piškvorky odevzdat bez chyb byl boj.
Pěkná práce je tohle online kontrolování.
Jen vychytat pár drobností, které člověka dost srazí :-)
Bez toho co je špatně, se to blbě hledá. Musel jsem si stáhnout řešení a v něm jsou drobné odchylky od zadání uvedených v článku:

Správně je:

System.out.println("Zadej pozici X kam chceš tahnout: ");
...
"Remíza."
...
System.out.println("\nNa řadě je hráč s "...
...

A toto se při odevzdání nekontroluje:
Při zadání neceločíselné hodnoty: "Zadej prosím celé číslo".

 
Odpovědět 18. října 18:43
Avatar
David Jančík
Tým ITnetwork
Avatar
Odpovídá na zitekv
David Jančík:18. října 19:07

Ahoj, díky moc za feedback. Neustále na tom pracujeme a snažíme se vše vyladit. Bohužel nemůžeme zobrazovat celé výsledky testu, jelikož by pak bylo lehce odhalitelné, co testy kontrolují a rychle by ztratily smysl (ale zamyslíme se nad tím, co by šlo uživateli zobrazit). Nicméně snažíme se vše poladit, aby vám to bylo co nejvíce ku prospěchu. Bohužel je to však velmi sofistikovaná činnost, takže to ještě chvilku potrvá. Díky za pochopení a hodně zdaru ve tvé cestě za IT kariérou :)

Odpovědět  +1 18. října 19:07
Čím více času dostaneš, tím méně ho máš.
Avatar
zitekv
Člen
Avatar
zitekv:18. října 21:30

Pokročilý příklad taky vyřešen, ale odevzdat nejde :-(
Rozumím tomu proč (musel bych ho napsat absolutně stejně a to není reálné).
Takže aspoň takhle:

public static void main(String[] args) {
 String[][] pole=new String[80][25];

        double osaX=75;

        double osaY=16;
        double pomocna;
        double deltaX=(2*Math.PI)/osaX;
        double deltaY=1/(osaY/2);



        for (int y=0;y<pole[0].length;y++){
            for(int x=0;x<pole.length;x++) {
                pole[x][y]=" ";

            }

        }

        for (int i=0; i<pole.length;i++)
        {
            pomocna=(Math.sin(i*deltaX)/deltaY)+osaY/2;

            pole[i][(int)Math.round(pomocna)]="█";

        }
        for (int y=0;y<pole[0].length;y++){
            for(int x=0;x<pole.length;x++) {
                System.out.print(pole[x][y]);

            }
            System.out.println();
        }


        }
 
Odpovědět 18. října 21:30
Avatar
LeenaNap
Člen
Avatar
LeenaNap:31. října 11:42

Piškvorky mi daly zabrat. Ale naučila jsem se vytrvat a zkoušet a zkoušet a znova zkoušet funkčnost programu. Díky moc za všechna cvičení, učit se teorii je jedna věc, ale cvičení člověka doopravdy donutí pořádně přemýšlet a vrtat se v kódu, dokud všechno nefunguje tak jak má :-)

 
Odpovědět 31. října 11:42
Avatar
frantisek spacek:15. listopadu 17:00

Uff v Net Beans mi to funguje no kontroly online nepustia :-))
naozaj sa niekedy líši výstup
mám piškvorky ktoré sú s vylepšeným vystupom- pauzy v poli pre lepšiu čitateľnosť
ale podľa zadania mi kód neprejde kontrolou
ale tolko som sa sám so sebou pišvoriek nenahral :-)

package onlineapp;
import java.util.Arrays;
import java.util.Scanner;
class publicPole {

void vypisPole(String[][] hpole)
    {
String [][]plocha=hpole;
System.out.printf("\f \r ");
int horiz= plocha [0].length;
int vert= plocha.length;
for(int i=0;i<horiz;i++) System.out.printf("%d",(i+1));
System.out.println();
for(int i=0;i<vert;i++){
        System.out.printf("%d",(i+1));
        for(String j : plocha[i]){ System.out.printf("%s",j);}
        System.out.println();
                    }
System.out.println();
    }
}// koniec publicPole

class TestPole {

    boolean VTest(String znak,String[][] hpole){

        for (int i=0;i<hpole.length;i++){
           int  kontrola=0;
            for( String c : hpole[i])  {
                  if( !c.contains(znak))kontrola=0;
                  else kontrola++;
                  if (kontrola==5) {return(true);}
                                        }


                                          }
                         return(false);
    }// koniec VTest

    boolean HTest(String znak,String[][] hpole){

        for (int j=0;j<hpole[0].length;j++){
           int  kontrola=0;
            for( int i=0;i<hpole.length;i++)  {
                  if( !hpole[i][j].contains(znak))kontrola=0;
                  else kontrola++;
                  if (kontrola==5) {return(true);}
                                        }


                                          }
                         return(false);
    }// koniec HTest
     boolean DTest(String znak,String[][] hpole){

        int ihran=hpole.length;
        int jhran=hpole[0].length;
        // zľava doprava šikmý vpravo
        int j=0;
        while(j<(jhran-5)){
           int  kontrola=0;int y=0;int x=j;
              while(x<jhran && y<ihran){
                  if( !hpole[y][x].contains(znak))kontrola=0;
                  else kontrola++;
                  if (kontrola==5) {return(true);}
                                 x++; y++;
                                       }
              j++;
                          }
             // zhora dole šikmý vpravo
        int i=1;
        while(i<=(ihran-5)){
           int  kontrola=0;int y=i;int x=0;
              while(x<jhran && y<ihran){
                  if( !hpole[y][x].contains(znak))kontrola=0;
                  else kontrola++;
                  if (kontrola==5) {return(true);}
                                 x++; y++;
                                       }
              i++;
                          }
        // zľava doprava šikmý vľavo
        j=jhran-1;
        while(j>3){
           int  kontrola=0;int y=0;int x=j;
              while(x>=0 && y<ihran){
                  if( !hpole[y][x].contains(znak))kontrola=0;
                  else kontrola++;
                  if (kontrola==5) {return(true);}
                   x--; y++;
                                       }
              j--;
                          }
        // zhora dole šikmý vľavo
        i=1;
        while(i<ihran-5){
           int  kontrola=0;int y=i;int x=jhran-1;
              while(x>=0 && y<ihran){
                  if( !hpole[y][x].contains(znak))kontrola=0;
                  else kontrola++;
                  if (kontrola==5) {return(true);}
                    x--;y++;
                                    }
              i++;
                          }

        return(false);
            }// koniec  Dtest
}// koniec TestPole

public class Ferkocvičenie10_2m {

    public static void main(String[] args) {
      String[][] pole=new String[9][9];
      String[] znak= {"O","X"};
      publicPole vypis= new publicPole();
      TestPole  testuj= new TestPole();
      Scanner sc= new Scanner(System.in,"Windows-1250");
      int Counter=0;
      int Xpoz=0;
      int Ypoz=0;
      int opakujvstup=0;
      int kto=0;
      String Xvstup,Yvstup;
      int volnePol=(int)( Math.pow((double)pole.length,(double)pole[0].length));
      //inicializácia poľa
      for (int i=0;i<pole.length;i++){
          for(int j=0;j<pole[0].length;j++){
              pole[i][j]=" ";               }
                                     }
          vypis.vypisPole(pole);
      while(volnePol>0){
          kto=Counter%2;
          if (kto!=0)kto=1;
          System.out.print("Na řadě je hráč s ");
          if (kto==0){System.out.printf("kolečky\n");}
          else{System.out.printf("křížky\n");}

          do {
          opakujvstup=0;
          System.out.print("Zadej pozici X kam chceš tahnout:");
          Xvstup=sc.nextLine();
          System.out.print("Zadej pozici Y kam chceš tahnout:");
          Yvstup=sc.nextLine();
          if(Xvstup.contains(".")||Yvstup.contains(".")||Xvstup.contains(",")||Yvstup.contains(","))
                {
             System.out.println("Zadej prosím celé číslo");
             opakujvstup=1;
                }
          else {
              Xpoz=Integer.parseInt(Xvstup)-1;
              Ypoz=Integer.parseInt(Yvstup)-1;
              if (Xpoz>=(pole[0].length) ||Xpoz<0 ||Ypoz>=(pole.length)||Ypoz<0 ||pole[Ypoz][Xpoz]!=" ")
            {opakujvstup=1;
            System.out.println("Neplatná pozice, zadej prosím znovu.");
            }
               }
            }while(opakujvstup==1);

          if (Counter%2==0)pole[Ypoz][Xpoz]=znak[0];
          else pole[Ypoz][Xpoz]=znak[1];
             Counter++; volnePol--;
               vypis.vypisPole(pole);
               if( testuj.VTest(znak[kto], pole)|| testuj.HTest(znak[kto], pole) || testuj.DTest(znak[kto], pole) )
                    {
                       if(kto==0) {System.out.printf("Vyhrál hráč s kolečky\n");return;}
                               else
                                {System.out.printf("Vyhrál hráč s křížky\n");return;}
                    }
             }// koniec ak plné políčka
      System.out.println("Remíza.");
         }// koniec main
    }// koniec Program
 
Odpovědět 15. listopadu 17:00
Avatar
frantisek spacek:15. listopadu 17:04

K príkladu sinusoidy -sinus od 0 po 360 určite nevyzerá ako v príklade
predsa prvý quadrant 0-90 rastie a je pozitívny a v príklade je krivka v prvom quadrante negatívna
ako je potom nastavený online test?
poradí niekto ?

 
Odpovědět 15. listopadu 17:04
Avatar
zitekv
Člen
Avatar
Odpovídá na frantisek spacek
zitekv:15. listopadu 18:29

Test čeká výstup tak jak je nakreslený v článku.

 
Odpovědět 15. listopadu 18:29
Avatar
Odpovídá na zitekv
frantisek spacek:15. listopadu 18:33

Ok potom treba v zadani uviest posun intervalu o 180 stup pre jednoznacnost.inak to problem nie je.dakujem

 
Odpovědět  +1 15. listopadu 18:33
Avatar
Odpovídá na Lubor Pešek
frantisek spacek:15. listopadu 19:50

treba posunuť interval nie od 0 ale od 180stp

 
Odpovědět 15. listopadu 19:50
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 22. Zobrazit vše