Webbserverprogrammering 1

Show sourcecode

The following files exists in this folder. Click to view.

webbsrvprg/exercises/slutprojekt/

actions.php
administer_users.php
create_code.php
database_include.php
dbconnection.php
index.php
login copy.php
login.php
main.php
password_renewals.php
play copy.php
play.php
setup.php
sign_up.php
statistics.php
verification.php
verify_mail.php

play.php

228 lines UTF-8 Windows (CRLF)
<?php
session_start
();
ini_set('display_errors'1);
error_reporting(E_ALL);

include(
"dbconnection.php");
$adminrequired false;
include(
"verification.php");

$game_id $_GET["game_id"] ?? null;
$user_id $_SESSION["user_id"];

if (!
$game_id) {
    exit(
"Saknar spel_id");
}
?>

<!DOCTYPE html>
<html lang="sv">

<head>
    <meta charset="UTF-8">
    <title>Spela</title>

    <style>
        body {
            font-family: Arial;
        }

        .container {
            display: flex;
            gap: 40px;
        }

        .grid {
            display: grid;
            grid-template-columns: repeat(5, 40px);
        }

        .cell {
            width: 40px;
            height: 40px;
            border: 1px solid black;
            box-sizing: border-box;
            cursor: pointer;
        }

        #status {
            margin-top: 20px;
            font-weight: bold;
        }
    </style>
</head>

<body>
    <h3>Du har 20s på dig att göra ditt drag när det är din tur. Annars förlorar du</h3>

    <div class="container">
        <div>
            <h3>Dina skepp</h3>
            <div id="myGrid" class="grid"></div>
        </div>

        <div>
            <h3>Fiende</h3>
            <div id="enemyGrid" class="grid"></div>
        </div>
    </div>

    <div id="status">Laddar...</div>

    <script>
        const game_id = <?php echo ($game_id); ?>;
        const user_id = <?php echo ($user_id?>;

        let current_turn = null;
        let last_shot = null; // Behövs för att visa ens sista skott om man vann.

        function get(id) {
            return (document.getElementById(id));
        }

        function createGrid(id, clickable) {
            // AI-skapad funktion för att skapa en grid. Sätter massa celler i grid-boxen
            const grid = get(id);

            for (let y = 0; y < 5; y++) {
                for (let x = 0; x < 5; x++) {
                    const cell = document.createElement("div");
                    cell.className = "cell";
                    cell.dataset.x = x;
                    cell.dataset.y = y;

                    if (clickable) {
                        cell.onclick = () => shoot(x, y);
                    }

                    grid.appendChild(cell);
                }
            }
        }

        createGrid("myGrid", false); // Man skjuter inte på sin egen grid
        createGrid("enemyGrid", true);

        function setClickable(state) {
            // AI-skapad funktion som bestämmer om man kan klicka på cellerna eller inte.
            document.querySelectorAll("#enemyGrid .cell").forEach(c => {
                c.style.pointerEvents = state ? "auto" : "none";
            });
        }

        async function shoot(x, y) {
            if (current_turn != user_id) return; // Man kan bara skjuta när det är ens tur.

            last_shot = [x, y];

            await fetch(`actions.php?action=SHOOT&game_id=${game_id}&x=${x}&y=${y}`); // Skjuter.
            // Verifieras i servern att man faktiskt är med i den matchen.
        }

        function renderMove(move) {
            // Väljer motsvarande fiendecell
            const enemy_cell = document.querySelector(
                `#enemyGrid .cell[data-x="${move.x}"][data-y="${move.y}"]`
            );

            // Väljer motsvarande egen cell
            const my_cell = document.querySelector(
                `#myGrid .cell[data-x="${move.x}"][data-y="${move.y}"]`
            );

            let cell;
            if (move.user_id == user_id) {
                target_cell = enemy_cell
                // JAG sköt → visa på fiendegrid
            } else {
                target_cell = my_cell
                // MOTSTÅNDAREN sköt → visa på min grid
            }
            target_cell.style.background = move.hit == 1 ? "red" : "cadetBlue";
        }

        async function update(first = false) {
            const result = await fetch(`actions.php?action=GET_GAME&game_id=${game_id}`);
            const data = await result.json(); // Det är json-encodat

            current_turn = data.turn;

            if (data.game_over) {
                clearInterval(update_interval);

                /**
                 * Den skickar game_over om matchen inte är aktiv. 
                 * Om detta sker när man först går in på sidan så har man gjort fel
                 * Då skickas man rakt härifrån        
                 */
                if (first) {
                    window.location.href = "main.php";
                }

                let winner_text = (data.winner == user_id) ? "Du vann" : "Du förlorade";
                get("status").innerText = "Spelet är slut: " + winner_text;
                setClickable(false); // Man kan inte skjuta längre
                get("status").innerHTML += '<br><a href="main.php">Tillbaka till main</a>'

                if (data.reason == "win" && data.winner == user_id) {
                    // Om man vann för att man skjöt alla fiendeskepp.
                    // Då har den inte hunnit printa ut den sista rutan man sköt så den visas här
                    let target_cell = document.querySelector(`#enemyGrid .cell[data-x="${last_shot[0]}"][data-y="${last_shot[1]}"]`);
                    target_cell.style.background = "red";
                } else if (data.winner != user_id) {
                    // Rödmarkerar ens skepp om man förlorar
                    const my_cells = document.querySelectorAll("#myGrid .cell");
                    my_cells.forEach(cell => {
                        if (cell.style.background == "green") {
                            cell.style.background = "red";
                        }
                    });
                }
                return;
            }

            get("status").innerText =
                (data.turn == user_id) ? "Din tur" : "Väntar på motståndaren";

            setClickable(data.turn == user_id); // Om det är ens tur så kan man skjuta

            // Visar ens egna skepp-------------------------------------------
            const is_user_1 = data.user_1_id == user_id;
            let placements = (is_user_1) ? data.user_1_placements : data.user_2_placements; // Hämtar ens egna skepp

            let myShips = {};
            try {
                myShips = JSON.parse(placements); // Fattar inte så bra men tolkar till en dictionary
            } catch (e) {
                myShips = {};
            }

            Object.values(myShips).forEach(([x, y]) => { // Loopar igenom myships på nåt skumt sätt
                const cell = document.querySelector(
                    `#myGrid .cell[data-x="${x}"][data-y="${y}"]`
                ); // Väljer den cell med de koordinaterna i ens egna grid
                cell.style.background = "green"; // Markerar skeppet med grönt
            });
            // ------------------------------------------------------------------------------

            // Visar alla drag ____________________________________________________
            if (data.moves) {
                data.moves.forEach(move => {
                    renderMove(move);
                });
            }
        }

        update(true); // true säger att det är första uppdateringen.
        let update_interval = setInterval(update, 2000); // Updaterar en gång varannan sekund och en gång direkt (nedan)

        // Så att man checkar in även här.
        setInterval(() =>
            fetch("actions.php?action=CHECKIN", {
                cache: "no-store"
            }), 30000)
    </script>

</body>

</html>