Renday commited on
Commit
e9b3222
·
verified ·
1 Parent(s): 52e1299

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +63 -19
app.py CHANGED
@@ -6,6 +6,7 @@ from flask_cors import CORS
6
 
7
  app = Flask(__name__, template_folder="templates")
8
  CORS(app, resources={r"/*": {"origins": "*"}})
 
9
  socketio = SocketIO(app, cors_allowed_origins="*", async_mode='eventlet')
10
 
11
  # --- SPIELLOGIK ---
@@ -14,19 +15,20 @@ RANKS = {'7': 7, '8': 8, '9': 9, '10': 10, 'B': 10, 'D': 10, 'K': 10, 'A': 11}
14
 
15
  class GameState:
16
  def __init__(self):
17
- self.players = {}
18
- self.middle = []
19
- self.deck = []
20
- self.turn_idx = 0
21
- self.active_emails = []
22
- self.current_bet = 50
23
 
24
  def calculate_score(self, hand):
 
25
  if not hand: return 0
26
- # SUMMEN-LOGIK: Alle Kartenwerte werden addiert
27
  return sum(c['val'] for c in hand)
28
 
29
  def broadcast_state(self):
 
30
  for email in self.active_emails:
31
  if email in self.players:
32
  p = self.players[email]
@@ -42,6 +44,8 @@ class GameState:
42
 
43
  game = GameState()
44
 
 
 
45
  @app.route('/')
46
  def index():
47
  return render_template('index.html')
@@ -51,13 +55,19 @@ def login():
51
  if request.method == 'OPTIONS': return jsonify({}), 200
52
  data = request.json
53
  email = data.get('email')
 
54
  if email not in game.players:
55
  game.players[email] = {
56
- 'email': email, 'coins': 1000, 'hand': [],
57
- 'score': 0, 'is_admin': len(game.players) == 0
 
 
 
58
  }
59
  return jsonify({'stats': game.players[email]})
60
 
 
 
61
  @socketio.on('join_game')
62
  def handle_join(data):
63
  email = data.get('email')
@@ -67,58 +77,92 @@ def handle_join(data):
67
 
68
  @socketio.on('start_round')
69
  def start_round(data):
 
70
  game.deck = [{'suit': s, 'rank': r, 'val': v} for s in SUITS for r, v in RANKS.items()]
71
  random.shuffle(game.deck)
 
72
  game.middle = [game.deck.pop() for _ in range(3)]
 
73
  for email in game.active_emails:
74
  if email in game.players:
75
  p = game.players[email]
76
  p['hand'] = [game.deck.pop() for _ in range(3)]
77
  p['score'] = game.calculate_score(p['hand'])
78
  p['coins'] -= int(game.current_bet)
 
79
  game.turn_idx = 0
80
  game.broadcast_state()
81
 
82
  @socketio.on('player_action')
83
  def handle_action(data):
84
  email = data.get('email')
85
- if not game.active_emails or game.active_emails[game.turn_idx] != email: return
 
 
 
86
  p = game.players.get(email)
87
  if not p: return
88
 
89
  if data['type'] == 'swap_one':
90
  h_idx, m_idx = data['h_idx'], data['m_idx']
91
  p['hand'][h_idx], game.middle[m_idx] = game.middle[m_idx], p['hand'][h_idx]
 
92
  elif data['type'] == 'swap_all':
93
  p['hand'], game.middle = game.middle, p['hand']
 
94
  elif data['type'] == 'knock':
 
95
  winner_email = None
96
  max_score = -1
 
97
  for e in game.active_emails:
98
- score = game.calculate_score(game.players[e]['hand'])
 
99
  if score > max_score:
100
  max_score = score
101
  winner_email = e
 
102
  pott = len(game.active_emails) * int(game.current_bet)
103
- game.players[winner_email]['coins'] += pott
104
- emit('game_over', {'winner': winner_email, 'score': max_score, 'pott': pott}, broadcast=True)
 
 
 
 
 
 
105
  return
106
 
 
107
  p['score'] = game.calculate_score(p['hand'])
108
  game.turn_idx = (game.turn_idx + 1) % len(game.active_emails)
109
  game.broadcast_state()
110
 
111
- # NEU: Spiel komplett beenden (Admin Funktion)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  @socketio.on('admin/end_game')
113
  def end_game(data):
 
114
  game.middle = []
115
  game.active_emails = []
116
- for p in game.players.values(): p['hand'] = []; p['score'] = 0
 
 
117
  emit('game_ended_by_admin', broadcast=True)
118
 
119
- @socketio.on('admin/set_bet')
120
- def set_bet(data):
121
- game.current_bet = data.get('bet', 50)
122
-
123
  if __name__ == '__main__':
 
124
  socketio.run(app, host='0.0.0.0', port=7860, debug=False)
 
6
 
7
  app = Flask(__name__, template_folder="templates")
8
  CORS(app, resources={r"/*": {"origins": "*"}})
9
+ # Eventlet ist wichtig für die Echtzeit-Performance auf Servern wie Hugging Face
10
  socketio = SocketIO(app, cors_allowed_origins="*", async_mode='eventlet')
11
 
12
  # --- SPIELLOGIK ---
 
15
 
16
  class GameState:
17
  def __init__(self):
