Веб дизајн/К2 2022 — разлика између измена

Извор: SI Wiki
Пређи на навигацију Пређи на претрагу
(додат К2 2022 из Веб дизајна)
 
м (Rešenje)
Ред 1: Ред 1:
{{tocright}}
{{tocright}}
{{нерешено}}
'''Drugi kolokvijum 2022. godine''' održan je 5. maja. Postavka nije dostupna sa stranice predmeta.


== Поставка ==
== Поставка ==
Ред 6: Ред 6:


== Решење ==
== Решење ==
=== <code>zadatak.html</code> ===
<syntaxhighlight lang="html">
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>
        <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
        <link href="zadatak.css" rel="stylesheet" />
        <script src="zadatak.js"></script>
    </head>
    <body>
        <main>
            <table>
                <tr>
                    <td id="field-0"></td>
                    <td id="field-1"></td>
                    <td id="field-2"></td>
                </tr>
                <tr>
                    <td id="field-3"></td>
                    <td id="field-4"></td>
                    <td id="field-5"></td>
                </tr>
                <tr>
                    <td id="field-6"></td>
                    <td id="field-7"></td>
                    <td id="field-8"></td>
                </tr>
            </table>
            <form>
                <input type="range" id="n" min="1" max="9">
                <input type="submit" id="start" value="Почни">
            </form>
            <p class="hidden">Игра је завршена!</p>
        </main>
    </body>
</html>
</syntaxhighlight>
=== <code>zadatak.css</code> ===
<syntaxhighlight lang="css">
main {
    padding: 20px;
    text-align: center;
}
table {
    margin: 0 auto;
}
td {
    border: 1px solid black;
    box-sizing: border-box;
    height: 100px;
    pointer-events: none;
    width: 100px;
}
form {
    margin-top: 20px;
}
.hidden {
    display: none;
}
.preview .selected {
    background-color: blue;
}
.playing td {
    pointer-events: all;
}
.playing .selected, .finished .selected {
    background-color: green;
}
.error .selected {
    background-color: red;
}
</syntaxhighlight>
=== <code>zadatak.js</code> ===
<syntaxhighlight lang="javascript">
$(function() {
    'use strict';
    // Niz tačnih polja u trenutnoj partiji
    let correctFields = null;
    // Identifikator intervala koji u 'preview' stanju boji ćelije
    let interval = 0;
    // DOM elementi
    const $startButton = $('#start');
    const $n = $('#n');
    const $message = $('p');
    const $table = $('table');
    const $cells = $('td');
    /**
    * Generiše indekse polja na tabli sa tačnim izborima, za dat broj polja
    * koji se generiše i ukupan broj polja.
    * @param {number} n Broj polja koji se generiše
    * @param {number} max Broj za jedan većeg od najvećeg broja koji se može
    *                    generisati
    * @returns {number[]} Niz brojeva koji predstavlja indekse polja na tabli
    *                    koji su tačni izbori
    */
    function selectFields(n, max) {
        const selected = new Set();
        while (selected.size < n) {
            selected.add(Math.floor(Math.random() * max));
        }
        return [...selected];
    }
    /**
    * Dohvata indeks zadate ćelije. Ćelije su numerisane brojevima počev od 0
    * i indeks ćelije se čuva u njenom identifikatoru.
    * @param {Node} cell DOM ćelija ili jQuery objekat ćelije čiji se indeks
    *                    dohvata
    * @returns Indeks zadate ćelije
    */
    function getCellIndex(cell) {
        return Number($(cell).attr('id').substring(6));
    }
    /**
    * Vraća indekse ćelija koje nisu izabrane.
    * @returns {number[]} Niz indeksa svih ćelija koje nisu izabrane
    */
    function getUnselectedFields() {
        const selectedFields = $('.selected')
            .map((_, cell) => getCellIndex(cell))
            .toArray();
        return correctFields.filter(field => !selectedFields.includes(field));
    }
    /**
    * Označava ćeliju sa zadatim indeksom kao izabranu.
    * @param {number} number Indeks ćelije za biranje
    */
    function selectField(number) {
        $('#field-' + number).addClass('selected');
    }
    /**
    * Uklanja oznaku da su izabrane sa svih ćelija.
    */
    function deselectAll() {
        $('.selected').removeClass('selected');
    }
    /**
    * Postavlja trenutno stanje igre kao klasu table za igru.
    *
    * Moguća stanja su:
    * - preview: Kada tačne ćelije postaju plave jedna po jedna
    * - playing: Kada korisnik može da bira ćelije i one postaju zelene
    * - error: Kada korisnik izabere pogrešnu ćeliju i ona postane crvena
    * - finished: Kada korisnik završi igru
    * @param {string} state Trenutno stanje igre
    */
    function setGameState(state) {
        $table.attr('class', state);
    }
    /**
    * Poziva se svake sekunde dok je igra u 'preview' stanju i boji jedno
    * polje u plavo ukoliko nije već obojeno, ili prelazi u 'playing' stanje
    * ako su sva već obojena.
    */
    function previewField() {
        const fieldsToPreview = getUnselectedFields();
        if (fieldsToPreview.length === 0) {
            deselectAll();
            setGameState('playing');
            clearInterval(interval);
        } else {
            selectField(fieldsToPreview[0]);
        }
    }
    /**
    * Vraća igru u 'playing' stanje nakon što je korisnik pogrešio.
    */
    function restoreStart() {
        setGameState('playing');
        deselectAll();
    }
    /**
    * Rukovalac pritiska na dugme za početak.
    * @param {ClickEvent} event Podaci događaja o pritisku na dugme
    */
    $startButton.click(event => {
        event.preventDefault();
        deselectAll();
        $startButton.attr('disabled', '');
        $message.addClass('hidden');
        setGameState('preview');
        correctFields = selectFields($n.val(), $cells.length);
        interval = setInterval(previewField, 1000);
    });
    /**
    * Rukovalac pritiska na ćeliju na tabli.
    * @param {ClickEvent} event Podaci događaja o pritisku na ćeliju
    */
    $cells.click(event => {
        const $cell = $(event.currentTarget);
        $cell.addClass('selected');
        if (correctFields.includes(getCellIndex($cell))) {
            if (getUnselectedFields().length === 0) {
                $message.removeClass('hidden');
                $startButton.removeAttr('disabled');
                setGameState('finished');
            }
        } else {
            setGameState('error');
            setTimeout(restoreStart, 1000);
        }
    });
});
</syntaxhighlight>


[[Категорија:Веб дизајн]]
[[Категорија:Веб дизајн]]
[[Категорија:Рокови]]
[[Категорија:Рокови]]

Верзија на датум 10. јул 2022. у 17:00

Drugi kolokvijum 2022. godine održan je 5. maja. Postavka nije dostupna sa stranice predmeta.

Поставка

Потребно је направити игру меморије. Треба направити квадрат 3x3 и слајдер за избор броја случајно генерисаних поља. Игра почиње тако што се генерише изабрани број случајних поља и поља се обоје у плаво (поља се боје једно по једно, и држе се обојена 1 s након чега се враћају у белу боју). Након тога треба да се изаберу та поља притиском миша. Све док се бирају добра поља она се боје у зелено, када се први пут изабере поље које није генерисано сва изабрана поља се боје у црвено и држе се тако 1 s након чега се враћају у белу боју. Треба омогућити да се након тога поново могу погађати поља. Ако се погоде сва поља треба исписати поруку да је игра завршена и омогућити да се поново могу генерисати поља.

Решење

zadatak.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>
        <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
        <link href="zadatak.css" rel="stylesheet" />
        <script src="zadatak.js"></script>
    </head>
    <body>
        <main>
            <table>
                <tr>
                    <td id="field-0"></td>
                    <td id="field-1"></td>
                    <td id="field-2"></td>
                </tr>
                <tr>
                    <td id="field-3"></td>
                    <td id="field-4"></td>
                    <td id="field-5"></td>
                </tr>
                <tr>
                    <td id="field-6"></td>
                    <td id="field-7"></td>
                    <td id="field-8"></td>
                </tr>
            </table>
            <form>
                <input type="range" id="n" min="1" max="9">
                <input type="submit" id="start" value="Почни">
            </form>
            <p class="hidden">Игра је завршена!</p>
        </main>
    </body>
</html>

zadatak.css

main {
    padding: 20px;
    text-align: center;
}

table {
    margin: 0 auto;
}

td {
    border: 1px solid black;
    box-sizing: border-box;
    height: 100px;
    pointer-events: none;
    width: 100px;
}

form {
    margin-top: 20px;
}

.hidden {
    display: none;
}

.preview .selected {
    background-color: blue;
}

.playing td {
    pointer-events: all;
}

.playing .selected, .finished .selected {
    background-color: green;
}

