File size: 25,119 Bytes
26d2e1c
0369546
26d2e1c
84f3b08
8981023
26d2e1c
 
 
0369546
 
 
0b0e156
0369546
 
 
 
 
26d2e1c
 
5e85d1f
26d2e1c
 
 
 
5706cbf
26d2e1c
 
5706cbf
 
 
 
 
 
 
 
 
 
 
 
26d2e1c
5706cbf
26d2e1c
e3995f9
26d2e1c
 
 
 
 
 
 
 
e0a05cd
bf6e4de
26d2e1c
 
 
 
7e51fa9
 
0369546
7e51fa9
3404dbd
8987ab0
0369546
5e85d1f
7e11006
26d2e1c
 
 
50d5022
26d2e1c
 
0c6b470
 
 
 
 
 
 
 
 
 
 
 
14df850
0c6b470
 
c3f1705
f1beee6
c3f1705
 
afe2c7a
ca4b51b
14df850
afe2c7a
0c6b470
15292c8
 
57c27f4
 
 
 
 
 
 
 
 
216ed9a
 
f8fe34e
15292c8
 
 
 
 
 
 
 
 
 
d7ac04f
5512c41
15292c8
 
 
38cfb33
15292c8
 
15b9f04
 
 
 
9b6b96a
15b9f04
 
 
6913be1
 
15b9f04
 
 
 
0c6b470
04a03f2
cc69406
 
 
04a03f2
 
9ec5d56
 
 
 
 
 
 
 
cc69406
04a03f2
 
b9631e3
15292c8
 
b9631e3
 
 
 
 
 
 
 
 
 
 
 
 
0c6b470
 
 
c61c7aa
b9631e3
c61c7aa
14df850
c61c7aa
 
0c6b470
 
14df850
6ecb163
c61c7aa
14df850
c61c7aa
14df850
c61c7aa
 
14df850
6ecb163
c61c7aa
 
14df850
 
c61c7aa
 
14df850
c61c7aa
b9631e3
665603b
 
c61c7aa
 
665603b
c61c7aa
 
665603b
ff5dfe0
c61c7aa
5acba4d
5c0e13e
5acba4d
665603b
 
 
5c0e13e
b9631e3
665603b
ff5dfe0
401116f
665603b
5c0e13e
 
665603b
04a03f2
b9631e3
04a03f2
 
 
 
 
 
 
 
 
 
b9631e3
04a03f2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
665603b
b9631e3
665603b
e2c5416
b9631e3
 
 
 
 
 
 
 
 
 
 
 
e2c5416
b9631e3
 
 
 
 
665603b
b9631e3
 
 
 
 
 
 
 
be202d4
b9631e3
 
52432be
e2c5416
be202d4
 
b9631e3
 
 
 
d5cda55
b9631e3
 
 
 
 
 
 
04a03f2
 
b9631e3
 
3ef16ad
04a03f2
b9631e3
04a03f2
b9631e3
 
 
 
 
 
 
2f38db0
3ef16ad
b9631e3
 
 
 
 
665603b
 
 
 
 
 
 
 
 
 
5acba4d
665603b
 
 
 
 
 
 
 
 
 
e0a05cd
15292c8
 
14df850
5b93212
 
14df850
e3995f9
1a50057
3d389e7
57c27f4
a1b1dac
14df850
5b93212
8987ab0
f8fe34e
 
 
 
c61c7aa
b9631e3
f8fe34e
 
 
 
 
 
 
 
 
665603b
0c6b470
b9631e3
26d2e1c
 
 
 
 
 
 
 
c919ba0
26d2e1c
8981023
 
c919ba0
8981023
266e69a
dd21b8f
 
d98aec5
c919ba0
e3995f9
d98aec5
 
e3995f9
c919ba0
26d2e1c
 
 
 
 
 
 
 
 
 
31bf844
 
 
 
26d2e1c
 
e3995f9
ff5dfe0
e3995f9
 
26d2e1c
 
31bf844
26d2e1c
 
8981023
 
 
 
 
c173974
8981023
 
 
 
 
 
 
 
