/* $Id: pile.c,v 1.3 2002/03/02 21:02:21 sverrehu Exp $ */ /************************************************************************** * * FILE pile.c * MODULE OF Card game. * * WRITTEN BY Sverre H. Huseby * **************************************************************************/ #include #include #include #include #include #include "pile.h" /************************************************************************** * * * P U B L I C F U N C T I O N S * * * **************************************************************************/ Pile * pileNew(void) { Pile *p; p = xmalloc(sizeof(Pile)); p->x = p->y = 0; p->maxWidth = CARD_WIDTH; p->maxHeight = CARD_HEIGHT; p->dx = p->dy = 0; p->deltaEach = 1; p->outline = -1; p->numCards = 0; p->bottom = p->top = NULL; return p; } void pileDelete(Pile *p) { pileRemoveAllCards(p); free(p); } /* before==NULL, insert at top. */ void pileInsertCardBefore(Pile *p, Card *c, Card *before) { Card *target; if (c->pile) pileRemoveCard(c->pile, c); c->pile = p; if (!before) { c->next = NULL; c->prev = p->top; if (p->top) p->top->next = c; else p->bottom = c; p->top = c; } else { target = p->top; while (target && target != before) target = target->prev; if (target != before) msgFatal("internal error in pileInsertCardBefore\n"); c->prev = target->prev; if (c->prev == NULL) p->bottom = c; else c->prev->next = c; target->prev = c; c->next = target; } ++(p->numCards); } void pileAddCardBottom(Pile *p, Card *c) { pileInsertCardBefore(p, c, p->bottom); } void pileAddCardTop(Pile *p, Card *c) { pileInsertCardBefore(p, c, NULL); } void pileInsertPileBefore(Pile *p, Pile *ip, Card *before) { msgFatal("pileInsertPileBefore() isn't implemented\n"); } void pileAddPileBottom(Pile *p, Pile *ap) { msgFatal("pileAddPileBottom() isn't implemented\n"); } void pileAddPileTop(Pile *p, Pile *ap) { Card *c; while ((c = ap->bottom) != NULL) { pileRemoveCard(ap, c); pileAddCardTop(p, c); } } void pileRemoveCard(Pile *p, Card *c) { if (p != c->pile) msgFatal("internal error in pileRemoveCard\n"); c->pile = NULL; if (c->prev) c->prev->next = c->next; else p->bottom = c->next; if (c->next) c->next->prev = c->prev; else p->top = c->prev; --(p->numCards); c->prev = c->next = NULL; } void pileRemoveAllCards(Pile *p) { while (p->numCards) pileRemoveCard(p, p->bottom); } Pile * pileMoveToNewPileFromCard(Pile *p, Card *c) { Pile *ret; Card *cc; if (p != c->pile) msgFatal("internal error in pileMoveToNewPileFromCard\n"); ret = pileNew(); cc = p->top; for (;;) { pileRemoveCard(p, cc); pileAddCardBottom(ret, cc); if (cc == c) break; cc = p->top; } ret->x = p->x; ret->y = p->y; ret->maxWidth = p->maxWidth; ret->maxHeight = p->maxHeight; ret->dx = p->dx; ret->dy = p->dy; ret->deltaEach = p->deltaEach; ret->outline = p->outline; return ret; }