From 48996cd85fbd96c9b35bb6cb8f1ae579f36d0cff Mon Sep 17 00:00:00 2001 From: Mercurio <47455213+NotLugozzi@users.noreply.github.com> Date: Tue, 24 Dec 2024 14:02:45 +0100 Subject: [PATCH] Add match termination endpoint, fix issue when joining a match you had created --- main.py | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/main.py b/main.py index b500958..050513b 100644 --- a/main.py +++ b/main.py @@ -12,6 +12,7 @@ app.add_middleware( allow_methods=["*"], allow_headers=["*"], ) + class RegisterRequest(BaseModel): email: str display_name: str @@ -175,8 +176,13 @@ def join_match(request: JoinMatchRequest): match = cursor.fetchone() if not match: raise HTTPException(status_code=404, detail="Match not found") + + if match["player1_uid"] == player2_uid: + raise HTTPException(status_code=503, detail="You cannot join a match you created") + if match["player2_uid"] is not None: raise HTTPException(status_code=400, detail="Match is already full") + cursor.execute( """ UPDATE matches @@ -194,6 +200,81 @@ def join_match(request: JoinMatchRequest): cursor.close() conn.close() +def calculate_elo(player1_elo, player2_elo, player1_score, player2_score): + k_factor = 32 + expected1 = 1 / (1 + 10 ** ((player2_elo - player1_elo) / 400)) + expected2 = 1 / (1 + 10 ** ((player1_elo - player2_elo) / 400)) + actual1 = 1 if player1_score > player2_score else 0 if player1_score < player2_score else 0.5 + actual2 = 1 - actual1 + elo_change1 = round(k_factor * (actual1 - expected1)) + elo_change2 = round(k_factor * (actual2 - expected2)) + return elo_change1, elo_change2 + +@app.post("/endmatch") +def end_match(request: EndMatchRequest): + conn = get_db_connection() + cursor = conn.cursor() + try: + cursor.execute( + """ + SELECT player1_uid, player2_uid + FROM matches + WHERE match_id = %s; + """, + (request.match_id,) + ) + match = cursor.fetchone() + if not match: + raise HTTPException(status_code=404, detail="Match not found") + + player1_uid, player2_uid = match["player1_uid"], match["player2_uid"] + + cursor.execute( + """ + SELECT uid, current_elo + FROM users + WHERE uid IN (%s, %s); + """, + (player1_uid, player2_uid) + ) + players = cursor.fetchall() + player1_elo = next(p["current_elo"] for p in players if p["uid"] == player1_uid) + player2_elo = next(p["current_elo"] for p in players if p["uid"] == player2_uid) + + elo_change1, elo_change2 = calculate_elo( + player1_elo, player2_elo, request.player1_score, request.player2_score + ) + + cursor.execute( + """ + UPDATE matches + SET player1_score = %s, player2_score = %s, + player1_elo_change = %s, player2_elo_change = %s + WHERE match_id = %s; + """, + (request.player1_score, request.player2_score, elo_change1, elo_change2, request.match_id) + ) + new_player1_elo = player1_elo + elo_change1 + new_player2_elo = player2_elo + elo_change2 + cursor.execute( + """ + UPDATE users + SET current_elo = CASE WHEN uid = %s THEN %s WHEN uid = %s THEN %s END + WHERE uid IN (%s, %s); + """, + (player1_uid, new_player1_elo, player2_uid, new_player2_elo, player1_uid, player2_uid) + ) + + conn.commit() + return {"message": "Match ended successfully"} + except Exception as e: + conn.rollback() + raise HTTPException(status_code=400, detail=str(e)) + finally: + cursor.close() + conn.close() + + @app.post("/getprofile") def get_profile(request: ProfileRequest): conn = get_db_connection()