5dda4a8
8981023
 
ff5dfe0
26d2e1c
8987ab0
ff5dfe0
 
 
 
8987ab0
 
 
8c2f58b
 
c3f1705
 
 
 
 
 
 
 
 
 
 
 
 
 
8c2f58b
 
 
 
 
 
 
 
 
5928a49
 
 
 
 
 
 
8981023
5928a49
8981023
5928a49
 
8981023
 
5928a49
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
from fastapi import FastAPI, Request, HTTPException
from fastapi.middleware.cors import CORSMiddleware
import uvicorn
import random
import logging

app = FastAPI()

# Enable CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

games = {}

@app.post("/api/createGame")
async def create_game(request: Request):
    data = await request.json()
    pin = data.get("pin")
    player_name = data.get("playerName")
    notPlaying = data.get("notPlaying")

    if not pin or not player_name:
        if not notPlaying:
            raise HTTPException(status_code=400, detail="PIN and player name are required.")
        else:
            games[pin] = {
            "pin": pin,
            "players": None,
            "gameStarted": False,
            "turn": player_name,
            "permissions": {player_name: {"steal": True, "gain": True}}
            }
            return {"success": True, "message": "Empty game created."}
            
    if pin in games:
        return {"success": False, "message": "Game already exists."}

    # Initialize permissions as a dictionary with proper keys.
    games[pin] = {
        "pin": pin,
        "players": [player_name],
        "gameStarted": False,
        "turn": player_name,
        "currentAction": None,
        "currentChallenge": None,
        "pendingCardLoss": None,
        "votes": [],
        "permissions": {player_name: {"steal": True, "gain": True}}
    }

    return {"success": True, "message": "Game created successfully!"}

@app.get("/api/test")
async def test():
    return {"success": True}

@app.get("/api/getGames")
async def getGames():
    return {"success": True, "data": games}

@app.get("/api/getGameStatus")
async def get_game_status(pin: str):
    game = games.get(pin)
    if not game:
        return {"success": False, "message": "Game was lost or does not exist. Please create a new game."}
    return {"success": True, "game": game}

