Created
August 16, 2023 06:30
-
-
Save zbowling/1834eab638693566298677444521d832 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// HCLevelModel.h | |
// HamsterCrunch | |
// | |
// Created by Zac Bowling on 2/25/12. | |
// Copyright (c) 2012 __MyCompanyName__. All rights reserved. | |
// | |
#import <Foundation/Foundation.h> | |
@class HCActorModel; | |
@class HCFinishLineModel; | |
@interface HCLevelModel : NSObject | |
#pragma mark View building property | |
- (id)initWithLevelSize:(CGSize)size columnCount:(NSInteger)columnCount; | |
@property (strong, nonatomic) NSMutableSet *wordModels; | |
@property (strong, nonatomic) NSMutableSet *rockModels; | |
@property (strong, nonatomic) HCActorModel *actorModel; | |
@property (assign, nonatomic) HCFinishLineModel *finishLineModel; | |
@property (assign, nonatomic) CGSize size; | |
@property (assign, nonatomic) CGFloat crunchLevel; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// HCLevelModel.m | |
// HamsterCrunch | |
// | |
// Created by Zac Bowling on 2/25/12. | |
// Copyright (c) 2012 __MyCompanyName__. All rights reserved. | |
// | |
#import "HCLevelModel.h" | |
#import "HCWordModel.h" | |
#import "HCActorModel.h" | |
#import "HCWordBuilder.h" | |
#import "HCRockModel.h" | |
static BOOL shouldShowTutorial = YES; | |
#define NUM_SAFE_ROWS 5 | |
#define TUTORIAL_PADDING 3 | |
@interface HCLevelModel() | |
- (void)_populateWords; | |
@end | |
@implementation HCLevelModel { | |
HCWordBuilder* wordProvider; | |
NSUInteger cellDimension; | |
NSInteger _columnCount; | |
} | |
@synthesize actorModel=_actorModel; | |
@synthesize crunchLevel=_crunchLevel; | |
@synthesize finishLineModel=_finishLineModel; | |
@synthesize wordModels=_wordModels; | |
@synthesize size=_size; | |
@synthesize rockModels=_rockModels; | |
- (id)initWithLevelSize:(CGSize)size columnCount:(NSInteger)columnCount { | |
self = [super init]; | |
if (self) { | |
_columnCount = columnCount; | |
_size = size; | |
cellDimension = size.width / columnCount; | |
wordProvider = [HCWordBuilder defaultWordBuilder]; | |
_wordModels = [[NSMutableSet alloc] init]; | |
_rockModels = [[NSMutableSet alloc] init]; | |
self.actorModel = [[HCActorModel alloc] init]; | |
[self _populateWords]; | |
} | |
return self; | |
} | |
- (NSUInteger)_pickWordLength | |
{ | |
return 3 + arc4random() % 5; | |
} | |
- (CGRect)_frameForPosition:(CGPoint)pt | |
withLength:(NSUInteger)numCells | |
isVertical:(BOOL)vertical | |
{ | |
return CGRectMake(pt.x * cellDimension, | |
pt.y * cellDimension, | |
vertical ? cellDimension : cellDimension * numCells, | |
vertical ? cellDimension * numCells : cellDimension); | |
} | |
- (void)_populateWords | |
{ | |
NSUInteger numSafeRows = NUM_SAFE_ROWS + (shouldShowTutorial ? TUTORIAL_PADDING : 0); | |
NSUInteger rowCount = _size.height / cellDimension; | |
NSMutableArray *wordList = [NSMutableArray array]; | |
NSMutableArray *rockList = [NSMutableArray array]; | |
NSInteger i=0,j=0,x=0,y=0; | |
__block int **cells = malloc(sizeof(int *)*_columnCount); | |
for(i = 0; i < _columnCount; i++) { | |
cells[i] = malloc(sizeof(int)*rowCount); | |
for (int j = 0; j < rowCount; j++){ | |
cells[i][j] = -1; | |
} | |
} | |
NSUInteger totalCellCount = rowCount * _columnCount; | |
NSUInteger remainderCellCount = totalCellCount; | |
NSUInteger wordLen; | |
NSUInteger numCells; | |
HCWordModel * word; | |
BOOL (^isPointSafe)(NSUInteger, NSUInteger, NSUInteger, BOOL) = ^(NSUInteger x, NSUInteger y, NSUInteger numCells, BOOL vertical){ | |
NSUInteger i = x, j = y, k = 0; | |
for (k = 0; k < numCells; k++){ | |
if (i >= _columnCount || j >= rowCount || cells[i][j] != -1){ | |
return NO; | |
} | |
if (vertical){ | |
j++; | |
} else { | |
i++; | |
} | |
} | |
return YES; | |
}; | |
__block NSUInteger (^longestSafeSequence)(NSUInteger, NSUInteger, BOOL *) = ^(NSUInteger x, NSUInteger y, BOOL *vertical){ | |
NSUInteger i = x, j = y, k = 0, numCells = 0; | |
NSLog(@"Longest Safe Sequence"); | |
for (k = 0; k < 6; k++){ | |
if (i >= _columnCount || j >= rowCount || cells[i][j] != -1){ | |
if (*vertical || numCells > 1){ | |
return numCells; | |
} else { | |
*vertical = YES; | |
return longestSafeSequence(x,y,vertical); | |
} | |
} | |
numCells++; | |
if (*vertical){ | |
j++; | |
} else { | |
i++; | |
} | |
} | |
return numCells; | |
}; | |
void (^markSpotTaken)(NSUInteger,NSUInteger, NSUInteger, BOOL, NSUInteger) = ^(NSUInteger x, NSUInteger y, NSUInteger wordLen, BOOL vertical, NSUInteger wordIndex){ | |
NSUInteger i = x, j = y, k = 0; | |
//NSLog(@"Starting To Mark Spot Taken! %d %d %d [Range: %d %d]",i,j,wordIndex, cells.size(), cells[i].size()); | |
for (k = 0; k < wordLen; k++){ | |
//NSLog(@"Marking Spot Taken! %d %d %d",i,j,wordIndex); | |
cells[i][j] = wordIndex; | |
if (vertical){ | |
j++; | |
} else { | |
i++; | |
} | |
} | |
}; | |
NSUInteger (^numCellsForLength)(NSUInteger wordLen) = ^(NSUInteger wordLen){ | |
return (NSUInteger)ceil(wordLen / 2.5); | |
}; | |
if (shouldShowTutorial){ | |
//shouldShowTutorial = NO; | |
#define Say(word,len)\ | |
markSpotTaken(curCol,curRow,len,NO,[wordList count]);\ | |
[wordList addObject:[[HCWordModel alloc] initWithWord: @"" #word \ | |
frame: [self _frameForPosition: CGPointMake(curCol,curRow)\ | |
withLength: len\ | |
isVertical: NO]\ | |
isVertical: NO]];\ | |
curCol += len; | |
#define Space \ | |
markSpotTaken(curCol,curRow,1,NO,[wordList count]);\ | |
(curCol++) | |
NSUInteger curCol = 0, curRow = NUM_SAFE_ROWS; | |
Say(Type, 2); | |
Space; | |
Say(these, 2); | |
Space; | |
Say(words, 2); | |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) { | |
curRow++; | |
curCol = 1; | |
} else { | |
Space; | |
} | |
Say(to,1); | |
Space; | |
Say(start,1); | |
Space; | |
Say(playing,3); | |
} | |
#define ShouldBeVertical (numCells > 1 && isVertical) | |
BOOL isVertical = YES; | |
NSUInteger failures = 0; | |
NSUInteger numVerticals = totalCellCount * .30; | |
for (i = 0; i < numVerticals; ) { | |
wordLen = [self _pickWordLength]; | |
numCells = numCellsForLength(wordLen); | |
x = arc4random() % _columnCount; | |
y = arc4random() % (rowCount - numCells - numSafeRows) + numSafeRows; | |
if (!isPointSafe(x,y,numCells,isVertical)){ | |
NSLog(@"Failed to pack vertical block, trying again"); | |
if (++failures < 40){ | |
continue; | |
} else { | |
NSLog(@"Failed to pack too many vertical blocks, aborting"); | |
failures = 0; | |
break; | |
} | |
} | |
markSpotTaken(x,y,numCells,isVertical,[wordList count]); | |
i += numCells; | |
if (arc4random()%7 == 0) { | |
HCRockModel *rock = [[HCRockModel alloc] initWithFrame:[self _frameForPosition: CGPointMake(x,y) | |
withLength: numCells | |
isVertical: ShouldBeVertical]]; | |
[rockList addObject:rock]; | |
} | |
else { | |
NSLog(@"%@ word length %d number of cells: %d",isVertical?@"Vertical":@"Horizontal",wordLen,numCells); | |
word = [[HCWordModel alloc] initWithWord: [wordProvider wordForLength:wordLen+1] | |
frame: [self _frameForPosition: CGPointMake(x,y) | |
withLength: numCells | |
isVertical: ShouldBeVertical] | |
isVertical: ShouldBeVertical]; | |
[wordList addObject:word]; | |
} | |
} | |
remainderCellCount -= i; | |
isVertical = NO; | |
NSUInteger numHorizontals = remainderCellCount * .40; | |
for (i = 0; i < numHorizontals; ) { | |
wordLen = [self _pickWordLength]; | |
numCells = numCellsForLength(wordLen); | |
x = arc4random() % (_columnCount - numCells); | |
y = arc4random() % (rowCount - numCells - numSafeRows) + numSafeRows; | |
if (!isPointSafe(x,y,numCells,isVertical)){ | |
NSLog(@"Failed to pack horizontal block, trying again"); | |
if (++failures < 40){ | |
continue; | |
} else { | |
NSLog(@"Failed to pack too many vertical blocks, aborting"); | |
failures = 0; | |
break; | |
} | |
} | |
markSpotTaken(x,y,numCells,isVertical,[wordList count]); | |
i += numCells; | |
if (arc4random()%6 == 0) { | |
HCRockModel *rock = [[HCRockModel alloc] initWithFrame:[self _frameForPosition: CGPointMake(x,y) | |
withLength: numCells | |
isVertical: ShouldBeVertical]]; | |
[rockList addObject:rock]; | |
} | |
else { | |
NSLog(@"%@ word length %d number of cells: %d",isVertical?@"Vertical":@"Horizontal",wordLen,numCells); | |
word = [[HCWordModel alloc] initWithWord: [wordProvider wordForLength:wordLen] | |
frame: [self _frameForPosition: CGPointMake(x,y) | |
withLength: numCells | |
isVertical: ShouldBeVertical] | |
isVertical: ShouldBeVertical]; | |
[wordList addObject:word]; | |
} | |
} | |
remainderCellCount -= i; | |
isVertical = NO; | |
NSLog(@"Taken Map"); | |
NSMutableString *rowStr; | |
/** | |
* Now iteratively search for open cells, and then figure out if they have an | |
* open cell next to them, and accumulate word sizes that way. | |
*/ | |
for (j = numSafeRows; j < rowCount; j++) { | |
rowStr = [[NSMutableString alloc] init]; | |
for (i = 0; i < _columnCount; i++) { | |
[rowStr appendFormat:@"%d ",cells[i][j]]; | |
isVertical = NO; | |
if (cells[i][j] == -1) { | |
wordLen = longestSafeSequence(i,j,&isVertical); | |
numCells = numCellsForLength(wordLen); | |
markSpotTaken(i,j,numCells,isVertical,[wordList count]); | |
//NSLog(@"%d",cells[i][j]); | |
if (arc4random()%5 == 0) { | |
HCRockModel *rock = [[HCRockModel alloc] initWithFrame:[self _frameForPosition: CGPointMake(i,j) | |
withLength: numCells | |
isVertical: ShouldBeVertical]]; | |
[rockList addObject:rock]; | |
} | |
else { | |
//NSLog(@"%@ word length %d number of cells: %d",isVertical?@"Vertical":@"Horizontal",wordLen,numCells); | |
word = [[HCWordModel alloc] initWithWord: [wordProvider wordForLength:wordLen] | |
frame: [self _frameForPosition: CGPointMake(i,j) | |
withLength: numCells | |
isVertical: ShouldBeVertical] | |
isVertical: ShouldBeVertical]; | |
[wordList addObject:word]; | |
} | |
} | |
} | |
NSLog(@"%d:\t%@",j,rowStr); | |
} | |
for(i = 0; i < _columnCount; i++) { | |
free(cells[i]); | |
} | |
free(cells); | |
self.rockModels = [NSMutableSet setWithArray:rockList]; | |
self.wordModels = [NSMutableSet setWithArray:wordList]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment