Cvičenie 6 – Dvojrozmerné polia

Cieľom cvičení šiesteho týždňa je vyskúšať si ďalšiu prácu s poľom a dvojrozmerným poliami.

Poliarka

Budeme programovať triedu Poliarka rozširujúcu triedu Turtle, ktorá bude poznať niekoľko užitočných metód na prácu s poliami celých čísel. Na skúšanie práce s objektom triedy Poliarka nebudeme už používať ObjectInspector, ale experimentálny kód napíšeme priamo do metódy main v triede Launcher. Na zobrazenie obsahu poľa využijeme Arrays.toString:


1
2
3
int[] pole = ...;
...
System.out.println(Arrays.toString(pole));

Na vytvorenie poľa si môžete vytvoriť metódu, ktorá vytvorí náhodné pole, alebo môžete využiť konštrukciu na vytvorenie poľa spolu s inicializáciou:


1
int[] pole = {4, 1, 8, 1, 3, 9, 10, 3, 14};
  • Pridajte do triedy Poliarka metódu priemer, ktorá vypočíta priemer čísel uložených v poli referencovanom parametrom pole.

1
public double priemer(int[] pole)
  • Pridajte do triedy Poliarka metódu pocetOpakovani, ktorá vráti, koľko krát sa číslo cislo opakuje v poli referencovanom parametrom pole.

1
public int pocetOpakovani(int[] pole, int cislo)
  • Pridajte do triedy Poliarka metódu zdvojPole, ktorá vráti referenciu na novovytvorené pole int-ov, v ktorom každý prvok poľa bude zduplikovaný. Ak pôvodné pole malo hodnoty {3, 7, 1, 4}, hodnoty vo vrátenom poli budú: {3, 3, 7, 7, 1, 1, 4, 4}

1
public int[] zdvojPole(int[] pole)
  • Pridajte do triedy Poliarka metódu jeNeklesajuce, ktorá vráti, či prvky v poli referencovanom parametrom pole tvoria neklesajúcu postupnosť.

1
public boolean jeNeklesajuce(int[] pole)

Projekt: prepínače (logická hra)

Naprogramujte jednoduchú logickú hru pre jedného hráča. Hrá sa na hracej doske, ktorá má 6 x 6 políčok. Na každom políčku je kameň červenej alebo modrej farby. Na začiatku sú farby všetkých kameňov „náhodné“. Ťah hráča spočíva v kliknutí na niektorý z kameňov (do niektorého z políčok). Toto kliknutie spôsobí, že každý z jeho susedov (vľavo, vpravo, hore a dole) zmení svoju farbu na opačnú. T.j. ak bol kameň červený, po zmene farby bude modrý a naopak. Hrá sa končí, ak majú všetky kamene rovnakú farbu. Pripomeňme, že kameň, na ktorý sa kliklo, nemení svoju farbu.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import java.awt.Color;
import java.awt.event.MouseEvent;

import sk.upjs.jpaz2.*;


public class PrepinaciaHra extends WinPane {
        /**
         * Policka hracej dosky
         */

        private boolean[][] doska = new boolean[6][6];

        /**
         * Indikuje, ci hra bezi (hra konci, ked sa dosiahlo vyherne rozlozenie)
         */

        private boolean hraBezi = true;

        public PrepinaciaHra() {
                this.kresliMriezku();
                this.zamiesaj(30);
                this.kresliDosku();
        }

        /**
         * Nakresli mriezku
         */

        public void kresliMriezku() {
                Turtle k = new Turtle();
                this.add(k);

                for (int i = 1; i < 6; i++) {
                        k.setPosition(i * 50, 0);
                        k.moveTo(i * 50, this.getHeight());
                }

                for (int i = 1; i < 6; i++) {
                        k.setPosition(0, i * 50);
                        k.moveTo(this.getWidth(), i * 50);
                }

                this.remove(k);
        }

        /**
         * Nakresli farebne kamene na zaklade obsahu policok
         * v this.doska
         */

        public void kresliDosku() {
                // ???
        }

        /**
         * Overi, ci riadok r a stlpec s su platne suradnice
         */

        public boolean dobraSuradnica(int r, int s) {
                return (r >= 0) && (r < 6) && (s >= 0) && (s < 6);
        }

        /**
         * Zrealizuje tah, kedy bolo zatlaceny prepinac na policku
         * v riadku r a stlpci s
         */

