1 /* $Id: pile.c,v 1.3 2002/03/02 21:02:21 sverrehu Exp $ */
2 /**************************************************************************
3 *
4 * FILE pile.c
5 * MODULE OF Card game.
6 *
7 * WRITTEN BY Sverre H. Huseby <shh@thathost.com>
8 *
9 **************************************************************************/
10
11 #include <stdlib.h>
12 #include <stdio.h>
13
14 #include <shhmsg.h>
15 #include <xalloc.h>
16 #include <shhcards.h>
17
18 #include "pile.h"
19
20 /**************************************************************************
21 * *
22 * P U B L I C F U N C T I O N S *
23 * *
24 **************************************************************************/
25
26 Pile *
pileNew(void)27 pileNew(void)
28 {
29 Pile *p;
30
31 p = xmalloc(sizeof(Pile));
32 p->x = p->y = 0;
33 p->maxWidth = CARD_WIDTH;
34 p->maxHeight = CARD_HEIGHT;
35 p->dx = p->dy = 0;
36 p->deltaEach = 1;
37 p->outline = -1;
38 p->numCards = 0;
39 p->bottom = p->top = NULL;
40 return p;
41 }
42
43 void
pileDelete(Pile * p)44 pileDelete(Pile *p)
45 {
46 pileRemoveAllCards(p);
47 free(p);
48 }
49
50 /* before==NULL, insert at top. */
51 void
pileInsertCardBefore(Pile * p,Card * c,Card * before)52 pileInsertCardBefore(Pile *p, Card *c, Card *before)
53 {
54 Card *target;
55
56 if (c->pile)
57 pileRemoveCard(c->pile, c);
58 c->pile = p;
59 if (!before) {
60 c->next = NULL;
61 c->prev = p->top;
62 if (p->top)
63 p->top->next = c;
64 else
65 p->bottom = c;
66 p->top = c;
67 } else {
68 target = p->top;
69 while (target && target != before)
70 target = target->prev;
71 if (target != before)
72 msgFatal("internal error in pileInsertCardBefore\n");
73 c->prev = target->prev;
74 if (c->prev == NULL)
75 p->bottom = c;
76 else
77 c->prev->next = c;
78 target->prev = c;
79 c->next = target;
80 }
81 ++(p->numCards);
82 }
83
84 void
pileAddCardBottom(Pile * p,Card * c)85 pileAddCardBottom(Pile *p, Card *c)
86 {
87 pileInsertCardBefore(p, c, p->bottom);
88 }
89
90 void
pileAddCardTop(Pile * p,Card * c)91 pileAddCardTop(Pile *p, Card *c)
92 {
93 pileInsertCardBefore(p, c, NULL);
94 }
95
96 void
pileInsertPileBefore(Pile * p,Pile * ip,Card * before)97 pileInsertPileBefore(Pile *p, Pile *ip, Card *before)
98 {
99 msgFatal("pileInsertPileBefore() isn't implemented\n");
100 }
101
102 void
pileAddPileBottom(Pile * p,Pile * ap)103 pileAddPileBottom(Pile *p, Pile *ap)
104 {
105 msgFatal("pileAddPileBottom() isn't implemented\n");
106 }
107
108 void
pileAddPileTop(Pile * p,Pile * ap)109 pileAddPileTop(Pile *p, Pile *ap)
110 {
111 Card *c;
112
113 while ((c = ap->bottom) != NULL) {
114 pileRemoveCard(ap, c);
115 pileAddCardTop(p, c);
116 }
117 }
118
119 void
pileRemoveCard(Pile * p,Card * c)120 pileRemoveCard(Pile *p, Card *c)
121 {
122 if (p != c->pile)
123 msgFatal("internal error in pileRemoveCard\n");
124 c->pile = NULL;
125 if (c->prev)
126 c->prev->next = c->next;
127 else
128 p->bottom = c->next;
129 if (c->next)
130 c->next->prev = c->prev;
131 else
132 p->top = c->prev;
133 --(p->numCards);
134 c->prev = c->next = NULL;
135 }
136
137 void
pileRemoveAllCards(Pile * p)138 pileRemoveAllCards(Pile *p)
139 {
140 while (p->numCards)
141 pileRemoveCard(p, p->bottom);
142 }
143
144 Pile *
pileMoveToNewPileFromCard(Pile * p,Card * c)145 pileMoveToNewPileFromCard(Pile *p, Card *c)
146 {
147 Pile *ret;
148 Card *cc;
149
150 if (p != c->pile)
151 msgFatal("internal error in pileMoveToNewPileFromCard\n");
152 ret = pileNew();
153 cc = p->top;
154 for (;;) {
155 pileRemoveCard(p, cc);
156 pileAddCardBottom(ret, cc);
157 if (cc == c)
158 break;
159 cc = p->top;
160 }
161 ret->x = p->x;
162 ret->y = p->y;
163 ret->maxWidth = p->maxWidth;
164 ret->maxHeight = p->maxHeight;
165 ret->dx = p->dx;
166 ret->dy = p->dy;
167 ret->deltaEach = p->deltaEach;
168 ret->outline = p->outline;
169 return ret;
170 }
171