2011-02-06 05:44:45 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2010-04-04 00:44:59 +00:00
|
|
|
#include <stdbool.h>
|
2011-02-06 05:44:45 +00:00
|
|
|
#include <malloc.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
2010-04-04 00:44:59 +00:00
|
|
|
#include "stack.h"
|
|
|
|
|
2011-02-06 06:45:53 +00:00
|
|
|
static bool maneuvre_stack(struct stack *stack) {
|
|
|
|
return(stack->card->frame->start_y >= MANEUVRE_STACKS_STARTING_Y);
|
|
|
|
}
|
|
|
|
|
2010-04-05 07:33:10 +00:00
|
|
|
void allocate_stack(struct stack **stack) {
|
2011-02-06 05:44:45 +00:00
|
|
|
if (!(*stack = malloc(sizeof(**stack)))) {
|
|
|
|
fprintf(stderr, "%s: %s (%s:%d)\n", program_name, strerror(errno), __FILE__, __LINE__ - 1);
|
|
|
|
exit(errno);
|
|
|
|
}
|
2010-04-04 00:44:59 +00:00
|
|
|
|
2010-04-05 07:33:10 +00:00
|
|
|
allocate_card(&((*stack)->card));
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void initialize_stack(struct stack *stack) {
|
2010-04-09 03:37:57 +00:00
|
|
|
initialize_card(stack->card);
|
2010-04-05 07:33:10 +00:00
|
|
|
stack->next = NULL;
|
2010-04-04 00:44:59 +00:00
|
|
|
|
2010-04-04 23:52:02 +00:00
|
|
|
return;
|
2010-04-04 00:44:59 +00:00
|
|
|
}
|
|
|
|
|
2011-02-14 02:10:47 +00:00
|
|
|
void free_stack(struct stack *stack) {
|
2011-02-14 02:04:26 +00:00
|
|
|
struct stack *tmp_stack;
|
|
|
|
|
2011-02-14 02:05:54 +00:00
|
|
|
while (stack) {
|
|
|
|
tmp_stack = stack->next;
|
2011-02-14 02:10:47 +00:00
|
|
|
free_card(stack->card);
|
2011-02-14 02:05:54 +00:00
|
|
|
free(stack);
|
|
|
|
stack = tmp_stack;
|
2011-02-12 03:26:03 +00:00
|
|
|
}
|
2010-04-07 00:59:21 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-04-04 00:44:59 +00:00
|
|
|
bool empty(struct stack *stack) {
|
2011-02-14 01:13:00 +00:00
|
|
|
return(stack->card->value == NO_VALUE &&
|
|
|
|
stack->card->suit == NO_SUIT &&
|
|
|
|
stack->card->face == NO_FACE &&
|
|
|
|
!stack->next);
|
2010-04-04 00:44:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int length(struct stack *stack) {
|
2010-04-04 03:51:14 +00:00
|
|
|
struct stack *iterator = stack;
|
2010-04-04 00:44:59 +00:00
|
|
|
int length = 0;
|
|
|
|
|
|
|
|
if (!empty(stack)) {
|
|
|
|
length = 1;
|
2010-04-04 03:51:14 +00:00
|
|
|
while (iterator->next != NULL) {
|
2010-04-04 00:44:59 +00:00
|
|
|
length++;
|
2010-04-04 03:51:14 +00:00
|
|
|
iterator = iterator->next;
|
2010-04-04 00:44:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return(length);
|
|
|
|
}
|
|
|
|
|
2010-04-04 06:20:56 +00:00
|
|
|
void push(struct stack **stack, struct card *card) {
|
2010-04-04 00:44:59 +00:00
|
|
|
struct stack *new_stack = NULL;
|
|
|
|
|
2011-02-14 01:13:00 +00:00
|
|
|
if (card) {
|
|
|
|
if (empty(*stack)) {
|
|
|
|
(*stack)->card = card;
|
|
|
|
} else {
|
|
|
|
allocate_stack(&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
|
|
|
|
2010-04-04 07:15:43 +00:00
|
|
|
struct stack *pop(struct stack **stack) {
|
2010-04-04 01:12:42 +00:00
|
|
|
struct stack *popped_entry = NULL;
|
|
|
|
|
2010-04-04 07:15:43 +00:00
|
|
|
if(!empty(*stack)) {
|
|
|
|
popped_entry = *stack;
|
2011-02-14 01:13:00 +00:00
|
|
|
/* As what's considered an empty stack is an allocated and initialized
|
|
|
|
* stack structure, we make sure pop doesn't make '*stack' point to NULL
|
|
|
|
* when popping a stack with only 1 element. */
|
2010-04-04 23:52:02 +00:00
|
|
|
if (length(*stack) == 1) {
|
2010-04-05 07:33:10 +00:00
|
|
|
allocate_stack(stack);
|
|
|
|
initialize_stack(*stack);
|
2011-02-14 01:13:00 +00:00
|
|
|
set_frame((*stack)->card->frame,
|
|
|
|
(*stack)->card->frame->start_y,
|
|
|
|
(*stack)->card->frame->start_x);
|
2010-04-04 23:52:02 +00:00
|
|
|
} else {
|
|
|
|
*stack = (*stack)->next;
|
|
|
|
}
|
2010-04-04 07:15:43 +00:00
|
|
|
popped_entry->next = NULL;
|
2010-04-04 01:12:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return(popped_entry);
|
|
|
|
}
|
2010-04-09 03:49:17 +00:00
|
|
|
|
|
|
|
void move_card(struct stack **origin, struct stack **destination) {
|
|
|
|
struct stack *stack = NULL;
|
|
|
|
|
2011-02-10 01:51:07 +00:00
|
|
|
(*origin)->card->frame->start_x = (*destination)->card->frame->start_x;
|
|
|
|
(*origin)->card->frame->start_y = (*destination)->card->frame->start_y;
|
|
|
|
if (!empty(*destination) && maneuvre_stack(*destination)) {
|
|
|
|
(*origin)->card->frame->start_y++;
|
|
|
|
}
|
2011-02-14 01:13:00 +00:00
|
|
|
if ((stack = pop(origin))) {
|
|
|
|
push(destination, stack->card);
|
|
|
|
}
|
2010-04-09 03:49:17 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|