        public void tah(int r, int s) {
                int[][] smery = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

                // ???
        }

        /**
         * Vytvori startovacie rozlozenie kamenov tak, ze spravi
         * zadany pocet nahodnych prepnuti (tahov)
         */

        public void zamiesaj(int pocetMiesani) {
                // ???
        }

        /**
         * Vrati, ci v aktualnom stave policok je kresliaca plocha
         * jednofarebna
         */

        public boolean jeVyherna() {
                return false;
        }

        @Override
        protected void onMouseClicked(int x, int y, MouseEvent detail) {
                // ???
        }
}

Asi nie každé iniciálne nastavenie farieb kameňov vedie k výhernej situácii. Preto na začiatku vytvorte iniciálne nastavenie farieb tak, že vychádzajúc z jednofarebnej konfigurácie hry zrealizujte zadaný počet náhodných ťahov.

Poliarka – ďalšie úlohy

  • Pridajte do triedy Poliarka metódu indexNajmensieho, ktorá vráti index políčka v poli referencovanom parametrom pole, ktorý má najmenšiu hodnotu spomedzi prvkov na indexoch start a koniec (vrátane)

1
public int indexNajmensieho(int[] pole, int start, int koniec)
  • Pridajte do triedy Poliarka metódu vymen, ktorá v poli referencovanom parametrom pole navzájom vymení obsah políčok na zadaných indexoch.

1
public void vymen(int[] pole, int idx1, int idx2)
  • Pridajte do triedy Poliarka metódu zahada, ktorá v poli referencovanom parametrom pole zrealizuje nasledujúci algoritmus (nech L je dĺžka poľa):
    • v prvom kroku vymení prvok na indexe 0 s prvkom, ktorý je spomedzi prvkov na indexoch 0L-1 najmenší
    • v druhom kroku vymení prvok na indexe 1 s prvkom, ktorý je spomedzi prvkov na indexoch 1L-1 najmenší
    • v treťom kroku vymení prvok na indexe 2 s prvkom, ktorý je spomedzi prvkov na indexoch 2L-1 najmenší
    • a tento postup sa opakuje, až kým sa nedôjde na koniec poľa

Využite metódy indexNajmensieho a vymen.


1
public void zahada(int[] pole)

Čo realizuje algoritmus implementovaný metódou zahada ?

  • Pridajte do triedy Poliarka metódu najcastejsiaHodnota, ktorá vráti najčastejšie sa vyskytujúcu hodnotu v poli referencovanom parametrom pole.

1
public int najcastejsiaHodnota(int[] pole)
  • Pridajte do triedy Poliarka metódu  bezDuplicity, ktorá vráti referenciu na novovytvorené pole, ktoré vznikne z pôvodného poľa odstránením duplicitných výskytov hodnôt. Pri riešení tejto úlohy zvážte vytvorenie pomocných metód:
    • na overenie počtu výskytov zadanej hodnoty v políčkach poľa medzi zadanými indexami (podobne ako to bolo v metóde  indexNajmensieho)
    • na zistenie počtu rôznych hodnôt, ktoré sú uložené v poli

1
public int[] bezDuplicity(int[] pole)
  • Vytvorte metódu, ktorá zadanú vetu (interpunkčné znamienka ignorujte) rozloží na slová (bez využitia metódy split objektov triedy String):

1
public String[] vetaNaSlova(String s)

Korytnačí futbal s odstraňovaním lôpt

  • Doprogramujte do projektu z prednášky odstraňovanie lôpt (lopta sa odstráni, ak na ňu klikneme so zatlačeným klávesom CTRL).

Je to to isté? (povinné)

V zdrojových kódoch možno často vidieť takéto if-y:


1
2
3
4
5
6
7
8
9
10
11
12
// p je premenná referenčného typu schopná uchovať referenciu na pole int-ov.
int[] p = ...;

// IF 1
if ((p == null) || (p.length == 0)) {
    return 0;
}

// IF 2
if ((p.length == 0) || (p == null)) {
    return 0;
}

Cieľom if-ov je vrátiť hodnotu 0, ak je referencia na pole null alebo pole je nulovej dĺžky. Ktorý z if-ov je správny a prečo?

  • IF 1,
  • IF 2,
  • IF 1 aj IF 2,
  • ani jeden.