@app.post("/api/handleAction")
async def handle_action(request: Request):
    data = await request.json()
    pin = data.get("pin")
    player = data.get("player")
    action = data.get("action")
    target = data.get("target")
    response = data.get("response")
    challenge = data.get("challenge")

    if pin not in games:
        raise HTTPException(status_code=404, detail="Game not found.")

    game = games[pin]

    # If a challenge is pending, only allow challengeResponse (or getStatus) actions.
    if game.get("challenge") and action not in ['challengeResponse', 'getStatus', 'choose']:
        return {"success": False, "message": "A challenge is pending, only challenge responses are allowed."}

    if action == 'getStatus':
        check_game_status(game)
        return {"success": True, "challenge": game.get("challenge", None)}

    if action == 'steal':
        if game["turn"] != player:
            return {"success": False, "message": "Not your turn."}
        if game["permissions"].get(player, {}).get("steal", True):
            game["challenge"] = {
                "action": 'steal',
                "challenger": player,
                "target": target,
                "challengeType": 'steal',
                "status": 'pending'
            }
            return {"success": True, "message": f"Steal initiated by {player} targeting {target}. Awaiting response from {target}."}
        else:
            return {"success": False, "message": "You can only steal once per turn."}

    if action == 'endTurn':
        if game["turn"] != player:
            return {"success": False, "message": "Not your turn."}
        players_list = game.get("players", [])
        # Find the index of the current player in the players list
        current_index = next((i for i, p in enumerate(players_list) if p["name"] == player), None)
        if current_index is None:
            return {"success": False, "message": "Player not found in game."}
        next_index = (current_index + 1) % len(players_list)
        game["turn"] = players_list[next_index]["name"]
        game["permissions"][player]["gain"] = True
        game["permissions"][player]["steal"] = True
        return {"success": True, "message": f"Turn ended. Next turn: {game['turn']}"}

    
    if action == 'coup':
        if game["turn"] != player:
            return {"success": False, "message": "Not your turn."}
        player_data = next((p for p in game["players"] if p["name"] == player), None)
        if not player_data:
            return {"success": False, "message": "Player not found."}
        if player_data["coins"] < 7:
            return {"success": False, "message": "You don't have enough coins to coup another player."}
        player_data["coins"] -= 7
        game["challenge"] = {
            "action": 'coup',
            "challenger": target,
            "target": player,
            "challengeType": 'coup',
            "status": 'choose'
        }
        return {"success": True, "message": f"Coup initiated by {player} targeting {target}."}

    if action == 'assassin':
        player_data = next((p for p in game["players"] if p["name"] == player), None)
        if player_data["coins"] < 3:
            return {"success": False, "message": "You don't have enough coins to assassinate another player."}
        if game["turn"] != player:
            return {"success": False, "message": "Not your turn."}
        game["challenge"] = {
            "action": "assassin",
            "challenger": player,
            "target": target,
            "challengeType": "assassin",
            "status": "pending",
            "phase": "target_decision"
        }
        player_data["coins"] -= 3
        return {"success": True, "message": f"Assassin action initiated by {player} targeting {target}. Awaiting target's response."}

    if action == 'duke':
        if game["turn"] != player:
            return {"success": False, "message": "Not your turn."}
        # Duke is a money-earning action and only works if the player is allowed to gain.
        player_data = next((p for p in game["players"] if p["name"] == player), None)
        if not game["permissions"].get(player, {}).get("gain", True):
            return {"success": False, "message": "You can only earn money once per turn."}
        game["challenge"] = {
            "action": "duke",
            "challenger": player,
            "challengeType": "duke",
            "responses": {},
            "status": "pending"
        }
        return {"success": True, "message": f"Duke action initiated by {player}. Waiting for opponents to respond."}

    if action == 'challengeResponse':
        if not game.get("challenge"):
            return {"success": False, "message": "No challenge pending."}

        # Handle Steal response.
        if game["challenge"]["challengeType"] == "steal":
            challenger_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
            target_player = next(p for p in game["players"] if p["name"] == game["challenge"]["target"])
            if response == 'accept':
                coins_to_steal = min(target_player["coins"], 2)
                target_player["coins"] -= coins_to_steal
                challenger_player["coins"] += coins_to_steal
                game["permissions"][challenger_player["name"]]["steal"] = False
                game["challenge"] = None
                return {"success": True, "message": f"Steal accepted. {coins_to_steal} coins transferred from {target_player['name']} to {challenger_player['name']}."}
            elif response == 'challenge':
                if "Captain" in challenger_player["cards"]:
                    coins_to_steal = min(target_player["coins"], 2)
                    target_player["coins"] -= coins_to_steal
                    challenger_player["coins"] += coins_to_steal
                    game["permissions"][challenger_player["name"]]["steal"] = False
                    game["challenge"]["status"] = 'choose'
                    game["challenge"]["challenger"] = target_player['name']
                    game["challenge"]["target"] = challenger_player['name']
                    return {"success": True, "message": f"Challenge failed. {target_player['name']} loses {coins_to_steal} coins to {challenger_player['name']}."}
                else:
                    game["challenge"]["status"] = 'choose'
                    return {"success": True, "message": f"Challenge successful. {challenger_player['name']} must choose a card to lose.", "challenge": game["challenge"]}

        # Handle Ambassador response.
        elif game["challenge"]["challengeType"] == "ambassador":
            if response == 'allow':
                if "responses" not in game["challenge"]:
                    game["challenge"]["responses"] = {}
                game["challenge"]["responses"][player] = 'allow'
                total_opponents = len(game["players"]) - 1
                if len(game["challenge"]["responses"]) == total_opponents:
                    ambassador_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
                    ambassador_player["cards"] = generate_cards(len(ambassador_player["cards"]))
                    game["challenge"] = None
                    return {"success": True, "message": f"Card swap accepted. {ambassador_player['name']} swaps cards with the deck."}
                else:
                    return {"success": True, "message": f"{player} allowed the card swap. Awaiting other responses."}
            elif response == 'challenge':
                ambassador_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
                if "Ambassador" in ambassador_player["cards"]:
                    game["challenge"]["status"] = "choose"
                    game["challenge"]["challenger"] = player
                    game["challenge"]["target"] = ambassador_player["name"]
                    ambassador_player["cards"] = generate_cards(len(ambassador_player["cards"]))
                    game["challenge"] = None
                    return {"success": True, "message": f"Challenge failed. {player} must lose a card, while {ambassador_player['name']} swaps cards with the deck."}
                else:
                    game["challenge"]["status"] = "choose"
                    return {"success": True, "message": "Challenge successful. Ambassador user must choose a card to lose.", "challenge": game["challenge"]}

        # Handle Assassin/Contessa responses.
        elif game["challenge"]["challengeType"] == "assassin":
            if game["challenge"].get("phase") == "target_decision":
                if response == "allow":
                    game["challenge"]["status"] = "choose"
                    game["challenge"]["challenger"] = game["challenge"]["target"]
                    return {"success": True, "message": f"{game['challenge']['target']} must now choose a card to lose."}
                elif response == "challenge":
                    assassin_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
                    if "Assassin" in assassin_player["cards"]:
                        target_player = next(p for p in game["players"] if p["name"] == game["challenge"]["target"])
                        target_player["cards"] = []
                        game["challenge"] = None
                        return {"success": True, "message": f"Challenge failed. {target_player['name']} loses both cards."}
                    else:
                        game["challenge"]["status"] = "choose"
                        game["challenge"]["challenger"] = assassin_player["name"]
                        return {"success": True, "message": f"Challenge successful. {assassin_player['name']} must choose a card to lose.", "challenge": game["challenge"]}
                elif response == "contessa":
                    game["challenge"]["phase"] = "assassin_contessa"
                    return {"success": True, "message": f"{game['challenge']['challenger']} must now choose to challenge or accept the Contessa."}
            elif game["challenge"].get("phase") == "assassin_contessa":
                if response == "accept":
                    game["challenge"]["status"] = "choose"
                    game["challenge"]["challenger"] = game["challenge"]["target"]
                    return {"success": True, "message": f"{game['challenge']['target']} must now choose a card to lose."}
                elif response == "challenge":
                    target_player = next(p for p in game["players"] if p["name"] == game["challenge"]["target"])
                    if "Contessa" in target_player["cards"]:
                        game["challenge"]["status"] = "choose"
                        return {"success": True, "message": f"Contessa challenge successful. {game['challenge']['challenger']} must choose a card to lose.", "challenge": game["challenge"]}
                    else:
                        target_player["cards"] = []
                        game["challenge"] = None
                        return {"success": True, "message": f"Contessa challenge failed. {target_player['name']} loses both cards."}

        # Handle Foreign Aid responses.
        elif game["challenge"]["challengeType"] == "foreignAid":
            challenger_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
            # If the response is coming from an opponent (blocking the action)
            if player != game["challenge"]["challenger"]:
                if response == "block":
                    # Instead of immediately ending the action, record the blocker and set status to pending block challenge.
                    game["challenge"]["blocker"] = player
                    game["challenge"]["status"] = "block_pending"
                    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"]}
                else:
                    game["challenge"]["responses"][player] = response
                    total_opponents = len(game["players"]) - 1
                    if len(game["challenge"]["responses"]) == total_opponents:
                        challenger_player["coins"] += 2
                        game["permissions"][challenger_player["name"]]["gain"] = False
                        game["challenge"] = None
                        return {"success": True, "message": f"Foreign Aid accepted. {challenger_player['name']} gains 2 coins."}
                    else:
                        return {"success": True, "message": f"{player} allowed Foreign Aid. Awaiting other responses."}
            # Response from the challenger to a pending block.
            else:
                # This branch is for the foreign aid requester responding to a block.
                if response == "allow":
                    game["challenge"] = None
                    return {"success": True, "message": "Block accepted. Foreign Aid fails."}
                elif response == "challenge":
                    blocker = game["challenge"].get("blocker")
                    blocker_player = next(p for p in game["players"] if p["name"] == blocker)
                    if "Duke" in blocker_player["cards"]:
                        game["challenge"]["status"] = "choose"
                        return {"success": True, "message": f"Challenge failed. {game['challenge']['challenger']} must choose a card to lose.", "challenge": game["challenge"]}
                    else:
                        challenger_player["coins"] += 2
                        game["permissions"][challenger_player["name"]]["gain"] = False
                        game["challenge"]["challenger"] = blocker_player["name"]
                        game["challenge"]["status"] = "choose"
                        return {"success": True, "message": f"Challenge successful. {blocker} must choose a card to lose.", "challenge": game["challenge"]}

        # Handle Duke responses.
        elif game["challenge"]["challengeType"] == "duke":
            challenger_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
            if player == game["challenge"]["challenger"]:
                # The player who initiated duke doesn't respond here.
                return {"success": False, "message": "Initiator cannot respond to their own Duke action."}
            if response == "allow":
                if "responses" not in game["challenge"]:
                    game["challenge"]["responses"] = {}
                game["challenge"]["responses"][player] = "allow"
                total_opponents = len(game["players"]) - 1
                if len(game["challenge"]["responses"]) == total_opponents:
                    acting_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
                    acting_player["coins"] += 3
                    game["permissions"][challenger_player["name"]]["gain"] = False
                    game["challenge"] = None
                    return {"success": True, "message": f"Duke action accepted. {acting_player['name']} gains 3 coins."}
                else:
                    return {"success": True, "message": f"{player} allowed the Duke action. Awaiting other responses."}
            elif response == "challenge":
                acting_player = next(p for p in game["players"] if p["name"] == game["challenge"]["challenger"])
                if "Duke" in acting_player["cards"]:
                    game["challenge"]["status"] = "choose"
                    game["challenge"]["challenger"] = player
                    game["challenge"]["target"] = acting_player["name"]
                    acting_player["coins"] += 3
                    game["permissions"][challenger_player["name"]]["gain"] = False
                    return {"success": True, "message": f"Challenge failed. {player} must choose a card to lose.", "challenge": game["challenge"]}
                else:
                    game["challenge"]["status"] = "choose"
                    return {"success": True, "message": f"Challenge successful. {acting_player['name']} must choose a card to lose.", "challenge": game["challenge"]}
        
    if action == 'ambassador':
        if game["turn"] != player:
            return {"success": False, "message": "Not your turn."}
        game["challenge"] = {
            "action": "ambassador",
            "challenger": player,
            "challengeType": "ambassador",
            "status": "pending",
            "responses": {}
        }
        return {"success": True, "message": f"Card swap initiated by {player}. Waiting for opponents to respond."}

    if action == 'choose':
        acting_player = next((p for p in game["players"] if p["name"] == game["challenge"]["challenger"]), None)
        if acting_player and target in acting_player["cards"]:
            acting_player["cards"].remove(target)
            game["challenge"] = None
            return {"success": True, "message": f"{acting_player['name']} loses the {target} card."}
        else:
            return {"success": False, "message": f"Card {target} not found in {acting_player['name']}'s hand."}

    if action == 'income':
        if game["turn"] != player:
            return {"success": False, "message": "Not your turn."}
        player_found = False
        for p in game["players"]:
            if p["name"] == player:
                player_found = True
                if not game["permissions"].get(player, {}).get("gain", True):
                    return {"success": False, "message": "You can only earn money once per turn."}
                p["coins"] += 1
                game["permissions"][player]["gain"] = False
                return {"success": True, "message": f"You now have {p['coins']} coins."}
        if not player_found:
            raise HTTPException(status_code=404, detail="Player not found in the game.")

    if action == 'foreignAid':
        if game["turn"] != player:
            return {"success": False, "message": "Not your turn."}
        if not game["permissions"].get(player, {}).get("gain", True):
            return {"success": False, "message": "You can only earn money once per turn."}
        # Initiate Foreign Aid but allow opponents to respond (block or allow).
        game["challenge"] = {
            "action": "foreignAid",
            "challenger": player,
            "challengeType": "foreignAid",
            "responses": {},
            "status": "pending"
        }
        return {"success": True, "message": f"Foreign Aid initiated by {player}. Waiting for opponents to respond."}

    return {"success": True, "message": f"Action '{action}' processed for player {player}."}