18
+ self.players = {} # Datenbank der Spieler (email -> Daten)
19
+ self.middle = [] # Die 3 Karten in der Tischmitte
20
+ self.deck = [] # Der Kartenstapel
21
+ self.turn_idx = 0 # Index des Spielers, der an der Reihe ist
22
+ self.active_emails = [] # Spieler in der aktuellen Runde
23
+ self.current_bet = 50 # Standard-Einsatz pro Runde
24
 
25
  def calculate_score(self, hand):
26
+ """Berechnet die Summe aller Kartenwerte auf der Hand."""
27
  if not hand: return 0
 
28
  return sum(c['val'] for c in hand)
29
 
30
  def broadcast_state(self):
31
+ """Sendet den aktuellen Tisch-Status an alle verbundenen Clients."""
32
  for email in self.active_emails:
33
  if email in self.players:
34
  p = self.players[email]
 
44
 
45
  game = GameState()
46
 
47
+ # --- HTTP ROUTES ---
48
+
49
  @app.route('/')
50
  def index():
51
  return render_template('index.html')
 
55
  if request.method == 'OPTIONS': return jsonify({}), 200
56
  data = request.json
57
  email = data.get('email')
58
+
59
  if email not in game.players:
60
  game.players[email] = {
61
+ 'email': email,
62
+ 'coins': 1000,
63
+ 'hand': [],
64
+ 'score': 0,
65
+ 'is_admin': len(game.players) == 0 # Der erste Spieler wird Admin
66
  }
67
  return jsonify({'stats': game.players[email]})
68
 
69
+ # --- SOCKET.IO EVENTS ---
70
+
71
  @socketio.on('join_game')
72
  def handle_join(data):
73
  email = data.get('email')
 
77
 
78
  @socketio.on('start_round')
79
  def start_round(data):
80
+ """Startet eine neue Runde: Zieht Einsatz ab und teilt Karten aus."""
81
  game.deck = [{'suit': s, 'rank': r, 'val': v} for s in SUITS for r, v in RANKS.items()]
82
  random.shuffle(game.deck)
83
+
84
  game.middle = [game.deck.pop() for _ in range(3)]
85
+
86
  for email in game.active_emails:
87
  if email in game.players:
88
  p = game.players[email]
89
  p['hand'] = [game.deck.pop() for _ in range(3)]
90
  p['score'] = game.calculate_score(p['hand'])
91
  p['coins'] -= int(game.current_bet)
92
+
93
  game.turn_idx = 0
94
  game.broadcast_state()
95
 
96
  @socketio.on('player_action')
97
  def handle_action(data):
98
  email = data.get('email')
99
+ # Nur handeln, wenn der Spieler an der Reihe ist
100
+ if not game.active_emails or game.active_emails[game.turn_idx] != email:
101
+ return
102
+
103
  p = game.players.get(email)
104
  if not p: return
105
 
106
  if data['type'] == 'swap_one':
107
  h_idx, m_idx = data['h_idx'], data['m_idx']
108
  p['hand'][h_idx], game.middle[m_idx] = game.middle[m_idx], p['hand'][h_idx]
109
+
110
  elif data['type'] == 'swap_all':
111
  p['hand'], game.middle = game.middle, p['hand']
112
+
113
  elif data['type'] == 'knock':
114
+ # Gewinner-Ermittlung beim Klopfen
115
  winner_email = None
116
  max_score = -1
117
+
118
  for e in game.active_emails:
119
+ current_p = game.players[e]
120
+ score = game.calculate_score(current_p['hand'])
121
  if score > max_score:
122
  max_score = score
123
  winner_email = e
124
+
125
  pott = len(game.active_emails) * int(game.current_bet)
126
+ if winner_email:
127
+ game.players[winner_email]['coins'] += pott
128
+
129
+ emit('game_over', {
130
+ 'winner': winner_email,
131
+ 'score': max_score,
132
+ 'pott': pott
133
+ }, broadcast=True)
134
  return
135
 
136
+ # Score aktualisieren und Zug weitergeben
137
  p['score'] = game.calculate_score(p['hand'])
138
  game.turn_idx = (game.turn_idx + 1) % len(game.active_emails)
139
  game.broadcast_state()
140
 
141
+ @socketio.on('admin/reshuffle')
142
+ def reshuffle(data):
143
+ """Mischt das Deck und die Mitte neu, ohne die Spielerliste zu löschen."""
144
+ game.deck = [{'suit': s, 'rank': r, 'val': v} for s in SUITS for r, v in RANKS.items()]
145
+ random.shuffle(game.deck)
146
+ game.middle = [game.deck.pop() for _ in range(3)]
147
+
148
+ for email in game.active_emails:
149
+ if email in game.players:
150
+ game.players[email]['hand'] = []
151
+ game.players[email]['score'] = 0
152
+
153
+ emit('cards_reshuffled', broadcast=True)
154
+ game.broadcast_state()
155
+
156
  @socketio.on('admin/end_game')
157
  def end_game(data):
158
+ """Beendet das Spiel komplett und setzt alles zurück."""
159
  game.middle = []
160
  game.active_emails = []
161
+ for p in game.players.values():
162
+ p['hand'] = []
163
+ p['score'] = 0
164
  emit('game_ended_by_admin', broadcast=True)
165
 
 
 
 
 
166
  if __name__ == '__main__':
167
+ # Port 7860 ist der Standard für Hugging Face Spaces
168
  socketio.run(app, host='0.0.0.0', port=7860, debug=False)