incognitolm commited on
Commit
b9631e3
·
verified ·
1 Parent(s): 665603b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -57
app.py CHANGED
@@ -125,25 +125,39 @@ async def handle_action(request: Request):
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,7 +180,7 @@ async def handle_action(request: Request):
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"]:
@@ -184,7 +198,7 @@ async def handle_action(request: Request):
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
@@ -193,75 +207,105 @@ async def handle_action(request: Request):
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."}
@@ -301,6 +345,7 @@ async def handle_action(request: Request):
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,
@@ -311,28 +356,9 @@ async def handle_action(request: Request):
311
  game["permissions"][player]["gain"] = False
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
330
- return {"success": True, "message": f"Foreign Aid accepted. {challenger_player['name']} gains 2 coins."}
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")
337
  async def join_game(request: Request):
338
  data = await request.json()
 
125
  return {"success": True, "message": f"Coup initiated by {player} targeting {target}."}
126
 
127
  if action == 'assassin':
 
128
  if game["turn"] != player:
129
  return {"success": False, "message": "Not your turn."}
 
130
  game["challenge"] = {
131
  "action": "assassin",
132
+ "challenger": player,
133
+ "target": target,
134
  "challengeType": "assassin",
135
  "status": "pending",
136
+ "phase": "target_decision"
137
  }
138
  return {"success": True, "message": f"Assassin action initiated by {player} targeting {target}. Awaiting target's response."}
139
 
140
+ if action == 'duke':
141
+ # Duke is a money-earning action and only works if the player is allowed to gain.
142
+ player_data = next((p for p in game["players"] if p["name"] == player), None)
143
+ if not game["permissions"].get(player, {}).get("gain", True):
144
+ return {"success": False, "message": "You can only earn money once per turn."}
145
+ # Set gain to false immediately.
146
+ game["permissions"][player]["gain"] = False
147
+ game["challenge"] = {
148
+ "action": "duke",
149
+ "challenger": player,
150
+ "challengeType": "duke",
151
+ "responses": {},
152
+ "status": "pending"
153
+ }
154
+ return {"success": True, "message": f"Duke action initiated by {player}. Waiting for opponents to respond."}
155
+
156
  if action == 'challengeResponse':
157
  if not game.get("challenge"):
158
  return {"success": False, "message": "No challenge pending."}
159
 
160
+ # Handle Steal response.
161
  if game["challenge"]["challengeType"] == "steal":
162
  challenger_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
163
  target_player = next(p for p in game["players"] if p["name"] == game["challenge"]["target"])
 
180
  game["challenge"]["status"] = 'choose'
181
  return {"success": True, "message": f"Challenge successful. {challenger_player['name']} must choose a card to lose.", "challenge": game["challenge"]}
182
 
183
+ # Handle Ambassador response.
184
  elif game["challenge"]["challengeType"] == "ambassador":
185
  if response == 'allow':
186
  if "responses" not in game["challenge"]:
 
198
  ambassador_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
199
  if "Ambassador" in ambassador_player["cards"]:
200
  game["challenge"]["status"] = "choose"
201
+ game["challenge"]["challenger"] = player
202
  game["challenge"]["target"] = ambassador_player["name"]
203
  ambassador_player["cards"] = generate_cards()
204
  game["challenge"] = None
 
207
  game["challenge"]["status"] = "choose"
208
  return {"success": True, "message": "Challenge successful. Ambassador user must choose a card to lose.", "challenge": game["challenge"]}
209
 
210
+ # Handle Assassin/Contessa responses.
211
  elif game["challenge"]["challengeType"] == "assassin":
 
212
  if game["challenge"].get("phase") == "target_decision":
213
  if response == "allow":
 
214
  game["challenge"]["status"] = "choose"
 
215
  game["challenge"]["challenger"] = game["challenge"]["target"]
216
  return {"success": True, "message": f"{game['challenge']['target']} must now choose a card to lose."}
217
  elif response == "challenge":
 
218
  assassin_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
219
  if "Assassin" in assassin_player["cards"]:
 
220
  target_player = next(p for p in game["players"] if p["name"] == game["challenge"]["target"])
221
+ target_player["cards"] = []
222
  game["challenge"] = None
223
  return {"success": True, "message": f"Challenge failed. {target_player['name']} loses both cards."}
224
  else:
 
225
  game["challenge"]["status"] = "choose"
226
  game["challenge"]["challenger"] = assassin_player["name"]
227
  return {"success": True, "message": f"Challenge successful. {assassin_player['name']} must choose a card to lose.", "challenge": game["challenge"]}
228
  elif response == "contessa":
 
229
  game["challenge"]["phase"] = "assassin_contessa"
230
  return {"success": True, "message": f"{game['challenge']['challenger']} must now choose to challenge or accept the Contessa."}
 
231
  elif game["challenge"].get("phase") == "assassin_contessa":
232
  if response == "accept":
 
233
  game["challenge"]["status"] = "choose"
