Homepage von Papa

Projekt Schiffeversenken

Der Spielcode

In diesem Kapitel wird der Spielcode generiert und in der Datenbanktabelle gespeichert.

Wichtig zum Verständnis:

auf dieser Seite ist der Endzustand der version_03 dokumentiert. Die einzelnen Schritte sind:

  • Erstellen Modul generate_code.py
  • Aufruf generate_code.py in route routes.py für Spieler 1 einbauen
  • Speichern des Codes in der Datenbanktabelle
  • Implementieren von Beitritt Spieler 2 zum Spiel
  • Update der Datenbanktabelle
  • Bei Erfolg Weiterleiten an neue Seite game.html, diese muss dann auch in der routes.py aufgenommen werden

Eine genauere Beschreibung gibt es in der Projektdoku (Download hier) im gleichnamigen Kapitel.

Îm letzten Kapitel kam ja "nur" die Datei game.html dazu, daher brauchen wir keine neue Version, wir integrieren die nächsten Änderungen in der version_03. Schauen wir uns zuerst wieder die neue Struktur an:

Cool

Der Sourcecode für generate_code.py sieht so aus:

import random
from string import ascii_uppercase
from app_init import db
from sqlalchemy import func
from models import Game

# Funktion liefert Großbuchstaben für die übergebene 
# Anzahl an Stellen
def gen(length):
    gen_code = ""
    for _ in range(length):
        gen_code += random.choice(ascii_uppercase)
    
    return gen_code

# Funktion schaut nach, ob der generierte Code schon 
# vorhanden ist und liefert True oder False zurück
def lookup(gen_code):
    valid = True
    lookup = Game.query.all()

    for item in lookup:
        if str(item) == gen_code:
            valid = False
            break

    return valid

#Funktion liefert den generierten Code zurück
def generate_unique_code(length):
    generate_new = True
    is_valid = False
    gen_code = ""
    # Testschalter - falls gewünscht, unten einen 
    # in der DB existierenden Code mitgeben und 
    # Schalter auf True setzen 
    test = False
    
    while generate_new:
        is_valid = False
        while not is_valid:
            if test:
                #hier einen existierenden Code eingeben
                gen_code = "ABCDEF"
                test = False
            else:
                gen_code = gen(length)

            is_valid = lookup(gen_code)

            if is_valid:
                generate_new = False
            else:
                gen_code = gen(length)
                is_valid = lookup(gen_code)
            
        generate_new = False

    return gen_code
    

Die Erweiterung in unserem Backend, also der routes.py, umfasst den Aufruf von generate_code.py und die neue Route für die Seite game.html. Der Code sieht so aus:

from flask import Blueprint, render_template, request, redirect, url_for, session
import generate_code
from app_init import db
from models import Game

# Erstelle ein Blueprint für die Routen
main = Blueprint('main', __name__)

@main.route('/')
def index():
    return render_template('index.html')

@main.route("/setup", methods=["GET", "POST"])
def setup():
    error = None
    board_init = "0000000000" * 10  # 10x10 Spielfeld, initial leer
    # Wenn Methode "POST" ist, erwarten wir Formulardaten
    if request.method == "POST":
        if request.form.get('p1_pressed') == 'True':
            p_1_name = request.form.get("p_1_name", "").strip()
            # Generiere einen eindeutigen Code
            game_code = generate_code.generate_unique_code(6)
            new_game = Game(game_code=game_code,
                            p_1_name=p_1_name,
                            p_1_board=board_init,
                            p_1_status="Spiel generiert")
            db.session.add(new_game)
            db.session.commit()
            session["p_actual"] = p_1_name
            return redirect(url_for("main.game", game_code=game_code))

        # hier könnten wir auch else: setzen, da wir nur bei Klick auf einen  
        # der beiden Button hier landen  
        if request.form.get('p2_pressed') == 'True':
            p_2_name = request.form.get("p_2_name", "").strip()
            game_code = request.form.get("game_code", "").strip()
            #Versuch, den Datensatz mit dem angegebenen Code zu finden
            existing_game = Game.query.filter_by(game_code=game_code).first()
            if not existing_game:
                error = f"Ups {p_2_name}, der Code {game_code} existiert nicht"
                return render_template(
                    "setup.html", 
                    error=error, 
                    p_2_name=p_2_name, 
                    game_code=game_code
                )
            else:
                if existing_game.p_1_status != "Spiel generiert":
                    error = f"Ups {p_2_name}, das Spiel mit dem Code {game_code} ist bereits gestartet"
                    return render_template(
                        "setup.html", 
                        error=error, 
                        p_2_name=p_2_name, 
                        game_code=game_code
                    )
                else:
                    p_1_name = existing_game.p_1_name
                    game_code = existing_game.game_code
                    existing_game.p_2_name = p_2_name
                    existing_game.p_2_board = board_init
                    existing_game.p_2_status = "Spieler 2 angemeldet"
                    db.session.commit()
                    session["p_actual"] = p_2_name
                    return redirect(url_for("main.game", game_code=game_code))

    else:
        return render_template(
            "setup.html"
        )

@main.route("/game/")
def game(game_code):
    game_code=game_code
    p_actual = session.get("p_actual")

    return render_template(
        "game.html",
        game_code=game_code,
        p_actual=p_actual
    )
    

Die neue Seite game.html ist erst einmal nur rudimentär gefüllt und sieht so aus:

{% extends 'base.html' %}
{% block content %}

<div>
  <h3>aktueller Spieler ist {{ p_actual }}, Spielcode ist {{ game_code }}
</h3>
</div>

{% endblock %}
  

Lassen wir es laufen. Spieler Klaus eröffnet das Spiel:

Sprung auf game.html, der redirekt hat geklappt:

Der Eintrag in der Datenbanktabelle hat auch funktioniert:

Kathleen kommt dazu. Wir öffnen dazu den anderen Browser, geben dort http://127.0.0.1:5000 in die Suchleiste ein, Klick auf "Go" und landen auf unserer setup.html:

Der redirekt auf game.html hat auch hier funktioniert:

Auch hier wieder die Kontrolle in der Datenbanktabelle:

Super, das sieht doch gut aus.

Bravo, damit haben wir auch dieses Kapitel erfolgreich abgeschlossen! Dann können wir uns jetzt der Erstellung der Spielfelder widmen.


  • Zurück
  • Weiter

Inhaltsverzeichnis:

1. Vorwort
2. Das Projekt
3. Vorarbeiten
4. Das Projekt „Schiffeversenken“
4.1. Der Funktionsumfang
4.2. Die Planung der Umsetzung
4.3. Das Coden
4.3.1 Arbeiten mit Flask
4.3.2 Die Datenbank
4.3.3 Der Spielstart
4.3.4 Der Spielcode
4.3.5 Die Spielfelder
4.3.6 Setzen der Schiffe
4.3.7 Das Spielen
4.4. Die Veröffentlichung
5. Abschluss

© by Papa. Die Seite ist online seit 2020.

Menu

  • Startseite
  • Projekte
    • Übersicht aller Projekte
    • Schiffeversenken
    • Taschenrechner
    • Nachbau Snake
  • Helferlein
    • Übersicht Hilfprogramme
    • Fonts in pygame
    • Quellcode nach HTML
    • Text nach HTML
  • Impressum
  • Disclaimer

Modal content goes here