update
This commit is contained in:
@@ -260,7 +260,7 @@ def drehen():
|
||||
"""Einer dreht, alle sehen dasselbe Ergebnis."""
|
||||
laeuft = (
|
||||
letzter_dreh["ergebnis"]
|
||||
and time.monotonic() - letzter_dreh["start"] < suggestions.DREH_DAUER
|
||||
and time.monotonic() - letzter_dreh["start"] < letzter_dreh["ergebnis"]["dauer"]
|
||||
)
|
||||
if laeuft:
|
||||
return {"started": False, "reason": "dreht bereits"}
|
||||
@@ -283,7 +283,7 @@ def letzter():
|
||||
return {"running": False, "result": None}
|
||||
vergangen = time.monotonic() - letzter_dreh["start"]
|
||||
return {
|
||||
"running": vergangen < suggestions.DREH_DAUER,
|
||||
"running": vergangen < ergebnis["dauer"],
|
||||
# Wer später dazukommt, überspringt den bereits gelaufenen Teil
|
||||
"elapsed": round(vergangen, 2),
|
||||
"result": ergebnis,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Filmvorschläge fürs Rad.
|
||||
"""Filmvorschläge für die Ziehung.
|
||||
|
||||
Jede Sitzung darf einen Film vorschlagen. Die Sitzung erkennt ein Cookie —
|
||||
ohne Anmeldung geht es nicht genauer, und für einen Filmabend im Freundeskreis
|
||||
@@ -37,7 +37,19 @@ COOKIE = "filmabend_sid"
|
||||
# So lange läuft die Animation im Browser. Der Server merkt sich das
|
||||
# Ergebnis mit, damit eine Seite, die mitten im Dreh geladen wird, es
|
||||
# trotzdem bekommt.
|
||||
DREH_DAUER = 4.2
|
||||
DREH_DAUER = 11.2
|
||||
|
||||
# Die Ziehung läuft wie das Öffnen einer Lootbox: ein Streifen aus
|
||||
# Postern rast vorbei und bremst auf dem Gewinner aus. Der Streifen ist
|
||||
# so lang, und an dieser Stelle steht der Treffer.
|
||||
STREIFEN_LAENGE = 64
|
||||
STREIFEN_ZIEL = 56
|
||||
|
||||
# Manchmal bricht nach dem Halt die Halterung: die Bahn rutscht ein paar
|
||||
# Poster zurück, und ein anderer gewinnt. So lange dauert das im Browser
|
||||
# zusätzlich (Ruhe plus Rückfahrt — die Werte stehen auch in WheelTab.vue).
|
||||
BRUCH_DAUER = 3.7
|
||||
BRUCH_ANTEIL = 0.5
|
||||
|
||||
|
||||
def init():
|
||||
@@ -112,11 +124,19 @@ def ersetzen(session_id, movie, name=None):
|
||||
return anlegen(session_id, movie, name)
|
||||
|
||||
|
||||
def _versatz():
|
||||
"""Wo genau im Poster die Marke stehen bleibt — nie exakt mittig.
|
||||
Jedes zweite Mal ganz knapp an der Kante: fast der andere."""
|
||||
if random.random() < 0.5:
|
||||
return round(random.choice((-1, 1)) * random.uniform(0.34, 0.46), 3)
|
||||
return round(random.uniform(-0.3, 0.3), 3)
|
||||
|
||||
|
||||
def ziehen():
|
||||
"""Server lost aus, damit alle Seiten dasselbe Ergebnis sehen.
|
||||
|
||||
Der Zielwinkel gehört dazu: sonst dreht jede Seite woanders hin und
|
||||
der Zeiger stünde am Ende auf einem anderen Segment.
|
||||
Der Streifen gehört dazu: sonst zeigt jede Seite andere Poster
|
||||
vorbeirauschen, und der Treffer stünde am Ende woanders.
|
||||
"""
|
||||
eintraege = alle()
|
||||
if not eintraege:
|
||||
@@ -130,26 +150,38 @@ def ziehen():
|
||||
}
|
||||
frisch = [i for i, e in enumerate(eintraege) if e["movie_id"] not in gesehen]
|
||||
treffer = random.choice(frisch) if frisch else random.randrange(len(eintraege))
|
||||
schritt = 360 / len(eintraege)
|
||||
runden = 5 + random.randrange(3)
|
||||
# Der Zeiger steht oben, also muss die Mitte des Zielsegments dorthin.
|
||||
# Ein einzelner Vorschlag ist ein Vollkreis mit Cover — der soll nach
|
||||
# dem Dreh aufrecht stehen, also bei 0° enden statt bei 180°.
|
||||
if len(eintraege) == 1:
|
||||
winkel = runden * 360
|
||||
else:
|
||||
winkel = runden * 360 + (360 - (treffer * schritt + schritt / 2))
|
||||
|
||||
# Blockweise gemischt: jeder Vorschlag kommt gleich oft vorbei
|
||||
streifen = []
|
||||
while len(streifen) < STREIFEN_LAENGE:
|
||||
block = list(range(len(eintraege)))
|
||||
random.shuffle(block)
|
||||
streifen.extend(block)
|
||||
streifen = streifen[:STREIFEN_LAENGE]
|
||||
|
||||
# Wo die Bahn hält — beim Bruch zweimal, und erst der zweite Halt zählt
|
||||
stopps = [{"position": STREIFEN_ZIEL, "versatz": _versatz()}]
|
||||
ziel = STREIFEN_ZIEL
|
||||
if random.random() < BRUCH_ANTEIL:
|
||||
ziel = STREIFEN_ZIEL - random.randint(1, 4)
|
||||
stopps.append({"position": ziel, "versatz": _versatz()})
|
||||
# Der erste Halt zeigt einen anderen — sonst wäre der Bruch egal
|
||||
andere = [i for i in range(len(eintraege)) if i != treffer]
|
||||
streifen[STREIFEN_ZIEL] = random.choice(andere) if andere else treffer
|
||||
streifen[ziel] = treffer
|
||||
|
||||
def karte(e):
|
||||
return {k: v for k, v in e.items() if k not in ("session_id", "user_id")}
|
||||
|
||||
return {
|
||||
"index": treffer,
|
||||
"winkel": winkel,
|
||||
"dauer": DREH_DAUER,
|
||||
"gewinner": {
|
||||
k: v
|
||||
for k, v in eintraege[treffer].items()
|
||||
if k not in ("session_id", "user_id")
|
||||
},
|
||||
"anzahl": len(eintraege),
|
||||
"streifen": streifen,
|
||||
"stopps": stopps,
|
||||
"dauer": DREH_DAUER + (BRUCH_DAUER if len(stopps) > 1 else 0),
|
||||
# Der Streifen zeigt diesen Stand, auch wenn danach jemand einen
|
||||
# Vorschlag dazutut
|
||||
"karten": [karte(e) for e in eintraege],
|
||||
"gewinner": karte(eintraege[treffer]),
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user