incognitolm commited on
Commit
04a03f2
·
verified ·
1 Parent(s): 598cd1b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +89 -22
app.py CHANGED
@@ -124,11 +124,26 @@ async def handle_action(request: Request):
124
  }
125
  return {"success": True, "message": f"Coup initiated by {player} targeting {target}."}
126
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  if action == 'challengeResponse':
128
  if not game.get("challenge"):
129
  return {"success": False, "message": "No challenge pending."}
130
 
131
- # Handle steal challengeResponse as before.
132
  if game["challenge"]["challengeType"] == "steal":
133
  challenger_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
134
  target_player = next(p for p in game["players"] if p["name"] == game["challenge"]["target"])
@@ -151,18 +166,15 @@ async def handle_action(request: Request):
151
  game["challenge"]["status"] = 'choose'
152
  return {"success": True, "message": f"Challenge successful. {challenger_player['name']} must choose a card to lose.", "challenge": game["challenge"]}
153
 
154
- # New: Handle Ambassador challenge/allow responses.
155
  elif game["challenge"]["challengeType"] == "ambassador":
156
- # Opponents respond with allow or challenge.
157
  if response == 'allow':
158
  if "responses" not in game["challenge"]:
159
  game["challenge"]["responses"] = {}
160
  game["challenge"]["responses"][player] = 'allow'
161
  total_opponents = len(game["players"]) - 1
162
  if len(game["challenge"]["responses"]) == total_opponents:
163
- # All opponents allowed; perform the swap.
164
  ambassador_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
165
- # Swap cards with the deck:
166
  ambassador_player["cards"] = generate_cards()
167
  game["challenge"] = None
168
  return {"success": True, "message": f"Ambassador action accepted. {ambassador_player['name']} swaps cards with the deck."}
@@ -170,22 +182,89 @@ async def handle_action(request: Request):
170
  return {"success": True, "message": f"{player} allowed the Ambassador action. Awaiting other responses."}
171
  elif response == 'challenge':
172
  ambassador_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
173
- # If the acting player really had Ambassador, then the challenger loses a card.
174
  if "Ambassador" in ambassador_player["cards"]:
175
  game["challenge"]["status"] = "choose"
176
- game["challenge"]["challenger"] = player # The challenging opponent now must choose a card to lose.
177
  game["challenge"]["target"] = ambassador_player["name"]
178
  ambassador_player["cards"] = generate_cards()
179
  game["challenge"] = None
180
- return {"success": True, "message": f"Challenge failed. Challenger must choose a card to lose. {ambassador_player['name']} swaps cards with the deck."}
181
  else:
182
  game["challenge"]["status"] = "choose"
183
  return {"success": True, "message": "Challenge successful. Ambassador user must choose a card to lose.", "challenge": game["challenge"]}
184
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
  if action == 'ambassador':
186
  if game["turn"] != player:
187
  return {"success": False, "message": "Not your turn."}