@app.post("/api/joinGame")
async def join_game(request: Request):
    data = await request.json()
    pin = data.get("pin")
    player_name = data.get("playerName")

    game = games.get(pin)
    if not game:
        return {"success": False, "message": "Game not found."}

    # Prevent joining if game has already started.
    if game.get("gameStarted"):
        return {"success": False, "message": "Cannot join a game that has started."}

    formatted_name = player_name

    existing_names = [name.lower() for name in game["permissions"].keys()]
    if formatted_name.lower() in existing_names:
        return {"success": False, "message": "Player name taken."}

    game["players"].append(formatted_name)
    game["permissions"][formatted_name] = {"steal": True, "gain": True}
    
    return {"success": True, "message": "You joined successfully!"}

@app.put("/api/startGame")
async def start_game(request: Request):
    data = await request.json()
    pin = data.get("pin")

    game = games.get(pin)
    if not game:
        raise HTTPException(status_code=404, detail="Game not found.")

    if game["gameStarted"]:
        raise HTTPException(status_code=400, detail="Game has already started.")

    if len(game["players"]) == 0:
        raise HTTPException(status_code=400, detail="No players in the game.")

    # Initialize players with 2 coins and cards.
    game["players"] = [{"name": name, "coins": 2, "cards": generate_cards(2)} for name in game["players"]]
    # Reset permissions to a dictionary with proper keys for each player.
    game["permissions"] = {player["name"]: {"steal": True, "gain": True} for player in game["players"]}
    game["gameStarted"] = True
    game["turn"] = game["players"][0]["name"]

    return {"success": True, "message": "Game started successfully!"}

