From cc7afb5477a7b7aee11d6b0e2158d94e77856906 Mon Sep 17 00:00:00 2001 From: denizk0461 Date: Wed, 16 Jul 2025 11:15:05 +0200 Subject: [PATCH] scoring implemented; clients calculate scores individually and display ranks per player --- cards/card_manager.gd | 8 ++++++++ components/bet_result.gd | 6 ++++++ components/score_result.gd | 15 +++++++++++++++ components/score_result.gd.uid | 1 + components/web_client_tcp.gd | 9 +++++++++ elements/player_hand.gd | 7 +++++++ elements/player_hand.tscn | 8 +++++++- environment_manager.gd | 16 ++++++++++++++++ game.tscn | 1 + game_client.gd | 4 ++-- server_tcp.py | 8 ++++++++ 11 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 components/score_result.gd create mode 100644 components/score_result.gd.uid diff --git a/cards/card_manager.gd b/cards/card_manager.gd index 340f58f..83db494 100644 --- a/cards/card_manager.gd +++ b/cards/card_manager.gd @@ -23,6 +23,14 @@ func _ready() -> void: assert(get_winning_card([14, 15, 18, 13], 46) == 18) # trumpless win assert(get_winning_card([28, 12, 31, 13], -1) == 31) + + # score calculation tests + assert(BetResult.new(1, 1).get_score() == 30) + assert(BetResult.new(0, 0).get_score() == 20) + assert(BetResult.new(4, 4).get_score() == 60) + assert(BetResult.new(1, 2).get_score() == -10) + assert(BetResult.new(1, 4).get_score() == -30) + assert(BetResult.new(4, 1).get_score() == -30) func get_shuffled_cards(client_ids: Array[String], cards_to_pick: int) -> Dictionary: # Dictionary[String, Array[int]] var dict: Dictionary = {} diff --git a/components/bet_result.gd b/components/bet_result.gd index 5f71c0e..79d23a6 100644 --- a/components/bet_result.gd +++ b/components/bet_result.gd @@ -22,3 +22,9 @@ func _to_string() -> String: "e": expected, "a": actual, }) + +func get_score() -> int: + if expected == actual: + return 20 + (actual * 10) + else: + return (abs(max(expected, actual)) - abs(min(expected, actual))) * -10 diff --git a/components/score_result.gd b/components/score_result.gd new file mode 100644 index 0000000..f97e445 --- /dev/null +++ b/components/score_result.gd @@ -0,0 +1,15 @@ +class_name ScoreResult +extends Resource + +@export var client_id: String +@export var score: int + +func _init( + client_id: String, + score: int = 0, +) -> void: + self.client_id = client_id + self.score = score + +func add_to_score(value: int) -> void: + self.score += value diff --git a/components/score_result.gd.uid b/components/score_result.gd.uid new file mode 100644 index 0000000..edb2aab --- /dev/null +++ b/components/score_result.gd.uid @@ -0,0 +1 @@ +uid://deee013gohqfd diff --git a/components/web_client_tcp.gd b/components/web_client_tcp.gd index ee1a043..53a35bc 100644 --- a/components/web_client_tcp.gd +++ b/components/web_client_tcp.gd @@ -49,6 +49,7 @@ signal received_winning_client(client_id: String) signal notify_play_card_request() signal received_played_card(client_id: String, card_id: int) signal received_play_winner_request() +signal received_end_game_request() signal request_next_play() signal request_next_round() @@ -160,6 +161,8 @@ func _handle_response(response: String) -> void: print(data) "determine_play_winner_request": # single card go-around received_play_winner_request.emit.call_deferred() + "end_game_request": + received_end_game_request.emit.call_deferred() "client_played_card": received_played_card.emit.call_deferred(data["client_id"], data["played_card"]) "client_won_play": @@ -240,6 +243,12 @@ func start_next_round(round_count: int) -> void: "cards": CardManager.get_shuffled_cards(_connected_client_ids, round_count), })) +func end_game() -> void: + _send_message(JSON.stringify({ + "response": "end_game", + "lobby_id": _lobby_id, + })) + func play_card(card_id: int) -> void: _send_message(JSON.stringify({ "response": "play_card", diff --git a/elements/player_hand.gd b/elements/player_hand.gd index f136fbb..8e7fd04 100644 --- a/elements/player_hand.gd +++ b/elements/player_hand.gd @@ -19,6 +19,7 @@ var _is_owned: bool @export_range(0, 20, 0.1, "radians_as_degrees") var card_angle: float @export var name_label: Label3D +@export var rank_label: Label3D @export var hide_client_name: bool = false var _selected_card: PlayingCard = null @@ -93,3 +94,9 @@ func _on_play_card_button_pressed() -> void: remove_card(_selected_card) _selected_card = null card_selected.emit(-1) + +func display_rank(rank: int, score: int) -> void: + rank_label.text = "#{rank} ({pts} pts)".format({ + "rank": rank, + "pts": score, + }) diff --git a/elements/player_hand.tscn b/elements/player_hand.tscn index 550fbbe..956b665 100644 --- a/elements/player_hand.tscn +++ b/elements/player_hand.tscn @@ -3,12 +3,13 @@ [ext_resource type="Script" uid="uid://b5b5cl2qlhywv" path="res://elements/player_hand.gd" id="1_ank64"] [ext_resource type="PackedScene" uid="uid://b55xpcxk7g5ph" path="res://cards/playing_card.tscn" id="2_11xsc"] -[node name="PlayerHand" type="Node3D" node_paths=PackedStringArray("card_container", "name_label")] +[node name="PlayerHand" type="Node3D" node_paths=PackedStringArray("card_container", "name_label", "rank_label")] script = ExtResource("1_ank64") card_scene = ExtResource("2_11xsc") card_container = NodePath("CardContainer") card_angle = 0.125664 name_label = NodePath("NameLabel") +rank_label = NodePath("RankLabel") [node name="NameLabel" type="Label3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.513717, 0) @@ -17,3 +18,8 @@ double_sided = false text = "name goes here" [node name="CardContainer" type="Node3D" parent="."] + +[node name="RankLabel" type="Label3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.283052, 0) +billboard = 1 +double_sided = false diff --git a/environment_manager.gd b/environment_manager.gd index ddbe5b2..cfd3ea6 100644 --- a/environment_manager.gd +++ b/environment_manager.gd @@ -123,3 +123,19 @@ func _on_web_client_tcp_received_expected_bet(client_id: String, expected_bet: i func _on_web_client_tcp_received_winning_client(client_id: String) -> void: _bets[client_id][_bets[client_id].size() - 1].add_win() print(_bets) + +func _on_web_client_tcp_received_end_game_request() -> void: + var scores: Array[ScoreResult] + + for client_id in _bets.keys(): + var score = ScoreResult.new(client_id) + for bet_result in _bets[client_id]: + score.add_to_score(bet_result.get_score()) + scores.append(score) + + scores.sort_custom(func(a, b): return a.score < b.score) + + var rank = scores.size() + for score_result: ScoreResult in scores: + hand_associations[score_result.client_id].display_rank(rank, score_result.score) + rank -= 1 diff --git a/game.tscn b/game.tscn index bcde9cd..7db630b 100644 --- a/game.tscn +++ b/game.tscn @@ -293,6 +293,7 @@ transform = Transform3D(0.957037, -0.289967, -1.26749e-08, 1.48302e-15, -4.37114 [connection signal="received_chat_message" from="WebClientTCP" to="HBoxContainer/ClientInterface" method="_on_web_client_tcp_received_chat_message"] [connection signal="received_client_id" from="WebClientTCP" to="EnvironmentManager" method="_on_web_client_tcp_received_client_id"] [connection signal="received_connection_message" from="WebClientTCP" to="HBoxContainer/ClientInterface" method="_on_web_client_tcp_received_connection_message"] +[connection signal="received_end_game_request" from="WebClientTCP" to="EnvironmentManager" method="_on_web_client_tcp_received_end_game_request"] [connection signal="received_expected_bet" from="WebClientTCP" to="EnvironmentManager" method="_on_web_client_tcp_received_expected_bet"] [connection signal="received_play_winner_request" from="WebClientTCP" to="EnvironmentManager" method="_on_web_client_tcp_received_play_winner_request"] [connection signal="received_played_card" from="WebClientTCP" to="EnvironmentManager" method="_on_web_client_tcp_received_played_card"] diff --git a/game_client.gd b/game_client.gd index f61fbc0..56aae13 100644 --- a/game_client.gd +++ b/game_client.gd @@ -25,7 +25,7 @@ func _start_next_play() -> void: func _start_next_round() -> void: if _current_round == _max_rounds: - pass + web_client.end_game() # end game else: _current_round += 1 @@ -35,7 +35,7 @@ func _start_next_round() -> void: func _get_max_rounds(player_count: int) -> int: match player_count: 3: - return 20 + return 3 4: return 15 5: diff --git a/server_tcp.py b/server_tcp.py index 1545d20..abe3093 100644 --- a/server_tcp.py +++ b/server_tcp.py @@ -539,6 +539,14 @@ async def process_input(message: str, websocket) -> None: ) print(f"DING DING DING we have a winner!!! {data_object['client_id']}") + + elif data_object["response"] == "end_game": + await lobby_manager.broadcast_message( + data_object["lobby_id"], + json.dumps({ + "response": "end_game_request", + }) + ) if __name__ == '__main__': run_local = False