diff options
Diffstat (limited to '')
-rw-r--r-- | stack.h | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/stack.h b/stack.h new file mode 100644 index 0000000..c315729 --- /dev/null +++ b/stack.h @@ -0,0 +1,122 @@ +/* Copyright (C) 2019 C. McEnroe <june@causal.agency> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef STACK_H +#define STACK_H + +#include <assert.h> +#include <stdlib.h> + +#include <SDL_stdinc.h> +#include <cards.h> + +#ifndef STACK_CAP +#define STACK_CAP 52 +#endif + +#if STACK_CAP < 52 +#error "Stack capacity too small for deck" +#endif + +typedef Sint8 Card; + +static inline int suit(Card card) { + card = abs(card); + if (card > Cards_Spade) { + return Cards_Spade; + } else if (card > Cards_Heart) { + return Cards_Heart; + } else if (card > Cards_Diamond) { + return Cards_Diamond; + } else { + return Cards_Club; + } +} + +static inline int color(Card card) { + return suit(card) == Cards_Diamond || suit(card) == Cards_Heart; +} + +static inline int rank(Card card) { + return abs(card) - suit(card); +} + +struct Stack { + Uint8 len; + Card cards[STACK_CAP]; +}; + +static const struct Stack Deck = { + .len = 52, + .cards = { + -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, + -14, -15, -16, -17, -18, -19, -20, -21, -22, -23, -24, -25, -26, + -27, -28, -29, -30, -31, -32, -33, -34, -35, -36, -37, -38, -39, + -40, -41, -42, -43, -44, -45, -46, -47, -48, -49, -50, -51, -52, + }, +}; + +static inline void clear(struct Stack *stack) { + stack->len = 0; +} + +static inline void push(struct Stack *stack, Card card) { + assert(stack->len < STACK_CAP); + stack->cards[stack->len++] = card; +} + +static inline Card pop(struct Stack *stack) { + if (!stack->len) return 0; + return stack->cards[--stack->len]; +} + +static inline Card peek(const struct Stack *stack) { + if (!stack->len) return 0; + return stack->cards[stack->len - 1]; +} + +static inline void flipTo(struct Stack *dst, struct Stack *src, Uint8 n) { + if (n > src->len) n = src->len; + for (Uint8 i = 0; i < n; ++i) { + push(dst, -pop(src)); + } +} + +static inline void moveTo(struct Stack *dst, struct Stack *src, Uint8 n) { + if (n > src->len) n = src->len; + for (Uint8 i = 0; i < n; ++i) { + push(dst, src->cards[src->len - n + i]); + } + src->len -= n; +} + +static inline int randUniform(int bound) { + for (;;) { + int r = rand(); + if (r >= RAND_MAX % bound) return r % bound; + } +} + +static inline void shuffle(struct Stack *stack) { + for (Uint8 i = stack->len - 1; i > 0; --i) { + Uint8 j = randUniform(i + 1); + Card x = stack->cards[i]; + stack->cards[i] = stack->cards[j]; + stack->cards[j] = x; + } +} + +#endif |