Spiel31 / app.py
Renday's picture
Update app.py
892b756 verified
import random
import os
from flask import Flask, request, jsonify, render_template
from flask_socketio import SocketIO, emit
from flask_cors import CORS
app = Flask(__name__, template_folder="templates")
CORS(app, resources={r"/*": {"origins": "*"}})
socketio = SocketIO(app, cors_allowed_origins="*", async_mode='eventlet')
# --- KONFIGURATION ---
SUITS = ['Herz', 'Karo', 'Pik', 'Kreuz']
RANKS = {'7': 7, '8': 8, '9': 9, '10': 10, 'B': 10, 'D': 10, 'K': 10, 'A': 11}
class GameState:
def __init__(self):
self.players = {}
self.active_emails = []
self.middle = []
self.deck = []
self.turn_idx = 0
self.current_bet = 50
def calculate_score(self, hand):
if not hand or len(hand) < 3: return 0
r = [c['rank'] for c in hand]
if r[0] == r[1] == r[2]: return 30.5
sums = {'Herz': 0, 'Karo': 0, 'Pik': 0, 'Kreuz': 0}
for c in hand: sums[c['suit']] += c['val']
return max(sums.values())
def broadcast_state(self):
for email in self.active_emails:
if email in self.players:
self.players[email]['score'] = self.calculate_score(self.players[email].get('hand', []))
state = {
'players': [self.players[e] for e in self.active_emails if e in self.players],
'middle': self.middle,
'turn_idx': self.turn_idx,
'current_bet': self.current_bet,
'pott': len(self.active_emails) * int(self.current_bet)
}
emit('update_table', state, broadcast=True)
game = GameState()
@app.route('/')
def index(): return render_template('index.html')
@app.route('/login', methods=['POST'])
def login():
data = request.json
email = data.get('email')
if email not in game.players:
game.players[email] = {
'email': email, 'coins': 1000, 'hand': [], 'score': 0,
'is_admin': len(game.players) == 0
}
return jsonify({'stats': game.players[email]})
@socketio.on('join_game')
def handle_join(data):
email = data.get('email')
if email and email not in game.active_emails:
game.active_emails.append(email)
game.broadcast_state()
@socketio.on('start_round')
def start_round(data):
email = data.get('email')
# Nur der Admin kann die Runde starten und den Einsatz einziehen
if email in game.players and game.players[email].get('is_admin'):
game.deck = [{'suit': s, 'rank': r, 'val': v} for s in SUITS for r, v in RANKS.items()]
random.shuffle(game.deck)
game.middle = [game.deck.pop() for _ in range(3)]
for e in game.active_emails:
p = game.players[e]
if p['coins'] >= game.current_bet:
p['hand'] = [game.deck.pop() for _ in range(3)]
p['coins'] -= int(game.current_bet)
game.turn_idx = 0
game.broadcast_state()
@socketio.on('player_action')
def handle_action(data):
email = data.get('email')
if not game.active_emails or game.active_emails[game.turn_idx] != email: return
p = game.players.get(email)
if data['type'] == 'swap_one':
p['hand'][data['h_idx']], game.middle[data['m_idx']] = game.middle[data['m_idx']], p['hand'][data['h_idx']]
elif data['type'] == 'swap_all':
p['hand'], game.middle = game.middle, p['hand']
elif data['type'] == 'knock':
scores = {e: game.calculate_score(game.players[e]['hand']) for e in game.active_emails}
max_s = max(scores.values())
winners = [e for e, s in scores.items() if s == max_s]
pott = len(game.active_emails) * int(game.current_bet)
for w in winners: game.players[w]['coins'] += pott // len(winners)
emit('game_over', {'winner': ", ".join(winners), 'score': max_s, 'pott': pott}, broadcast=True)
return
game.turn_idx = (game.turn_idx + 1) % len(game.active_emails)
game.broadcast_state()
# --- ADMIN SPEZIAL FUNKTIONEN ---
@socketio.on('admin/reshuffle')
def admin_reshuffle(data):
email = data.get('email')
if email in game.players and game.players[email].get('is_admin'):
game.deck = [{'suit': s, 'rank': r, 'val': v} for s in SUITS for r, v in RANKS.items()]
random.shuffle(game.deck)
# Neue Karten für die Mitte
game.middle = [game.deck.pop() for _ in range(3)]
# Neue Karten für alle aktiven Spieler (ohne Bezahlung)
for e in game.active_emails:
if e in game.players:
game.players[e]['hand'] = [game.deck.pop() for _ in range(3)]
emit('cards_reshuffled', broadcast=True)
game.broadcast_state()
@socketio.on('admin/end_game')
def admin_end_game(data):
email = data.get('email')
if email in game.players and game.players[email].get('is_admin'):
# Signal an alle: Spiel vorbei, bitte neu laden
emit('game_ended_by_admin', broadcast=True)
# Server-Seitig Daten aufräumen
game.active_emails = []
game.middle = []
@socketio.on('admin/update_bet')
def update_bet(data):
email = data.get('email')
if email in game.players and game.players[email].get('is_admin'):
game.current_bet = int(data.get('bet', 50))
emit('bet_updated', {'new_bet': game.current_bet}, broadcast=True)
game.broadcast_state()
if __name__ == '__main__':
socketio.run(app, host='0.0.0.0', port=7860)