This is Country.m in view mode; [Download] [Up]
// // This file is a part of Risk by Mike Ferris. // #import "Risk.h" RCSID ("$Id: Country.m,v 1.2 1997/12/15 07:43:46 nygard Exp $"); #import "Country.h" #import "CountryShape.h" #import "NSObjectExtensions.h" #import "RiskMapView.h" #define Country_VERSION 2 DEFINE_NSSTRING (CountryUpdatedNotification); @implementation Country + (void) initialize { if (self == [Country class]) { [self setVersion:Country_VERSION]; } } //---------------------------------------------------------------------- - initWithCountryName:(NSString *)aName continentName:(NSString *)aContinentName shape:(CountryShape *)aCountryShape continent:(RiskContinent)aContinent { if ([super init] == nil) return nil; name = [aName retain]; countryShape = [aCountryShape retain]; continentName = [aContinentName retain]; neighborCountries = [[NSMutableSet set] retain];; playerNumber = 0; troopCount = 0; unmovableTroopCount = 0; return self; } //---------------------------------------------------------------------- - (void) dealloc { SNRelease (name); SNRelease (continentName); SNRelease (countryShape); SNRelease (neighborCountries); [super dealloc]; } //---------------------------------------------------------------------- - (void) encodeWithCoder:(NSCoder *)aCoder { [super encodeWithCoder:aCoder]; [aCoder encodeObject:name]; [aCoder encodeObject:countryShape]; [aCoder encodeObject:continentName]; // World will encode neighbors [aCoder encodeValueOfObjCType:@encode (int) at:&playerNumber]; [aCoder encodeValueOfObjCType:@encode (int) at:&troopCount]; [aCoder encodeValueOfObjCType:@encode (int) at:&unmovableTroopCount]; } //---------------------------------------------------------------------- - initWithCoder:(NSCoder *)aDecoder { if ([super initWithCoder:aDecoder] == nil) return nil; name = [[aDecoder decodeObject] retain]; countryShape = [[aDecoder decodeObject] retain]; continentName = [[aDecoder decodeObject] retain]; neighborCountries = [[NSMutableSet set] retain];; [aDecoder decodeValueOfObjCType:@encode (int) at:&playerNumber]; [aDecoder decodeValueOfObjCType:@encode (int) at:&troopCount]; [aDecoder decodeValueOfObjCType:@encode (int) at:&unmovableTroopCount]; return self; } //---------------------------------------------------------------------- - (NSString *) countryName { return name; } //---------------------------------------------------------------------- - (CountryShape *) countryShape { return countryShape; } //---------------------------------------------------------------------- - (NSString *) continentName { return continentName; } //---------------------------------------------------------------------- - (NSSet *) neighborCountries { return neighborCountries; } //---------------------------------------------------------------------- - (void) setAdjacentToCountry:(Country *)aCountry { [neighborCountries addObject:aCountry]; } //---------------------------------------------------------------------- - (void) resetAdjacentCountries { [neighborCountries removeAllObjects]; } //---------------------------------------------------------------------- - (BOOL) isAdjacentToCountry:(Country *)aCountry { return [neighborCountries containsObject:aCountry]; } //---------------------------------------------------------------------- - (BOOL) bordersAnotherContinent { NSEnumerator *countryEnumerator; Country *country; BOOL flag; flag = NO; countryEnumerator = [neighborCountries objectEnumerator]; while (country = [countryEnumerator nextObject]) { if ([[country continentName] isEqualToString:continentName] == NO) { flag = YES; break; } } return flag; } //---------------------------------------------------------------------- - (void) drawInView:(RiskMapView *)aView isSelected:(BOOL)selected { if (countryShape != nil) { [countryShape drawWithCountry:self inView:aView isSelected:selected]; } } //---------------------------------------------------------------------- - (BOOL) pointInCountry:(NSPoint)aPoint { return [countryShape pointInShape:aPoint]; } //---------------------------------------------------------------------- - (NSString *) description { return [NSString stringWithFormat:@"%@", name]; } //---------------------------------------------------------------------- // Army methods //---------------------------------------------------------------------- - (Player) playerNumber { return playerNumber; } //---------------------------------------------------------------------- - (int) troopCount { return troopCount; } //---------------------------------------------------------------------- - (int) movableTroopCount { return troopCount - unmovableTroopCount; } //---------------------------------------------------------------------- - (void) setPlayerNumber:(Player)aPlayerNumber { playerNumber = aPlayerNumber; // These need to be reset when a country is captured. troopCount = 0; unmovableTroopCount = 0; [self update]; } //---------------------------------------------------------------------- - (void) setTroopCount:(int)count { troopCount = count; [self update]; #if 0 if (troopCount < 0) troopCount = 0; #endif } //---------------------------------------------------------------------- - (void) addTroops:(int)count { troopCount += count; [self update]; #if 0 if (troopCount < 0) troopCount = 0; #endif } //---------------------------------------------------------------------- // We need to keep track of the unmovable troops (the troops that have // already been fortified), otherwise under the "fortify many to many // neighbors" rule, you could march the armies up to the front one // country at a time. //---------------------------------------------------------------------- - (int) unmovableTroopCount { return unmovableTroopCount; } //---------------------------------------------------------------------- - (void) addUnmovableTroopCount:(int)count { unmovableTroopCount += count; NSAssert (unmovableTroopCount <= troopCount, @"Too many unmovable troops!"); } //---------------------------------------------------------------------- - (void) resetUnmovableTroops { unmovableTroopCount = 0; } //---------------------------------------------------------------------- - (void) update { [[NSNotificationCenter defaultCenter] postNotificationName:CountryUpdatedNotification object:self]; } //====================================================================== // Useful methods: //====================================================================== - (NSSet *) connectedCountries { NSMutableSet *connectedSet, *greySet, *tmpSet; Country *current; connectedSet = [NSMutableSet set]; greySet = [NSMutableSet setWithObject:self]; while (current = [greySet anyObject]) { [greySet removeObject:current]; [connectedSet addObject:current]; // Now, add neighbors: tmpSet = [NSMutableSet setWithSet:[current neighborCountries]]; [tmpSet minusSet:connectedSet]; [greySet unionSet:tmpSet]; } return connectedSet; } //---------------------------------------------------------------------- - (NSSet *) ourNeighborCountries { NSMutableSet *ourNeighborCountries; NSEnumerator *countryEnumerator; Country *country; ourNeighborCountries = [NSMutableSet set]; countryEnumerator = [[self neighborCountries] objectEnumerator]; while (country = [countryEnumerator nextObject]) { if ([country playerNumber] == playerNumber) [ourNeighborCountries addObject:country]; } return ourNeighborCountries; } //---------------------------------------------------------------------- - (NSSet *) ourConnectedCountries { NSMutableSet *connectedSet, *greySet, *tmpSet; Country *current; connectedSet = [NSMutableSet set]; greySet = [NSMutableSet setWithObject:self]; while (current = [greySet anyObject]) { [greySet removeObject:current]; [connectedSet addObject:current]; // Now, add neighbors: tmpSet = [NSMutableSet setWithSet:[current ourNeighborCountries]]; [tmpSet minusSet:connectedSet]; [greySet unionSet:tmpSet]; } return connectedSet; } //---------------------------------------------------------------------- - (NSSet *) enemyNeighborCountries { NSMutableSet *enemyNeighborCountries; NSEnumerator *countryEnumerator; Country *country; enemyNeighborCountries = [NSMutableSet set]; countryEnumerator = [[self neighborCountries] objectEnumerator]; while (country = [countryEnumerator nextObject]) { if ([country playerNumber] != playerNumber) [enemyNeighborCountries addObject:country]; } return enemyNeighborCountries; } //---------------------------------------------------------------------- - (int) enemyNeighborTroopCount { NSEnumerator *countryEnumerator; Country *country; int count; count = 0; countryEnumerator = [[self enemyNeighborCountries] objectEnumerator]; while (country = [countryEnumerator nextObject]) { count += [country troopCount]; } return count; } //---------------------------------------------------------------------- - (int) ourNeighborTroopCount { NSEnumerator *countryEnumerator; Country *country; int count; count = 0; countryEnumerator = [[self ourNeighborCountries] objectEnumerator]; while (country = [countryEnumerator nextObject]) { count += [country troopCount]; } return count; } //====================================================================== // Useful, somewhat optimized methods: //====================================================================== - (BOOL) hasEnemyNeighbors { NSEnumerator *countryEnumerator; Country *country; BOOL flag; flag = NO; countryEnumerator = [neighborCountries objectEnumerator]; while (country = [countryEnumerator nextObject]) { if ([country playerNumber] != playerNumber) { flag = YES; break; } } return flag; } //---------------------------------------------------------------------- - (BOOL) hasFriendlyNeighborsWithEnemyNeighbors { NSEnumerator *countryEnumerator; Country *country; BOOL flag; flag = NO; countryEnumerator = [[self ourNeighborCountries] objectEnumerator]; while (country = [countryEnumerator nextObject]) { if ([country hasEnemyNeighbors] == YES) { flag = YES; break; } } return flag; } //---------------------------------------------------------------------- - (BOOL) hasTroops { return troopCount > 0; } //---------------------------------------------------------------------- - (BOOL) hasMobileTroops { return [self movableTroopCount] > 0; } //---------------------------------------------------------------------- - (BOOL) surroundedByPlayerNumber:(Player)number { NSEnumerator *countryEnumerator; Country *country; BOOL flag; flag = YES; countryEnumerator = [[self neighborCountries] objectEnumerator]; while (country = [countryEnumerator nextObject]) { if ([country playerNumber] != number) { flag = NO; break; } } return flag; } //---------------------------------------------------------------------- - (BOOL) hasEnemyNeighborsExcludingCountry:(Country *)excludedCountry { NSEnumerator *countryEnumerator; Country *country; BOOL flag; flag = NO; countryEnumerator = [neighborCountries objectEnumerator]; while (country = [countryEnumerator nextObject]) { if (country != excludedCountry && [country playerNumber] != playerNumber) { flag = YES; break; } } return flag; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.