// This file is part of Timmi. // // Timmi is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. #ifndef CARDS_HH #define CARDS_HH #include #include // Basic datatypes enum Joker {NOJOKER = 0, REDJOKER, BLACKJOKER, JOKER}; enum Suit {NOSUIT = 0, CLUBS = 1, SPADES = 2, HEARTS = 3, DIAMONDS = 4}; enum Rank {NORANK = 0, ACE = 1, R2 = 2, R3 = 3, R4 = 4, R5 = 5, R6 = 6, \ R7 = 7, R8 = 8, R9 = 9, R10 = 10, JACK = 11, QUEEN = 12, KING = 13}; struct Card { Joker joker; Suit suit; Rank rank; bool operator==(const Card &other) const; }; struct TableCard { Card tobeat; Card beater; bool operator==(const TableCard &other) const; }; //----------------------- // Card-related functions // Card has actual rank and suit, not NORANK nor NOSUIT // Unassigned jokers return false. bool is_card(const Card &); // Card is a joker bool is_joker(const Card &); // Joker & suit combination is valid bool is_valid_joker(const Card &); // If card is assigned joker, unassign Card unassign_joker(Card); // First card can be beaten with second, when suit is trump bool can_beat(const Card &, const Card &, Suit); // First rank is higher than second bool rank_higher(Rank, Rank); //----------------------------------- // Vector of cards -related functions // Add one full deck of cards to vector void init_deck(std::vector &, bool jokers = false); // Remove first occurring card from a vector of cards void remove_card(std::vector &, Card); // Shuffle vector of cards void shuffle_deck(std::vector &deck); //---------------------------------------- // Vector of TableCards -related functions // All cards on table have been beaten and table is not empty bool all_beaten(const std::vector &); // Assign joker to something sensible // Something sensible for hitting is biggest existing rank // with trump suit if possible. Card assign_joker_hit(std::vector &, Card card, Suit trump); // Sensible for beating is existing rank if possible, with trump or tobeat suit. Card assign_joker_beat(std::vector &, Card card, Card tobeat, Suit trump); // Card to beat is on table and is not beaten yet bool card_on_table(const std::vector &, const Card &); // Player with hand can beat all cards on table // Implementation is not perfect, may return false negatives bool can_beat_all(const std::vector &table, const std::vector &hand, Suit trump); // Card on table are of only one rank and none are beaten bool one_rank_only(const std::vector &, Rank); // Card of same rank exists on table already bool rank_exists_on_table(const std::vector &, Rank); bool rank_exists_on_table(const std::vector &, const Card &); //--------------------------------------- // Sorting vector of cards // Sort worst card first, beatwise class CMPWorst { public: CMPWorst(Suit trump); bool operator()(Card a, Card b) const; private: Suit trump_; }; // Sort cards by suit and rank, trump suit first class CMPSuit { public: CMPSuit(Suit trump); bool operator()(Card a, Card b) const; private: Suit trump_; }; //--------------------------------------- // Sorting vector of tablecards // Beaten first, then by rank // Functor interface for future expansion class CMPTable { public: CMPTable(Suit trump); bool operator()(TableCard a, TableCard b) const; private: Suit trump_; }; #endif