.error .selected {
    background-color: red;
}

zadatak.js

$(function() {
    'use strict';
    // Niz tačnih polja u trenutnoj partiji
    let correctFields = null;
    // Identifikator intervala koji u 'preview' stanju boji ćelije
    let interval = 0;
    // DOM elementi
    const $startButton = $('#start');
    const $n = $('#n');
    const $message = $('p');
    const $table = $('table');
    const $cells = $('td');
    /**
     * Generiše indekse polja na tabli sa tačnim izborima, za dat broj polja
     * koji se generiše i ukupan broj polja.
     * @param {number} n Broj polja koji se generiše
     * @param {number} max Broj za jedan većeg od najvećeg broja koji se može
     *                     generisati
     * @returns {number[]} Niz brojeva koji predstavlja indekse polja na tabli
     *                     koji su tačni izbori
     */
    function selectFields(n, max) {
        const selected = new Set();
        while (selected.size < n) {
            selected.add(Math.floor(Math.random() * max));
        }
        return [...selected];
    }
    /**
     * Dohvata indeks zadate ćelije. Ćelije su numerisane brojevima počev od 0
     * i indeks ćelije se čuva u njenom identifikatoru.
     * @param {Node} cell DOM ćelija ili jQuery objekat ćelije čiji se indeks
     *                    dohvata
     * @returns Indeks zadate ćelije
     */
    function getCellIndex(cell) {
        return Number($(cell).attr('id').substring(6));
    }
    /**
     * Vraća indekse ćelija koje nisu izabrane.
     * @returns {number[]} Niz indeksa svih ćelija koje nisu izabrane
     */
    function getUnselectedFields() {
        const selectedFields = $('.selected')
            .map((_, cell) => getCellIndex(cell))
            .toArray();
        return correctFields.filter(field => !selectedFields.includes(field));
    }
    /**
     * Označava ćeliju sa zadatim indeksom kao izabranu.
     * @param {number} number Indeks ćelije za biranje
     */
    function selectField(number) {
        $('#field-' + number).addClass('selected');
    }
    /**
     * Uklanja oznaku da su izabrane sa svih ćelija.
     */
    function deselectAll() {
        $('.selected').removeClass('selected');
    }
    /**
     * Postavlja trenutno stanje igre kao klasu table za igru.
     * 
     * Moguća stanja su:
     * - preview: Kada tačne ćelije postaju plave jedna po jedna
     * - playing: Kada korisnik može da bira ćelije i one postaju zelene
     * - error: Kada korisnik izabere pogrešnu ćeliju i ona postane crvena
     * - finished: Kada korisnik završi igru
     * @param {string} state Trenutno stanje igre
     */
    function setGameState(state) {
        $table.attr('class', state);
    }
    /**
     * Poziva se svake sekunde dok je igra u 'preview' stanju i boji jedno
     * polje u plavo ukoliko nije već obojeno, ili prelazi u 'playing' stanje
     * ako su sva već obojena.
     */
    function previewField() {
        const fieldsToPreview = getUnselectedFields();
        if (fieldsToPreview.length === 0) {
            deselectAll();
            setGameState('playing');
            clearInterval(interval);
        } else {
            selectField(fieldsToPreview[0]);
        }
    }
    /**
     * Vraća igru u 'playing' stanje nakon što je korisnik pogrešio.
     */
    function restoreStart() {
        setGameState('playing');
        deselectAll();
    }
    /**
     * Rukovalac pritiska na dugme za početak.
     * @param {ClickEvent} event Podaci događaja o pritisku na dugme
     */
    $startButton.click(event => {
        event.preventDefault();
        deselectAll();
        $startButton.attr('disabled', '');
        $message.addClass('hidden');
        setGameState('preview');
        correctFields = selectFields($n.val(), $cells.length);
        interval = setInterval(previewField, 1000);
    });
    /**
     * Rukovalac pritiska na ćeliju na tabli.
     * @param {ClickEvent} event Podaci događaja o pritisku na ćeliju
     */
     $cells.click(event => {
        const $cell = $(event.currentTarget);
        $cell.addClass('selected');
        if (correctFields.includes(getCellIndex($cell))) {
            if (getUnselectedFields().length === 0) {
                $message.removeClass('hidden');
                $startButton.removeAttr('disabled');
                setGameState('finished');
            }
        } else {
            setGameState('error');
            setTimeout(restoreStart, 1000);
        }
    });
});