I have a MxN matrix of tile (string of 1 length basically a,b,c,d,e......). I want to arrange this matrix in a specific manner :-
There are numbers of set which are used to set neighbors of sibling tiles. No more then sets should be neighbors of siblings.
Rest of tiles (i.e (MxN)-(2*sets) ) should be placed randomly but not neighbors of sibling.
Neighbors of sibling could only be Left (-1) or Right (+1) or Up (-M) or Down (+M). (from current index of tile).
I have made an algorithm for it (although its not good ) with few goto statements and one recursive method. But it didn't working as i expected. Here is my Code.
-(NSMutableArray*)shufflePuzzle:(NSArray*)aPuzzle ForDangerTilesSets:(int)sets
{
NSMutableArray *tempPuzzle=[[NSMutableArray alloc]initWithArray: [aPuzzle copy]];
NSMutableArray *tempShuffleArray=[[NSMutableArray alloc]init];
NSMutableArray *indexArray=[[NSMutableArray alloc]init];
for (int i=0; i<TileInX*TileInY; i++)
{
[tempShuffleArray addObject:[NSNull null]];
[indexArray addObject:[NSNumber numberWithInt:i]];
}
for (int i=0; i<sets; i++)
{
int index=0;
restart:
index=arc4random()%(tempPuzzle.count);
int tileIndex=[[indexArray objectAtIndex:index] intValue];
NSString *tile=[aPuzzle objectAtIndex:tileIndex];
NSLog(@"TEMPPUZZLE remove sibling at index %d from array which counts %d",tileIndex,(int)tempPuzzle.count);
[tempPuzzle removeObjectAtIndex:index];
NSLog(@"TEMPPUZZLE OBJECT REMOVED");
if (![tempPuzzle containsObject:tile]) {
[tempPuzzle insertObject:tile atIndex:index];
NSLog(@"restart");
goto restart;
}
else
{
[indexArray removeObject:[NSNumber numberWithInt:tileIndex]];
int tileSecondIndex=(int)[tempPuzzle indexOfObject:tile];
NSLog(@"remove sibling at index %d from array which counts %d",tileSecondIndex,(int)tempPuzzle.count);
[tempPuzzle removeObjectAtIndex:tileSecondIndex];
NSLog(@"Removed :-D");
BOOL isSiblingAdded=[self checkSiblingOfTile:tile atIndex:tileIndex forPuzzle:tempShuffleArray andIndexes:indexArray];
if (!isSiblingAdded) {
NSLog(@"callback 1");
return [self shufflePuzzle:aPuzzle ForDangerTilesSets:sets];
}
}
}
NSLog(@"all sibling found");
int count=0;
for (int i=0; i<[[indexArray copy] count]; i++)
{
NSString *tile;
siblingMatched:
tile=[aPuzzle objectAtIndex:i];
int tempIndex=arc4random()%(indexArray.count);
int index=[[indexArray objectAtIndex:tempIndex] intValue];
BOOL check=[self checkSiblingOfTile:tile atIndex:index forPuzzle:tempShuffleArray];
if (check) {
if (count==5) {
NSLog(@"callback 2");
return [self shufflePuzzle:aPuzzle ForDangerTilesSets:sets];
}
count++;
NSLog(@"sibling matched %d",count);
goto siblingMatched;
}
else
{
NSLog(@"remove tile at index %d from array which counts %d",index,(int)tempPuzzle.count);
[tempShuffleArray replaceObjectAtIndex:index withObject:tile];
[indexArray removeObject:[NSNumber numberWithInt:index]];
NSLog(@"Removed 1 :-D");
[tempPuzzle removeObject:tile];
NSLog(@"Removed 2 :-D");
}
}
if ([tempShuffleArray containsObject:[NSNull null]]) {
NSLog(@"%@",indexArray);
NSLog(@"callback 3");
return [self shufflePuzzle:aPuzzle ForDangerTilesSets:sets];
}
return tempShuffleArray;
}
-(BOOL)checkSiblingOfTile:(NSString*)aTile atIndex:(int)aIndex forPuzzle:(NSMutableArray*)puzzle
{
int row=aIndex/TileInX;
int column=aIndex%TileInY;
//left
if (column!=0) {
if ([[puzzle objectAtIndex:aIndex-1] isEqual:aTile]) {
return YES;
}
}
//right
if (column<TileInX-1) {
if ([[puzzle objectAtIndex:aIndex+1] isEqual:aTile]) {
return YES;
}
}
//up
if (row!=0) {
if ([[puzzle objectAtIndex:aIndex-TileInX] isEqual:aTile]) {
return YES;
}
}
//down
if (row<TileInY-1) {
if ([[puzzle objectAtIndex:aIndex+TileInX] isEqual:aTile]) {
return YES;
}
}
NSLog(@"no sibling for tile %@ at index %d",aTile,aIndex);
return NO;
}
-(BOOL)checkSiblingOfTile:(NSString*)aTile atIndex:(int)aIndex forPuzzle:(NSMutableArray*)puzzle andIndexes:(NSMutableArray*)indexArray
{
int row=aIndex/TileInX;
int column=aIndex%TileInY;
NSMutableArray *siblings=[[NSMutableArray alloc]init];
//left
if (column!=0) {
[self addSiblingForTile:aTile atIndex:aIndex-1 inArray:siblings forPuzzle:puzzle];
}
//right
if (column<TileInX-1) {
[self addSiblingForTile:aTile atIndex:aIndex+1 inArray:siblings forPuzzle:puzzle];
}
//up
if (row!=0) {
[self addSiblingForTile:aTile atIndex:aIndex-TileInX inArray:siblings forPuzzle:puzzle];
}
//down
if (row<TileInY-1) {
[self addSiblingForTile:aTile atIndex:aIndex+TileInX inArray:siblings forPuzzle:puzzle];
}
NSLog(@"siblings %@ of tile %@",siblings,aTile);
if (siblings.count!=0)
{
int sibIndex=arc4random()%(siblings.count);
int aSibling=[[siblings objectAtIndex:sibIndex] intValue];
[indexArray removeObject:[NSNumber numberWithInt:aSibling]];
[puzzle replaceObjectAtIndex:aSibling withObject:aTile];
[puzzle replaceObjectAtIndex:aIndex withObject:aTile];
NSLog(@"sibling set");
return YES;
}
NSLog(@"sibling not set");
return NO;
}
-(void)addSiblingForTile:(NSString*)aTile atIndex:(int)sibIndex inArray:(NSMutableArray*)sibArray forPuzzle:(NSArray*)aPuzzle
{
if ([[aPuzzle objectAtIndex:sibIndex] isEqual:[NSNull null]])
{
[sibArray addObject:[NSNumber numberWithInt:sibIndex]];
}
}
it having problem at [tempShuffleArray containsObject:[NSNull null]] mostly and going in a deadlock.
Help me to fix it. Any help will be appreciated. Thanks.
My current Puzzle is [a,a,a,a,b,b,b,b,c]. Neighbor Sets are 2. tileInX=3 and tileInY=3 (M=3 and N=3).
Aucun commentaire:
Enregistrer un commentaire