/* Copyright (C) 2019 C. McEnroe * * 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 . */ #ifndef STACK_H #define STACK_H #include #include #include #include "cards.h" #ifndef STACK_CAP #define STACK_CAP 52 #endif typedef Sint8 Card; static int cardSuit(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 int cardColor(Card card) { return cardSuit(card) == Cards_Diamond || cardSuit(card) == Cards_Heart; } static int cardRank(Card card) { return abs(card) - cardSuit(card); } struct Stack { Uint8 len; Card cards[STACK_CAP]; }; static inline void stackClear(struct Stack *stack) { stack->len = 0; } static inline void stackPush(struct Stack *stack, Card card) { assert(stack->len < STACK_CAP); stack->cards[stack->len++] = card; } static inline Card stackPop(struct Stack *stack) { if (!stack->len) return 0; return stack->cards[--stack->len]; } static inline Card stackTop(const struct Stack *stack) { if (!stack->len) return 0; return stack->cards[stack->len - 1]; } static inline void stackFlipTo(struct Stack *dst, struct Stack *src, Uint8 n) { if (n > src->len) n = src->len; for (Uint8 i = 0; i < n; ++i) { stackPush(dst, -stackPop(src)); } } static inline void stackMoveTo(struct Stack *dst, struct Stack *src, Uint8 n) { if (n > src->len) n = src->len; for (Uint8 i = 0; i < n; ++i) { stackPush(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 stackShuffle(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