Udvalgte opgaver

Opgavebeskrivelse

Lave en Slider Puzzle (4×4 tiles, med én manglende tile), hvor man kan ‘skubbe’ tiles rundt, og kombinere sig frem til det rigtige billede.

Funktioner for opgaven

  • Opbygge tiles
  • Blande tiles
  • Skifte billede
  • Tælle træk
  • Skubbe hele rækker
  • Tjekke om puslespillet er løst

Opgaven skal løses med

  • HTML
  • CSS
  • Javascript eller jQuery

Disclaimer!
Jeg er ikke ejer af Lego Batman billederne.
De er fundet på nettet via google og anvendes udelukkende til at løse en skole-relateret opgave.

Lego Batman Puzzle

Antal træk:
HTML
<div id="slidecontent">
    <h3 class="h3Puzzle">Lego Batman Puzzle</h3>
    <h5 style="color:white; font-family: Impact, Haettenschweiler, 'Arial Narrow Bold', sans-serif !important; margin-top: 0 !important;">Antal træk: <span id="moves"></span></h5>
    <div id="puzzle">
        <div id="tile11" class="img11 bg1 finished"></div>
        <div id="tile12" class="img12 bg1 finished"></div>
        <div id="tile13" class="img13 bg1 finished"></div>
        <div id="tile14" class="img14 bg1 finished"></div>

        <div id="tile21" class="img21 bg1 finished"></div>
        <div id="tile22" class="img22 bg1 finished"></div>
        <div id="tile23" class="img23 bg1 finished"></div>
        <div id="tile24" class="img24 bg1 finished"></div>

        <div id="tile31" class="img31 bg1 finished"></div>
        <div id="tile32" class="img32 bg1 finished"></div>
        <div id="tile33" class="img33 bg1 finished"></div>
        <div id="tile34" class="img34 bg1 finished"></div>

        <div id="tile41" class="img41 bg1 finished"></div>
        <div id="tile42" class="img42 bg1 finished"></div>
        <div id="tile43" class="img43 bg1 finished"></div>
        <div id="tile44" class="img44 bg1 finished"></div>
    </div>
    <div id="options">
        <select name="images" id="images"></select>
        <button id="btnShuffler">Shuffle Puzzle</button>
    </div>
</div>
CSS
#slidecontent {
    width: 620px;
    align-items: center;
    text-align: center;
    color: white;
    margin:0 auto;
}

#puzzle {
    border: solid 0px white;
    border-radius: 15px;
    overflow: hidden;
    margin: 0px auto;
    width: fit-content;
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
}

.h3Puzzle {
    margin: 0 !important;
    padding:0 !important;
    color: gold;
}

.completed {
    box-shadow: rgb(255 241 74 / 26%) 0px 0px 70px 4px;
}

.unfinished {
    width: 144px;
    height: 144px;
    border: 3px solid #1e1e1e;
    box-shadow: inset 4px 4px 15px -11px white, inset -4px -4px 15px 0px black, inset 6px 6px 11px -8px white;
    cursor: pointer;
    float: left;
    border-radius: 15px;

}
.finished {
    width: 150px;
    height: 150px;
    cursor: default;
    float: left;
}

.img11 {
    background-position: 0% 0%;
}.img12 {
    background-position: 33.33% 0%;
}.img13 {
    background-position: 66.66% 0%;
}.img14 {
    background-position: 99.99% 0%;
}

.img21 {
    background-position: 0% 33.33%;
}.img22 {
    background-position: 33.33% 33.33%;
}.img23 {
    background-position: 66.66% 33.33%;
}.img24 {
    background-position: 99.99% 33.33%;
}

.img31 {
    background-position: 0% 66.66%;
}.img32 {
    background-position: 33.33% 66.66%;
}.img33 {
    background-position: 66.66% 66.66%;
}.img34 {
    background-position: 99.99% 66.66%;
}

.img41 {
    background-position: 0% 99.99%;
}.img42 {
    background-position: 33.33% 99.99%;
}.img43 {
    background-position: 66.66% 99.99%;
}.img44 {
    background-position: 99.99% 99.99%;
}.img44.unfinished {
    background-image: none !important;
    box-shadow: none;
}

.bg1, .bg2, .bg3, .bg4, .bg5 {
    background-repeat: no-repeat;
    background-size: 600px;
}

.bg1 {
    background-image: url("img/legoBatman1.jpg");
}
.bg2 {
    background-image: url("img/legoBatman2.jpg");
}
.bg3 {
    background-image: url("img/legoBatman3.jpg");
}
.bg4 {
    background-image: url("img/legoBatman4.jpg");
}
.bg5 {
    background-image: url("img/legoBatman5.jpg");
}

#images, #btnShuffler {
    background-color: gold;
    font-family: Impact, Haettenschweiler, 'Arial Narrow Bold', sans-serif;
    font-size: 20px;
    padding: 8px 20px;
    margin: 20px;
    width: 200px;
    cursor: pointer;
    border-radius: 5px;
    border-width: 0px;
    height: 40px;
    align-items: center;
    line-height: normal;
    color:black;
}