188
- # Initiate the ambassador action with a pending challenge.
189
  game["challenge"] = {
190
  "action": "ambassador",
191
  "challenger": player,
@@ -196,7 +275,6 @@ async def handle_action(request: Request):
196
  return {"success": True, "message": f"Ambassador action initiated by {player}. Waiting for opponents to respond."}
197
 
198
  if action == 'choose':
199
- # Pre-existing choose logic to lose a card.
200
  acting_player = next((p for p in game["players"] if p["name"] == game["challenge"]["challenger"]), None)
201
  if acting_player and target in acting_player["cards"]:
202
  acting_player["cards"].remove(target)
@@ -218,14 +296,11 @@ async def handle_action(request: Request):
218
  if not player_found:
219
  raise HTTPException(status_code=404, detail="Player not found in the game.")
220
 
221
- # --- NEW: Foreign Aid ---
222
  if action == 'foreignAid':
223
- # Ensure it is the player's turn and they haven't already performed a gain action.
224
  if game["turn"] != player:
225
  return {"success": False, "message": "Not your turn."}
226
  if not game["permissions"].get(player, {}).get("gain", True):
227
  return {"success": False, "message": "You can only earn money once per turn."}
228
- # Create a pending foreign aid challenge.
229
  game["challenge"] = {
230
  "action": "foreignAid",
231
  "challenger": player,
@@ -237,25 +312,18 @@ async def handle_action(request: Request):
237
  return {"success": True, "message": f"Foreign Aid initiated by {player}. Waiting for opponents to respond."}
238
 
239
  if action == 'foreignAidResponse':
240
- # This branch handles responses from opponents for the foreign aid action.
241
  if not game.get("challenge") or game["challenge"].get("challengeType") != "foreignAid":
242
  return {"success": False, "message": "No foreign aid action pending."}
243
- # Only opponents may respond.
244
  if player == game["challenge"]["challenger"]:
245
  return {"success": False, "message": "Challenger cannot respond to their own action."}
246
- # Record the response.
247
  game["challenge"]["responses"][player] = response
248
- # If any opponent chooses to block, immediately cancel the foreign aid.
249
  if response == "block":
250
  game["challenge"]["status"] = "blocked"
251
- challenger = game["challenge"]["challenger"]
252
  game["challenge"] = None
253
  return {"success": True, "message": f"Foreign Aid blocked by {player}."}
254
  else:
255
- # Check if all opponents have responded (all players except the challenger).
256
  total_opponents = len(game["players"]) - 1
257
  if len(game["challenge"]["responses"]) == total_opponents:
258
- # No opponent blocked; grant the acting player +2 coins.
259
  challenger_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
260
  challenger_player["coins"] += 2
261
  game["challenge"] = None
@@ -263,7 +331,6 @@ async def handle_action(request: Request):
263
  else:
264
  return {"success": True, "message": f"{player} allowed Foreign Aid. Awaiting other responses."}
265
 
266
- # Default response.
267
  return {"success": True, "message": f"Action '{action}' processed for player {player}."}
268
 
269
  @app.post("/api/joinGame")
 
124
  }
125
  return {"success": True, "message": f"Coup initiated by {player} targeting {target}."}
126
 
127
+ if action == 'assassin':
128
+ # Assassin action: must be the player's turn.
129
+ if game["turn"] != player:
130
+ return {"success": False, "message": "Not your turn."}
131
+ # Create an assassin challenge waiting for the target's decision.
132
+ game["challenge"] = {
133
+ "action": "assassin",
134
+ "challenger": player, # the assassin
135
+ "target": target, # the chosen target
136
+ "challengeType": "assassin",
137
+ "status": "pending",
138
+ "phase": "target_decision" # awaiting target's decision: allow/challenge/contessa
139
+ }
140
+ return {"success": True, "message": f"Assassin action initiated by {player} targeting {target}. Awaiting target's response."}
141
+
142
  if action == 'challengeResponse':
143
  if not game.get("challenge"):
144
  return {"success": False, "message": "No challenge pending."}
145
 
146
+ # --- Handle existing steal response ---
147
  if game["challenge"]["challengeType"] == "steal":
148
  challenger_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
149
  target_player = next(p for p in game["players"] if p["name"] == game["challenge"]["target"])
 
166
  game["challenge"]["status"] = 'choose'
167
  return {"success": True, "message": f"Challenge successful. {challenger_player['name']} must choose a card to lose.", "challenge": game["challenge"]}
168
 
169
+ # --- Handle Ambassador response (existing) ---
170
  elif game["challenge"]["challengeType"] == "ambassador":
 
171
  if response == 'allow':
172
  if "responses" not in game["challenge"]:
173
  game["challenge"]["responses"] = {}
174
  game["challenge"]["responses"][player] = 'allow'
175
  total_opponents = len(game["players"]) - 1
176
  if len(game["challenge"]["responses"]) == total_opponents:
 
177
  ambassador_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
 
178
  ambassador_player["cards"] = generate_cards()
179
  game["challenge"] = None
180
  return {"success": True, "message": f"Ambassador action accepted. {ambassador_player['name']} swaps cards with the deck."}
 
182
  return {"success": True, "message": f"{player} allowed the Ambassador action. Awaiting other responses."}
183
  elif response == 'challenge':
184
  ambassador_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
 
185
  if "Ambassador" in ambassador_player["cards"]:
186
  game["challenge"]["status"] = "choose"
187
+ game["challenge"]["challenger"] = player # challenger loses card
188
  game["challenge"]["target"] = ambassador_player["name"]
189
  ambassador_player["cards"] = generate_cards()
190
  game["challenge"] = None
191
+ return {"success": True, "message": f"Challenge failed. {player} must lose a card, while {ambassador_player['name']} swaps cards with the deck."}
192
  else:
193
  game["challenge"]["status"] = "choose"
194
  return {"success": True, "message": "Challenge successful. Ambassador user must choose a card to lose.", "challenge": game["challenge"]}
195
+
196
+ # --- Handle Assassin/Contessa responses ---
197
+ elif game["challenge"]["challengeType"] == "assassin":
198
+ # Phase 1: target's decision on assassination
199
+ if game["challenge"].get("phase") == "target_decision":
200
+ if response == "allow":
201
+ # Target accepts assassination: must lose one card.
202
+ game["challenge"]["status"] = "choose"
203
+ # Set the losing player to the target.
204
+ game["challenge"]["challenger"] = game["challenge"]["target"]
205
+ return {"success": True, "message": f"{game['challenge']['target']} must now choose a card to lose."}
206
+ elif response == "challenge":
207
+ # Target challenges the assassin's claim.
208
+ assassin_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
209
+ if "Assassin" in assassin_player["cards"]:
210
+ # Assassin is truthful: target loses both cards.
211
+ target_player = next(p for p in game["players"] if p["name"] == game["challenge"]["target"])
212
+ target_player["cards"] = [] # remove all cards (eliminated)
213
+ game["challenge"] = None
214
+ return {"success": True, "message": f"Challenge failed. {target_player['name']} loses both cards."}
215
+ else:
216
+ # Assassin is lying: assassin must lose one card.
217
+ game["challenge"]["status"] = "choose"
218
+ game["challenge"]["challenger"] = assassin_player["name"]
219
+ return {"success": True, "message": f"Challenge successful. {assassin_player['name']} must choose a card to lose.", "challenge": game["challenge"]}
220
+ elif response == "contessa":
221
+ # Target opts to block with Contessa. Shift phase.
222
+ game["challenge"]["phase"] = "assassin_contessa"
223
+ return {"success": True, "message": f"{game['challenge']['challenger']} must now choose to challenge or accept the Contessa."}
224
+ # Phase 2: assassin responding to contessa claim.
225
+ elif game["challenge"].get("phase") == "assassin_contessa":
226
+ if response == "accept":
227
+ # Assassin accepts contessa block: target loses one card.
228
+ game["challenge"]["status"] = "choose"
229
+ game["challenge"]["challenger"] = game["challenge"]["target"]
230
+ return {"success": True, "message": f"{game['challenge']['target']} must now choose a card to lose."}
231
+ elif response == "challenge":
232
+ # Assassin challenges contessa.
233
+ target_player = next(p for p in game["players"] if p["name"] == game["challenge"]["target"])
234
+ if "Contessa" in target_player["cards"]:
235
+ # Contessa is truthful: assassin loses one card.
236
+ game["challenge"]["status"] = "choose"
237
+ # Losing player is the assassin.
238
+ game["challenge"]["challenger"] = game["challenge"]["challenger"]
239
+ return {"success": True, "message": f"Contessa challenge successful. {game['challenge']['challenger']} must choose a card to lose.", "challenge": game["challenge"]}
240
+ else:
241
+ # Contessa is bluffing: target loses both cards.
242
+ target_player["cards"] = []
243
+ game["challenge"] = None
244
+ return {"success": True, "message": f"Contessa challenge failed. {target_player['name']} loses both cards."}
245
+
246
+ # --- Handle Foreign Aid responses ---
247
+ elif game["challenge"]["challengeType"] == "foreignAid":
248
+ if player == game["challenge"]["challenger"]:
249
+ return {"success": False, "message": "Challenger cannot respond to their own action."}
250
+ game["challenge"]["responses"][player] = response
251
+ if response == "block":
252
+ game["challenge"]["status"] = "blocked"
253
+ game["challenge"] = None
254
+ return {"success": True, "message": f"Foreign Aid blocked by {player}."}
255
+ else:
256
+ total_opponents = len(game["players"]) - 1
257
+ if len(game["challenge"]["responses"]) == total_opponents:
258
+ challenger_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
259
+ challenger_player["coins"] += 2
260
+ game["challenge"] = None
261
+ return {"success": True, "message": f"Foreign Aid accepted. {challenger_player['name']} gains 2 coins."}
262
+ else:
263
+ return {"success": True, "message": f"{player} allowed Foreign Aid. Awaiting other responses."}
264
+
265
  if action == 'ambassador':
266
  if game["turn"] != player:
267
  return {"success": False, "message": "Not your turn."}
 
268
  game["challenge"] = {
269
  "action": "ambassador",
270
  "challenger": player,
 
275
  return {"success": True, "message": f"Ambassador action initiated by {player}. Waiting for opponents to respond."}
276
 
277
  if action == 'choose':
 
278
  acting_player = next((p for p in game["players"] if p["name"] == game["challenge"]["challenger"]), None)
279
  if acting_player and target in acting_player["cards"]:
280
  acting_player["cards"].remove(target)
 
296
  if not player_found:
297
  raise HTTPException(status_code=404, detail="Player not found in the game.")
298
 
 
299
  if action == 'foreignAid':
 
300
  if game["turn"] != player:
301
  return {"success": False, "message": "Not your turn."}
302
  if not game["permissions"].get(player, {}).get("gain", True):
303
  return {"success": False, "message": "You can only earn money once per turn."}
 
304
  game["challenge"] = {
305
  "action": "foreignAid",
306
  "challenger": player,
 
312
  return {"success": True, "message": f"Foreign Aid initiated by {player}. Waiting for opponents to respond."}
313
 
314
  if action == 'foreignAidResponse':
 
315
  if not game.get("challenge") or game["challenge"].get("challengeType") != "foreignAid":
316
  return {"success": False, "message": "No foreign aid action pending."}
 
317
  if player == game["challenge"]["challenger"]:
318
  return {"success": False, "message": "Challenger cannot respond to their own action."}
 
319
  game["challenge"]["responses"][player] = response
 
320
  if response == "block":
321
  game["challenge"]["status"] = "blocked"
 
322
  game["challenge"] = None
323
  return {"success": True, "message": f"Foreign Aid blocked by {player}."}
324
  else:
 
325
  total_opponents = len(game["players"]) - 1
326
  if len(game["challenge"]["responses"]) == total_opponents:
 
327
  challenger_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
328
  challenger_player["coins"] += 2
329
  game["challenge"] = None
 
331
  else:
332
  return {"success": True, "message": f"{player} allowed Foreign Aid. Awaiting other responses."}
333
 
 
334
  return {"success": True, "message": f"Action '{action}' processed for player {player}."}
335
 
336
  @app.post("/api/joinGame")