tty-solitaire/src/stack.c

127 lines
3.2 KiB
C
Raw Normal View History

#include <stdio.h>
#include <stdlib.h>
2010-04-04 00:44:59 +00:00
#include <stdbool.h>
#include <errno.h>
2011-06-03 05:48:26 +00:00
2010-04-04 00:44:59 +00:00
#include "stack.h"
2011-06-03 05:48:26 +00:00
#include "card.h"
2011-05-08 23:38:36 +00:00
#include "common.h"
2010-04-04 00:44:59 +00:00
void stack_malloc(struct stack **stack) {
if (!(*stack = malloc(sizeof(**stack)))) {
2011-06-19 22:36:29 +00:00
tty_solitaire_generic_error(errno, __FILE__, __LINE__);
}
card_malloc(&((*stack)->card));
}
void stack_init(struct stack *stack) {
card_init(stack->card);
stack->next = NULL;
2010-04-04 00:44:59 +00:00
}
void stack_free(struct stack *stack) {
2011-06-03 05:48:26 +00:00
struct stack *tmp;
for (; stack; stack = tmp) {
tmp = stack->next;
card_free(stack->card);
2011-06-03 05:48:26 +00:00
free(stack);
}
}
struct stack *stack_dup(struct stack *stack) {
2011-05-01 06:06:43 +00:00
struct stack *iterator = stack;
struct stack *tmp_stack, *new_stack;
stack_malloc(&new_stack);
stack_malloc(&tmp_stack);
stack_init(new_stack);
stack_init(tmp_stack);
2011-05-01 06:06:43 +00:00
for (iterator = stack; iterator; iterator = iterator->next) {
stack_push(&tmp_stack, card_dup(iterator->card));
2011-05-01 06:06:43 +00:00
}
while (!stack_empty(tmp_stack)) {
stack_push(&new_stack, (stack_pop(&tmp_stack)));
2011-05-01 06:06:43 +00:00
}
stack_free(tmp_stack);
2011-05-01 06:06:43 +00:00
return(new_stack);
}
bool stack_empty(struct stack *stack) {
return(stack->card->value == NO_VALUE &&
2011-05-31 05:45:11 +00:00
stack->card->suit == NO_SUIT &&
stack->card->face == NO_FACE &&
!stack->next);
2010-04-04 00:44:59 +00:00
}
int stack_length(struct stack *stack) {
int stack_length = 0;
2010-04-04 00:44:59 +00:00
if (!stack_empty(stack)) {
for (stack_length = 1; stack->next; stack = stack->next, stack_length++)
;
2010-04-04 00:44:59 +00:00
}
return(stack_length);
2010-04-04 00:44:59 +00:00
}
void stack_push(struct stack **stack, struct card *card) {
if (card) {
if (stack_empty(*stack)) {
card_free((*stack)->card);
(*stack)->card = card;
} else {
/* Allocating by hand because stack_malloc() would
2011-05-31 05:45:11 +00:00
* have allocated an unwanted card object. */
struct stack *new_stack = malloc(sizeof(*new_stack));
new_stack->card = card;
new_stack->next = (*stack);
*stack = new_stack;
}
2010-04-04 00:44:59 +00:00
}
}
2010-04-04 01:12:42 +00:00
struct card *stack_pop(struct stack **stack) {
if(stack_empty(*stack)) {
return(NULL);
} else {
struct card *popped_card = (*stack)->card;
if (stack_length(*stack) == 1) {
/* Remembering the stack position before clearing it. */
int begin_y = (*stack)->card->frame->begin_y;
int begin_x = (*stack)->card->frame->begin_x;
card_malloc(&((*stack)->card));
/* An stack_empty stack is a stack with a blank top card
* and with stack->next == NULL. */
card_set((*stack)->card, NO_VALUE, NO_SUIT, NO_FACE, begin_y, begin_x);
(*stack)->next = NULL;
} else {
struct stack *tmp = *stack;
*stack = (*stack)->next;
free(tmp);
}
return(popped_card);
2010-04-04 01:12:42 +00:00
}
}
2011-05-01 01:13:41 +00:00
struct stack *stack_reverse(struct stack *stack) {
2011-06-03 05:48:26 +00:00
struct stack *tmp_stack, *iterator;
2011-05-01 01:13:41 +00:00
stack_malloc(&tmp_stack);
stack_init(tmp_stack);
if (stack_length(stack) > 1) {
for (iterator = stack; iterator; iterator = iterator->next) {
stack_push(&tmp_stack, card_dup(iterator->card));
2011-05-01 01:13:41 +00:00
}
} else {
card_set(tmp_stack->card,
2011-06-03 05:48:26 +00:00
stack->card->value,
stack->card->suit,
stack->card->face,
stack->card->frame->begin_y,
stack->card->frame->begin_x);
2011-05-01 01:13:41 +00:00
}
2011-06-03 05:48:26 +00:00
return(tmp_stack);
2011-05-01 01:13:41 +00:00
}