from django.db.models import Q from apps.epic.models import Room, RoomInvite # ── Game-wide constants ──────────────────────────────────────────────────── # Reversal probability applied to any card pulled from a stack, anywhere in # the game (PICK SEA initially; future phases — gameplay draws etc. — will # share this single source of truth). Stub for a future per-user profile # override: callers MUST go through stack_reversal_probability(user, room) # rather than referencing the constant directly so the user-config hookup is # a one-line change inside the helper. STACK_REVERSAL_PROBABILITY = 0.25 def stack_reversal_probability(user=None, room=None): """Reversal probability for a draw stack in this user's context. Current behavior: returns the module default for everyone. Plumbing point for a forthcoming per-user setting — when that lands, swap the body to something like `return getattr(user.profile, 'reversal_rate', STACK_REVERSAL_PROBABILITY)` and every call site picks up the per-user value automatically. """ return STACK_REVERSAL_PROBABILITY def _planet_house(degree, cusps): """Return 1-based house number for a planet at ecliptic degree. cusps is the 12-element list from PySwiss where cusps[i] is the start of house i+1. Handles the wrap-around case where a cusp crosses 0°/360°. """ degree = degree % 360 for i in range(12): start = cusps[i] % 360 end = cusps[(i + 1) % 12] % 360 if start < end: if start <= degree < end: return i + 1 else: # wrap-around: e.g. cusp at 350° → next at 10° if degree >= start or degree < end: return i + 1 return 1 def _compute_distinctions(planets, houses): """Return dict {house_number_str: planet_count} for all 12 houses.""" cusps = houses['cusps'] counts = {str(i): 0 for i in range(1, 13)} for planet_data in planets.values(): h = _planet_house(planet_data['degree'], cusps) counts[str(h)] += 1 return counts def rooms_for_user(user): """Return a queryset of rooms the user owns, has a gate slot in, or is invited to.""" return Room.objects.filter( Q(owner=user) | Q(gate_slots__gamer=user) | Q(invites__invitee_email=user.email, invites__status=RoomInvite.PENDING) ).distinct()