mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 12:37:44 +00:00
LibCards+Games: Move "create a deck" logic to LibCards
`create_standard_deck()` is the usual 52-card deck, but more custom setups (such as Spider's multiples-of-one-suit) can be created by passing suit counts to `create_deck()`.
This commit is contained in:
parent
1d533acbc0
commit
46299f3853
5 changed files with 64 additions and 42 deletions
|
@ -199,20 +199,12 @@ void Game::setup(String player_name, int hand_number)
|
||||||
m_passing_button->set_focus(false);
|
m_passing_button->set_focus(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullRefPtrVector<Card> deck;
|
NonnullRefPtrVector<Card> deck = Cards::create_standard_deck(Cards::Shuffle::Yes);
|
||||||
deck.ensure_capacity(Card::card_count * 4);
|
|
||||||
|
|
||||||
for (int i = 0; i < Card::card_count; ++i) {
|
|
||||||
deck.append(Card::construct(Cards::Suit::Clubs, static_cast<Cards::Rank>(i)));
|
|
||||||
deck.append(Card::construct(Cards::Suit::Spades, static_cast<Cards::Rank>(i)));
|
|
||||||
deck.append(Card::construct(Cards::Suit::Hearts, static_cast<Cards::Rank>(i)));
|
|
||||||
deck.append(Card::construct(Cards::Suit::Diamonds, static_cast<Cards::Rank>(i)));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& player : m_players) {
|
for (auto& player : m_players) {
|
||||||
player.hand.ensure_capacity(Card::card_count);
|
player.hand.ensure_capacity(Card::card_count);
|
||||||
for (uint8_t i = 0; i < Card::card_count; ++i) {
|
for (uint8_t i = 0; i < Card::card_count; ++i) {
|
||||||
auto card = deck.take(get_random_uniform(deck.size()));
|
auto card = deck.take_last();
|
||||||
if constexpr (!HEARTS_DEBUG) {
|
if constexpr (!HEARTS_DEBUG) {
|
||||||
if (&player != &m_players[0])
|
if (&player != &m_players[0])
|
||||||
card->set_upside_down(true);
|
card->set_upside_down(true);
|
||||||
|
|
|
@ -162,15 +162,7 @@ void Game::setup(Mode mode)
|
||||||
if (on_undo_availability_change)
|
if (on_undo_availability_change)
|
||||||
on_undo_availability_change(false);
|
on_undo_availability_change(false);
|
||||||
|
|
||||||
for (int i = 0; i < Card::card_count; ++i) {
|
m_new_deck = Cards::create_standard_deck(Cards::Shuffle::Yes);
|
||||||
m_new_deck.append(Card::construct(Cards::Suit::Clubs, static_cast<Cards::Rank>(i)));
|
|
||||||
m_new_deck.append(Card::construct(Cards::Suit::Spades, static_cast<Cards::Rank>(i)));
|
|
||||||
m_new_deck.append(Card::construct(Cards::Suit::Hearts, static_cast<Cards::Rank>(i)));
|
|
||||||
m_new_deck.append(Card::construct(Cards::Suit::Diamonds, static_cast<Cards::Rank>(i)));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 200; ++i)
|
|
||||||
m_new_deck.append(m_new_deck.take(get_random_uniform(m_new_deck.size())));
|
|
||||||
|
|
||||||
m_focused_stack = nullptr;
|
m_focused_stack = nullptr;
|
||||||
m_focused_cards.clear();
|
m_focused_cards.clear();
|
||||||
|
|
|
@ -48,32 +48,24 @@ void Game::setup(Mode mode)
|
||||||
m_score = 500;
|
m_score = 500;
|
||||||
update_score(0);
|
update_score(0);
|
||||||
|
|
||||||
NonnullRefPtrVector<Card> deck;
|
unsigned heart_suits = 0;
|
||||||
deck.ensure_capacity(Card::card_count * 2);
|
unsigned spade_suits = 0;
|
||||||
|
|
||||||
for (int i = 0; i < Card::card_count; ++i) {
|
|
||||||
switch (m_mode) {
|
switch (m_mode) {
|
||||||
case Mode::SingleSuit:
|
case Mode::SingleSuit:
|
||||||
for (int j = 0; j < 8; j++) {
|
spade_suits = 8;
|
||||||
deck.append(Card::construct(Cards::Suit::Spades, static_cast<Cards::Rank>(i)));
|
heart_suits = 0;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case Mode::TwoSuit:
|
case Mode::TwoSuit:
|
||||||
for (int j = 0; j < 4; j++) {
|
spade_suits = 4;
|
||||||
deck.append(Card::construct(Cards::Suit::Spades, static_cast<Cards::Rank>(i)));
|
heart_suits = 4;
|
||||||
deck.append(Card::construct(Cards::Suit::Hearts, static_cast<Cards::Rank>(i)));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
m_new_deck.clear_with_capacity();
|
m_new_deck = Cards::create_deck(0, 0, heart_suits, spade_suits, Cards::Shuffle::Yes);
|
||||||
m_new_deck.ensure_capacity(deck.size());
|
|
||||||
while (!deck.is_empty())
|
|
||||||
m_new_deck.append(deck.take(get_random_uniform(deck.size())));
|
|
||||||
|
|
||||||
m_focused_stack = nullptr;
|
m_focused_stack = nullptr;
|
||||||
m_focused_cards.clear();
|
m_focused_cards.clear();
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, Till Mayer <till.mayer@web.de>
|
* Copyright (c) 2020, Till Mayer <till.mayer@web.de>
|
||||||
* Copyright (c) 2022, the SerenityOS developers.
|
* Copyright (c) 2022, the SerenityOS developers.
|
||||||
|
* Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Card.h"
|
#include "Card.h"
|
||||||
|
#include <AK/Random.h>
|
||||||
#include <LibCards/CardPainter.h>
|
#include <LibCards/CardPainter.h>
|
||||||
|
|
||||||
namespace Cards {
|
namespace Cards {
|
||||||
|
@ -50,4 +52,40 @@ void Card::clear_and_draw(GUI::Painter& painter, Color const& background_color)
|
||||||
save_old_position();
|
save_old_position();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NonnullRefPtrVector<Card> create_standard_deck(Shuffle shuffle)
|
||||||
|
{
|
||||||
|
return create_deck(1, 1, 1, 1, shuffle);
|
||||||
|
}
|
||||||
|
|
||||||
|
NonnullRefPtrVector<Card> create_deck(unsigned full_club_suit_count, unsigned full_diamond_suit_count, unsigned full_heart_suit_count, unsigned full_spade_suit_count, Shuffle shuffle)
|
||||||
|
{
|
||||||
|
NonnullRefPtrVector<Card> deck;
|
||||||
|
deck.ensure_capacity(Card::card_count * (full_club_suit_count + full_diamond_suit_count + full_heart_suit_count + full_spade_suit_count));
|
||||||
|
|
||||||
|
auto add_cards_for_suit = [&deck](Cards::Suit suit, unsigned number_of_suits) {
|
||||||
|
for (auto i = 0u; i < number_of_suits; ++i) {
|
||||||
|
for (auto rank = 0; rank < Card::card_count; ++rank) {
|
||||||
|
deck.append(Card::construct(suit, static_cast<Cards::Rank>(rank)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
add_cards_for_suit(Cards::Suit::Clubs, full_club_suit_count);
|
||||||
|
add_cards_for_suit(Cards::Suit::Diamonds, full_diamond_suit_count);
|
||||||
|
add_cards_for_suit(Cards::Suit::Hearts, full_heart_suit_count);
|
||||||
|
add_cards_for_suit(Cards::Suit::Spades, full_spade_suit_count);
|
||||||
|
|
||||||
|
if (shuffle == Shuffle::Yes)
|
||||||
|
shuffle_deck(deck);
|
||||||
|
|
||||||
|
return deck;
|
||||||
|
}
|
||||||
|
|
||||||
|
void shuffle_deck(NonnullRefPtrVector<Card>& deck)
|
||||||
|
{
|
||||||
|
auto iteration_count = deck.size() * 4;
|
||||||
|
for (auto i = 0u; i < iteration_count; ++i)
|
||||||
|
deck.append(deck.take(get_random_uniform(deck.size())));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,6 +123,14 @@ private:
|
||||||
bool m_inverted { false };
|
bool m_inverted { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class Shuffle {
|
||||||
|
No,
|
||||||
|
Yes,
|
||||||
|
};
|
||||||
|
NonnullRefPtrVector<Card> create_standard_deck(Shuffle);
|
||||||
|
NonnullRefPtrVector<Card> create_deck(unsigned full_club_suit_count, unsigned full_diamond_suit_count, unsigned full_heart_suit_count, unsigned full_spade_suit_count, Shuffle);
|
||||||
|
void shuffle_deck(NonnullRefPtrVector<Card>&);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue