Use player names in two-player briscola

Classic briscola has no partnerships: its "teams" are just the two
players, but the UI labelled them Team A/Team B.

- add is_individual_game() and GameView::player_name_for_team() to the
  model;
- the briscola table HUD reads "Alice 0 — 0 Bob (target 61)" and the
  seat panels drop the Team badge for two-player games;
- the deal summary and game-over screen name the sides and the winner;
- the waiting room and join preview hide the Team badge.

briscola a quattro and scopone keep their team labels, and the match
history table is unchanged.
This commit is contained in:
woggioni committed 2026-10-06 17:37:55 +08:00
1 parent 6222e38da3
commit b821274f0b
5 files changed
+121 -27

No files matched your search

+21 -7
View File
@@ -12,8 +12,8 @@ use crate::components::copy::CopyButton;
use crate::components::summary::{hand_summary_modal, summary_rows};
use crate::components::toast::toast;
use crate::model::{
card_label, hand_sort_key, is_briscola, GameView, MoveView, PlayerView, Scores,
ServerMessage,
card_label, hand_sort_key, is_briscola, is_individual_game, GameView, MoveView,
PlayerView, Scores, ServerMessage,
};
use crate::pages::briscola::briscola_table;
use crate::ws::{self, GameSocket};
@@ -433,19 +433,23 @@ fn LobbyView(game: GameView) -> View {
let join_code = game.join_code.clone();
let watch_link = watch_link(&game.id);
let show_teams = !is_individual_game(&game.game_type);
let players = game
.players
.iter()
.map(|p| {
let name = p.name.clone();
let seat = p.seat;
let team = p.team.clone();
let team_badge = show_teams.then(|| {
let team = p.team.clone();
view! { span(class="badge text-bg-info") { "Team " (team) } }
});
view! {
li(class="list-group-item d-flex justify-content-between align-items-center") {
strong { (name) }
span {
span(class="badge text-bg-secondary me-2") { "Seat " (seat) }
span(class="badge text-bg-info") { "Team " (team) }
(team_badge)
}
}
}
@@ -744,14 +748,24 @@ fn game_over_view(over: Option<(Scores, Option<String>)>, game: Option<GameView>
None => view! {},
Some((scores, winner)) => {
let winner = winner.unwrap_or_else(|| "?".to_string());
let line = format!("Team {winner} wins {} – {}", scores.a, scores.b);
// Two-player briscola has no teams: name the winner instead.
let winner_label = match game.as_ref() {
Some(g) if is_individual_game(&g.game_type) => {
g.player_name_for_team(&winner)
}
_ => format!("Team {winner}"),
};
let line = format!("{winner_label} wins {} – {}", scores.a, scores.b);
// Spectators have no match history to look at.
let spectator = game.as_ref().is_some_and(|g| g.spectator);
// Explain the final hand's (scopone) or deal's (briscola)
// scoring before the result.
let final_summary: View = if briscola {
match game.as_ref().and_then(|g| g.last_deal.clone()) {
Some(deal) => deal_rows(&deal),
match game.as_ref() {
Some(g) => match g.last_deal.clone() {
Some(deal) => deal_rows(g, &deal),
None => view! {},
},
None => view! {},
}
} else {