# New endpoint for deleting a game
@app.post("/api/deleteGame")
async def delete_game(request: Request):
    data = await request.json()
    pin = data.get("pin")
    newPin = data.get("newPin")
    
    if not pin:
        raise HTTPException(status_code=400, detail="PIN is required.")
    
    game = games.get(pin)
    if not game:
        raise HTTPException(status_code=404, detail="Game not found.")
    
    games[pin] = {"gameEnded": True, "newPin": newPin}
    return {"success": True, "message": "Game deleted successfully!"}

def generate_cards(numofcards):
    cards = ['Duke', 'Assassin', 'Captain', 'Ambassador', 'Contessa']
    shuffled = sorted(cards, key=lambda x: 0.5 - random.random())
    if numofcards == 1:
        return [shuffled[0]]
    else:
        return [shuffled[0], shuffled[1]]

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

def check_game_status(game):
    # Filter active players (only those who still have cards)
    active_players = [p for p in game.get("players", []) if p.get("cards")]

    # If the current turn player is no longer in the active players, update turn to the next available player's name.
    if not any(p["name"] == game.get("turn") for p in active_players):
        if active_players:
            game["turn"] = active_players[0]["name"]
        else:
            game["turn"] = None

    # Update the game players to only the active players.
    game["players"] = active_players

    # Update permissions: Flag players with more than 10 coins to coup.
    for p in game["players"]:
        name = p["name"]
        if p.get("coins", 0) > 10:
            if name not in game.get("permissions", {}):
                game.setdefault("permissions", {})[name] = {}
            game["permissions"][name]["mustCoup"] = True
        else:
            if name in game.get("permissions", {}):
                game["permissions"][name].pop("mustCoup", None)
    return game

def capitalize_name(name):
    result = ""
    capitalize_next = True  # Capitalize first letter

    for char in name:
        if capitalize_next and char.isalpha():
            result += char.upper()
            capitalize_next = False
        else:
            result += char
        if char == " ":
            capitalize_next = True

    return result