|
6 | 6 | // |
7 | 7 |
|
8 | 8 | #include "format-cards.hpp" |
| 9 | + |
| 10 | +#include <stdexcept> |
| 11 | +#include <cctype> |
| 12 | + |
9 | 13 | #include "params.hpp" |
10 | 14 | #include "utils.hpp" |
| 15 | +#include "random.hpp" |
| 16 | + |
| 17 | +using namespace std; |
| 18 | + |
| 19 | +// https://en.wikipedia.org/wiki/High_card_by_suit |
| 20 | +static const vector<char> card_suits = { 'd', 'c', 'h', 's' }; |
| 21 | +static const vector<char> card_ranks = { 'a', '2', '3', '4', '5', '6', '7', '8', '9', 't', 'j', 'q', 'k'}; |
| 22 | + |
| 23 | +static size_t parse_rank(char c) { |
| 24 | + c = tolower(c); |
| 25 | + for(size_t i = 0; i < card_ranks.size(); i++) { |
| 26 | + if(c == card_ranks[i]) { |
| 27 | + return i; |
| 28 | + } |
| 29 | + } |
| 30 | + throw runtime_error("Invalid card rank. Allowed: [A,2-9,T,J,Q,K]"); |
| 31 | +} |
| 32 | + |
| 33 | +static size_t parse_suit(char c) { |
| 34 | + c = tolower(c); |
| 35 | + for(size_t i = 0; i < card_suits.size(); i++) { |
| 36 | + if(c == card_suits[i]) { |
| 37 | + return i; |
| 38 | + } |
| 39 | + } |
| 40 | + throw runtime_error("Invalid card rank. Allowed: [D,C,H,S]"); |
| 41 | +} |
11 | 42 |
|
12 | | -static const std::string card_suits[] = { "c", "d", "h", "s" }; |
13 | | -static const std::string card_ranks[] = { "a", "2", "3", "4", "5", "6", "7", "8", "9", "t", "j", "q", "k"}; |
| 43 | +vector<uint8_t> cards_to_data(const string& cards) { |
| 44 | + vector<uint8_t> result; |
14 | 45 |
|
15 | | -static std::string to_card(size_t n) { |
| 46 | + auto len = cards.length(); |
| 47 | + if(len % 2 != 0) { |
| 48 | + throw runtime_error("Cards string must have even number of characters."); |
| 49 | + } |
| 50 | + auto count = len / 2; |
| 51 | + result.reserve(count); |
| 52 | + for(auto i = 0; i < count; i++) { |
| 53 | + auto rank = parse_rank(cards[i * 2]); |
| 54 | + auto suit = parse_suit(cards[i * 2 + 1]); |
| 55 | + auto n = suit * 13 + rank; |
| 56 | + result.push_back(n); |
| 57 | + } |
| 58 | + |
| 59 | + return result; |
| 60 | +} |
| 61 | + |
| 62 | +void FormatCards::process_input(Params* p) { |
| 63 | + auto input = p->get_one_argument(); |
| 64 | + auto entropy = cards_to_data(input); |
| 65 | + p->seed = deterministic_random(entropy, p->count); |
| 66 | +} |
| 67 | + |
| 68 | +static string to_card(size_t n) { |
16 | 69 | if(n > 51) { return NULL; } |
17 | | - std::string buf; |
| 70 | + string buf; |
18 | 71 | size_t rank = n % 13; |
19 | 72 | size_t suit = n / 13; |
20 | | - buf.append(card_ranks[rank]); |
21 | | - buf.append(card_suits[suit]); |
22 | | - return buf; |
23 | | -} |
| 73 | + buf += card_ranks[rank]; |
| 74 | + buf += card_suits[suit]; |
24 | 75 |
|
25 | | -void FormatCards::process_input(Params* p) { |
| 76 | + // test value round trip |
| 77 | + auto v = cards_to_data(buf); |
| 78 | + assert(v.size() == 1); |
| 79 | + assert(v[0] == n); |
| 80 | + |
| 81 | + return buf; |
26 | 82 | } |
27 | 83 |
|
28 | 84 | void FormatCards::process_output(Params* p) { |
|
0 commit comments