This is Deck.m in view mode; [Download] [Up]
#import "Deck.h"
#import "Card.h"
#import "Random.h"
#import <appkit/nextstd.h>
#import <appkit/Panel.h>
#import <limits.h>
/* External Function Declarations */
static Random *ranGen; /* returns a random number */
extern char *re_comp(char *s);
#define Notify(title, msg) NXRunAlertPanel(title, msg, "OK", NULL, NULL)
#define NotifyArg(title, msg, arg)\
NXRunAlertPanel(title, msg, "OK", NULL, NULL, arg)
#define MARKED (marker != DECK_UNMARKED)
#define MARK_OR_NE (MARKED ? marker : numElements)
#define copyIds(From, To, N) bcopy(From, To, sizeof(id) * N)
static int qcomp(a, b)
id *a, *b;
{
return[*a compare:*b];
}
BOOL regexString(char *expr)
{
char *result = re_comp(expr);
if (result) {
Notify("Find", result);
return NO;
}
return YES;
}
@implementation Deck
/* Creating and freeing a Deck object */
+ new
{
self = [self newCount:8];
marker = DECK_UNMARKED;
return self;
}
+ initialize
{
[self setVersion:DECK_VERSION];
ranGen = [Random new];
return self;
}
- copy /* Kludge since List is broken (reported) */
{
id newDeck = [[self class] newCount:numElements];
copyIds(dataPtr, newDeck->dataPtr, numElements);
newDeck->numElements = numElements;
newDeck->marker = marker;
return newDeck;
}
/* Marker Manipulation */
- setMarkerAtEnd
{
return[self setMarkerAt:numElements];
}
- setMarkerAt:(unsigned)index
{
marker = MIN(index, numElements);
return self;
}
- (unsigned)marker
{
return marker;
}
- clearMarker
{
marker = DECK_UNMARKED;
return self;
}
/* draw and discard */
- giveCard
{
return[self giveCardAt:0];
}
- giveCardAt:(unsigned)index
{
if (index >= MARK_OR_NE)
return nil;
if (MARKED)
--marker;
return[self removeObjectAt:index];
}
- takeCard:anObject
{
return[self addObject:anObject];
}
/* Manipulate Deck */
- (unsigned)dealTo:(List *) handList
{
return[self dealTo:handList each:numElements];
}
- (unsigned)dealTo:(List *) handList each:(int)numCards
{
int hands = [handList count];
int c, h;
if (hands * numCards > numElements)
numCards = numElements / hands;
for (c = 0; c < numCards; c++)
for (h = 0; h < hands; h++)
[NX_ADDRESS(handList)[h] takeCard:[self giveCard]];
return (marker = numElements);
}
- emptyTo:(Deck *) hand
{
id card;
while (card = [self giveCard])
[hand takeCard:card];
return self;
}
- cutAt:(unsigned)index
{
id *copyPtr, *copyIndex;
id *dataEnd, *dataIndex;
if (index < 0 || index > MARK_OR_NE)
return nil;
NX_MALLOC(copyPtr, id, numElements);
copyIds(dataPtr, copyPtr, numElements);
copyIds(copyPtr + index, dataPtr, numElements - index);
copyIds(copyPtr, dataPtr + (numElements - index), index);
NX_FREE(copyPtr);
[self setMarkerAtEnd];
return self;
}
static void mixup(id * aPtr, id * bPtr, int n)
{
id *aIndex, *bIndex, *bEnd;
int i;
bIndex = bPtr + n; /* Fill in Backwards */
bEnd = bPtr + (n / 5); /* Mix 80% of indices */
[ranGen scaleFrom:0 to:n];
while (bIndex > bEnd) { /* Pull in at Random */
while (aPtr[i = [ranGen whole]] == nil);
*(--bIndex) = aPtr[i];
aPtr[i] = nil;
}
aIndex = aPtr - 1;
while (bIndex > bPtr) { /* Get rest */
while (*(++aIndex) == nil);
*(--bIndex) = *aIndex;
}
}
- shuffle:sender
{
id *copyPtr, *copyEnd;
[self setMarkerAtEnd];
NX_MALLOC(copyPtr, id, numElements);
mixup(dataPtr, copyPtr, numElements);
mixup(copyPtr, dataPtr, numElements);
NX_FREE(copyPtr);
return self;
}
- sort:sender
{
[self setMarkerAtEnd];
qsort(dataPtr, numElements, sizeof(id), qcomp);
return self;
}
- flipAll:sender
{
id *dataIndex, *dataEnd;
dataEnd = dataPtr + numElements;
for (dataIndex = dataPtr; dataIndex < dataEnd; ++dataIndex)
[*dataIndex flip];
return self;
}
- reverse:sender
{
id *copyPtr, *copyIndex;
id *dataIndex;
[self setMarkerAtEnd];
NX_MALLOC(copyPtr, id, numElements);
copyIds(dataPtr, copyPtr, numElements);
dataIndex = dataPtr + numElements; /* Fill in Backwards */
copyIndex = copyPtr;
while (dataIndex > dataPtr) /* Get rest */
*(--dataIndex) = *(copyIndex++);
NX_FREE(copyPtr);
return self;
}
- findSTR:(const char *) aString
{
id *dataIndex, *dataEnd;
dataEnd = dataPtr + numElements;
if (regexString(aString))
for (dataIndex = dataPtr; dataIndex < dataEnd; ++dataIndex)
if ([*dataIndex findSTR:aString])
return *dataIndex;
return nil;
}
- findAllSTR:(const char *) aString
{
id *dataIndex, *dataEnd;
id list;
dataEnd = dataPtr + numElements;
list = [List new];
if (regexString(aString))
for (dataIndex = dataPtr; dataIndex < dataEnd; ++dataIndex)
if ([*dataIndex findSTR:aString])
[list addObject:*dataIndex];
if ([list count])
return list;
else
return nil;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.