mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 01:07:36 +00:00
Hearts: Add support for playing more than one hand
This changes the game so that more than one hand can be played. Once one player has 100 or more points the game ends. A score card is shown between each hand. Fixes #7374.
This commit is contained in:
parent
e636ed43eb
commit
87ace131bc
6 changed files with 226 additions and 33 deletions
89
Userland/Games/Hearts/ScoreCard.cpp
Normal file
89
Userland/Games/Hearts/ScoreCard.cpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Gunnar Beutner <gbeutner@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "ScoreCard.h"
|
||||
#include <LibGUI/Button.h>
|
||||
#include <LibGUI/Painter.h>
|
||||
#include <LibGUI/Window.h>
|
||||
#include <LibGfx/Font.h>
|
||||
|
||||
namespace Hearts {
|
||||
|
||||
ScoreCard::ScoreCard(Player (&players)[4], bool game_over)
|
||||
: m_players(players)
|
||||
, m_game_over(game_over)
|
||||
{
|
||||
set_min_size(recommended_size());
|
||||
resize(recommended_size());
|
||||
}
|
||||
|
||||
Gfx::IntSize ScoreCard::recommended_size()
|
||||
{
|
||||
auto& card_font = font().bold_variant();
|
||||
|
||||
return Gfx::IntSize {
|
||||
4 * column_width + 3 * cell_padding,
|
||||
16 * card_font.glyph_height() + 15 * cell_padding
|
||||
};
|
||||
}
|
||||
void ScoreCard::paint_event(GUI::PaintEvent& event)
|
||||
{
|
||||
GUI::Widget::paint_event(event);
|
||||
|
||||
GUI::Painter painter(*this);
|
||||
painter.add_clip_rect(frame_inner_rect());
|
||||
painter.add_clip_rect(event.rect());
|
||||
|
||||
auto& font = painter.font().bold_variant();
|
||||
|
||||
auto cell_rect = [this, &font](int x, int y) {
|
||||
return Gfx::IntRect {
|
||||
frame_inner_rect().left() + x * column_width + x * cell_padding,
|
||||
frame_inner_rect().top() + y * font.glyph_height() + y * cell_padding,
|
||||
column_width,
|
||||
font.glyph_height(),
|
||||
};
|
||||
};
|
||||
|
||||
VERIFY(!m_players[0].scores.is_empty());
|
||||
|
||||
int leading_score = -1;
|
||||
for (size_t player_index = 0; player_index < 4; player_index++) {
|
||||
auto& player = m_players[player_index];
|
||||
auto cumulative_score = player.scores[player.scores.size() - 1];
|
||||
if (leading_score == -1 || cumulative_score < leading_score)
|
||||
leading_score = cumulative_score;
|
||||
}
|
||||
|
||||
for (int player_index = 0; player_index < 4; player_index++) {
|
||||
auto& player = m_players[player_index];
|
||||
auto cumulative_score = player.scores[player.scores.size() - 1];
|
||||
auto leading_color = m_game_over ? Color::Magenta : Color::Blue;
|
||||
auto text_color = cumulative_score == leading_score ? leading_color : Color::Black;
|
||||
dbgln("text_rect: {}", cell_rect(player_index, 0));
|
||||
painter.draw_text(cell_rect(player_index, 0),
|
||||
player.name,
|
||||
font, Gfx::TextAlignment::Center,
|
||||
text_color);
|
||||
for (int score_index = 0; score_index < (int)player.scores.size(); score_index++) {
|
||||
auto text_rect = cell_rect(player_index, 1 + score_index);
|
||||
auto score_text = String::formatted("{}", player.scores[score_index]);
|
||||
auto score_text_width = font.width(score_text);
|
||||
if (score_index != (int)player.scores.size() - 1) {
|
||||
painter.draw_line(
|
||||
{ text_rect.left() + text_rect.width() / 2 - score_text_width / 2 - 3, text_rect.top() + font.glyph_height() / 2 },
|
||||
{ text_rect.right() - text_rect.width() / 2 + score_text_width / 2 + 3, text_rect.top() + font.glyph_height() / 2 },
|
||||
text_color);
|
||||
}
|
||||
painter.draw_text(text_rect,
|
||||
score_text,
|
||||
font, Gfx::TextAlignment::Center,
|
||||
text_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue