lundi 2 février 2015

Shuffle M x n tiles in specific manner

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