234
  game["challenge"]["challenger"] = game["challenge"]["target"]
235
  return {"success": True, "message": f"{game['challenge']['target']} must now choose a card to lose."}
236
  elif response == "challenge":
 
237
  target_player = next(p for p in game["players"] if p["name"] == game["challenge"]["target"])
238
  if "Contessa" in target_player["cards"]:
 
239
  game["challenge"]["status"] = "choose"
 
 
240
  return {"success": True, "message": f"Contessa challenge successful. {game['challenge']['challenger']} must choose a card to lose.", "challenge": game["challenge"]}
241
  else:
 
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 the response is coming from an opponent (blocking the action)
249
+ if player != game["challenge"]["challenger"]:
250
+ if response == "block":
251
+ # Instead of immediately ending the action, record the blocker and set status to pending block challenge.
252
+ game["challenge"]["blocker"] = player
253
+ game["challenge"]["status"] = "block_pending"
254
+ return {"success": True, "message": f"{player} is attempting to block Foreign Aid. {game['challenge']['challenger']} may now challenge or allow the block.", "challenge": game["challenge"]}
255
+ else:
256
+ game["challenge"]["responses"][player] = response
257
+ total_opponents = len(game["players"]) - 1
258
+ if len(game["challenge"]["responses"]) == total_opponents:
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
262
+ return {"success": True, "message": f"Foreign Aid accepted. {challenger_player['name']} gains 2 coins."}
263
+ else:
264
+ return {"success": True, "message": f"{player} allowed Foreign Aid. Awaiting other responses."}
265
+ # Response from the challenger to a pending block.
266
  else:
267
+ # This branch is for the foreign aid requester responding to a block.
268
+ if response == "allow":
269
+ game["challenge"] = None
270
+ return {"success": True, "message": "Block accepted. Foreign Aid fails."}
271
+ elif response == "challenge":
272
+ blocker = game["challenge"].get("blocker")
273
+ blocker_player = next(p for p in game["players"] if p["name"] == blocker)
274
+ if "Duke" in blocker_player["cards"]:
275
+ game["challenge"]["status"] = "choose_on_challenger"
276
+ return {"success": True, "message": f"Challenge failed. {game['challenge']['challenger']} must choose a card to lose.", "challenge": game["challenge"]}
277
+ else:
278
+ game["challenge"]["status"] = "choose_on_blocker"
279
+ return {"success": True, "message": f"Challenge successful. {blocker} must choose a card to lose.", "challenge": game["challenge"]}
280
+
281
+ # Handle Duke responses.
282
+ elif game["challenge"]["challengeType"] == "duke":
283
+ if player == game["challenge"]["challenger"]:
284
+ # The player who initiated duke doesn't respond here.
285
+ return {"success": False, "message": "Initiator cannot respond to their own Duke action."}
286
+ if response == "allow":
287
+ if "responses" not in game["challenge"]:
288
+ game["challenge"]["responses"] = {}
289
+ game["challenge"]["responses"][player] = "allow"
290
  total_opponents = len(game["players"]) - 1
291
  if len(game["challenge"]["responses"]) == total_opponents:
292
+ acting_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
293
+ acting_player["coins"] += 3
294
  game["challenge"] = None
295
+ return {"success": True, "message": f"Duke action accepted. {acting_player['name']} gains 3 coins."}
296
  else:
297
+ return {"success": True, "message": f"{player} allowed the Duke action. Awaiting other responses."}
298
+ elif response == "challenge":
299
+ acting_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
300
+ if "Duke" in acting_player["cards"]:
301
+ game["challenge"]["status"] = "choose"
302
+ game["challenge"]["challenger"] = player
303
+ game["challenge"]["target"] = acting_player["name"]
304
+ return {"success": True, "message": f"Challenge failed. {player} must choose a card to lose.", "challenge": game["challenge"]}
305
+ else:
306
+ game["challenge"]["status"] = "choose"
307
+ return {"success": True, "message": f"Challenge successful. {acting_player['name']} must choose a card to lose.", "challenge": game["challenge"]}
308
+
309
  if action == 'ambassador':
310
  if game["turn"] != player:
311
  return {"success": False, "message": "Not your turn."}
 
345
  return {"success": False, "message": "Not your turn."}
346
  if not game["permissions"].get(player, {}).get("gain", True):
347
  return {"success": False, "message": "You can only earn money once per turn."}
348
+ # Initiate Foreign Aid but allow opponents to respond (block or allow).
349
  game["challenge"] = {
350
  "action": "foreignAid",
351
  "challenger": player,
 
356
  game["permissions"][player]["gain"] = False
357
  return {"success": True, "message": f"Foreign Aid initiated by {player}. Waiting for opponents to respond."}
358
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
359
  return {"success": True, "message": f"Action '{action}' processed for player {player}."}
360
 
361
+
362
  @app.post("/api/joinGame")
363
  async def join_game(request: Request):
364
  data = await request.json()