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.