button#btnShuffler:focus, button#btnShuffler:hover {
    outline: 0px !important;
    color: black;
}
jQuery
// Bygger div tiles i html'en
function buildPuzzle(bg) {
    $('div#puzzle').empty();
    for (let row = 1; row <= 4; row++)
        for (let cell = 1; cell <= 4; cell++) {
            $('#puzzle')
                .append($('<div>')
                    .attr('id', 'tile' + row + cell)
                    .addClass('img' + row + cell)
                    .addClass(bg)
                    .addClass('finished'))
        }
}

// Tilføjer options i select#images
for (i = 1; i <= 5; i++) {
    let options = $('<option>')
        .attr('value', 'bg' + i)
        .text('Lego Batman ' + i);
    $('#images').append(options);
}

// Ændrer css værdien for baggrundsbilledet
$('select#images').on('click', function changeBg() {
    $('#images option').each(function () {
        if ($(this).is(':selected')) {
            buildPuzzle($(this).val());
            clickTile();
            movesNr = 0;
            $('span#moves').text(movesNr);
            $('div#puzzle').removeClass();
        }
    })
});

var movesNr;
$('#btnShuffler').on('click', function shuffle() {
    let shuffleAmount = 100;

    // Ændre status fra 'færdig' til 'ikke-færdigt'
    for (let row = 1; row <= 4; row++) {
        for (let cell = 1; cell <= 4; cell++) {
            let div = $('div#tile' + row + cell);
            div.removeClass('finished');
            div.addClass('unfinished');
        }
    }

    // Byt tom felt med tilfældig nabobrik
    const neighbors = [1, -1, 0];
    while (0 < shuffleAmount--)
        for (let row = 1; row <= 4; row++)
            for (let cell = 1; cell <= 4; cell++) {
                let rndNeighbor = neighbors[Math.floor(Math.random() * 3)];
                let rowNeighbor = row + rndNeighbor;
                (rndNeighbor === 0) ?
                    rndNeighbor = neighbors[Math.floor(Math.random() * 2)] :
                    rndNeighbor = 0;
                let cellNeighbor = cell + rndNeighbor;

                let tile = $('div#tile' + row + cell);
                let emptyId = $('div.img44').attr('id');
                if (tile.attr('id') == emptyId)
                    if (rowNeighbor >= 1 && rowNeighbor <= 4 && cellNeighbor >= 1 && cellNeighbor <= 4) {
                        // console.log(tile.attr('id'), 'tile' + rowNeighbor + cellNeighbor);
                        swapTiles('tile' + row + cell, 'tile' + rowNeighbor + cellNeighbor);

                        movesNr = 0;
                        $('span#moves').text(movesNr);
                        $('div#puzzle').removeClass();
                    }
            }
});

// Bytter to tiles
function swapTiles(tile1, tile2) {
    let temp = $('div#' + tile1).attr('class');
    $('div#' + tile1).attr('class', $('div#' + tile2).attr('class'));
    $('div#' + tile2).attr('class', temp);

    movesNr++;
    $('span#moves').text(movesNr);
}

function clickTile() {
    $('#puzzle div').on('click', function () {
        let tile = $(this).attr('id').toString();
        let row = parseInt(tile.substring(4, 5));
        let cell = parseInt(tile.substring(5, 6));
        let empty = 'img44';

        emptyId = $('div.img44').attr('id');
        emptyRow = parseInt(emptyId.substring(4, 5));
        emptyCell = parseInt(emptyId.substring(5, 6));

        if ($(tile).attr('class') != empty && $('.unfinished').length === 16) {
            // Tjek om 'empty' har matchende row nr
            if (emptyRow === row)
                if (emptyCell < cell) 
                    while (cell > emptyCell++) {
                        swapTiles(emptyId, 'tile' + emptyRow + emptyCell);
                        emptyId = $('div.img44').attr('id');
                    }
                else
                    while (cell < emptyCell--) {
                        swapTiles(emptyId, 'tile' + emptyRow + emptyCell);
                        emptyId = $('div.img44').attr('id');
                    }

            // Tjek om 'empty' har matchende cell nr
            if (emptyCell === cell)
                if (emptyRow < row)
                    while (row > emptyRow++) {
                        swapTiles(emptyId, 'tile' + emptyRow + emptyCell);
                        emptyId = $('div.img44').attr('id');
                    }
                else
                    while (row < emptyRow--) {
                        swapTiles(emptyId, 'tile' + emptyRow + emptyCell);
                        emptyId = $('div.img44').attr('id');
                    }
        }

        // Tæl antal korrekte tiles
        let correctTiles = 0;
        for (let row = 1; row <= 4; row++)
            for (let cell = 1; cell <= 4; cell++) {
                let idNr = $('div#tile' + row + cell).attr('id').substring(4, 6);
                let classNr = $('div#tile' + row + cell).attr('class').substring(3, 5);

                if (idNr == classNr)
                    correctTiles++;
            }

        // Hvis alle tiles er rigtige
        if (correctTiles === 16 && $('.unfinished').length === 16) {
            for (let row = 1; row <= 4; row++)
                for (let cell = 1; cell <= 4; cell++) {
                    let div = $('div#tile' + row + cell);
                    div.removeClass('unfinished');
                    div.addClass('finished');
                }

            $('span#moves').text(movesNr + ' - GENNEMFØRT!');
            $('div#puzzle').addClass('completed');
        }
    })
}
clickTile();
Opgavebeskrivelse

Text

HTML
CSS
jQuery

Mere på vej...