iOS 小游戲-連連看-算法(三)

元素的坐標(biāo)來自二維數(shù)組的 i,j。而通過 i,j 可以取到元素類型


數(shù)據(jù)圖.png

前面講連通方式分三種:直連,一折連,二折連

直連:
直連.png

從圖中可以看出規(guī)律,直連的兩個元素,同行或同列( i相等 或者 j相等 ) ,把 i、j轉(zhuǎn)換成坐標(biāo) point 就是 point(i, j)

直連邏輯方法如下:

 * 直連
 * pointA:點(diǎn)擊的其中一個元素
 * pointB:點(diǎn)擊的另一個元素
 * data:數(shù)據(jù)圖
 */
+ (BOOL)oneConnectionWithCGPoint:(CGPoint)pointA pointB:(CGPoint)pointB data:(NSMutableArray *)data{
    //如果同行
    NSInteger minValue = -1;
    NSInteger maxValue = -1;
    //同行
    if (pointA.x == pointB.x) {
        //相鄰
        if (fabs(pointA.y - pointB.y) == 1) {
            return YES;
        }
        //判斷哪個值大小
        if (pointA.y > pointB.y) {
            minValue = pointB.y;
            maxValue = pointA.y;
        }
        else{
            maxValue = pointB.y;
            minValue = pointA.y;
        }
        //遍歷數(shù)據(jù)minValue 與 maxValue 之間的數(shù)值 如果為0代表通路 否則有阻礙
        if (pointA.x > data.count) {
            return NO;
        }
        NSMutableArray *list = data[(NSInteger)pointA.x];
        for (NSInteger i = minValue + 1; i < maxValue; i++){
            NSNumber *number = list[I];
            if ([number integerValue] != 0) {
                return NO;
            }
        }
    }
    //同列
    else if (pointA.y == pointB.y){
        //相鄰
        if (fabs(pointA.x - pointB.x) == 1) {
            return YES;
        }
        //判斷哪個值大小
        if (pointA.x > pointB.x) {
            minValue = pointB.x;
            maxValue = pointA.x;
        }
        else{
            maxValue = pointB.x;
            minValue = pointA.x;
        }
        //遍歷數(shù)據(jù)minValue 與 maxValue 之間的數(shù)值 如果為0代表通路 否則有阻礙
        if (pointA.y > data.count) {
            return NO;
        }
        for (NSInteger i = minValue + 1; i < maxValue; i++){
            NSMutableArray *list = data[I];
            NSNumber *number = list[(NSInteger)pointA.y];
            if ([number integerValue] != 0) {
                return NO;
            }
        }
    }
    else{
        return NO;
    }
    return YES;
}

直連邏輯做了以下幾件事

1.判斷是同行還是同列( x 相等還是 y 相等)
2.如果同行,判斷兩個元素的 y 差值是不是為1,為1證明挨著,可以連成功
3.如果同行,判斷兩個元素之間,是否有元素在,如果有(不等于0),則有其他元素存在,連不成功。如果沒有,則沒有任何元素存在,就是通路,連成功
4.同列的話差不多的邏輯

一折連:
一折連.png

從圖中可以看出規(guī)律:
0:拐點(diǎn)就是圖中的直角點(diǎn),比如我從1連到1,必然要轉(zhuǎn)彎,轉(zhuǎn)彎的點(diǎn)就是拐點(diǎn)
1:如果為一折連的話,必有兩個拐點(diǎn)。
2:如果一折連連成功的話,兩個拐點(diǎn)必有一個拐點(diǎn)是0,也就是沒有圖片占據(jù)。
那么試想一下,如果我點(diǎn)擊兩個元素A1和B1(也就是上圖的兩個1),然后取它們的兩個拐點(diǎn)p1和 p2,然后將它們分別與A1和B1進(jìn)行 直連,如果兩個拐點(diǎn)有一個成功,那么A1和 B1是不是就算連成功了?答案:是的

一折連邏輯方法如下:

/**
* 一折連
* pointA:點(diǎn)擊的其中一個元素
* pointB:點(diǎn)擊的另一個元素
* data:數(shù)據(jù)圖
*/
+(BOOL)twoConnectionWithCGPoint:(CGPoint)pointA pointB:(CGPoint)pointB data:(NSMutableArray *)data{
    CGPoint point1 = CGPointMake(pointA.x, pointB.y);//取第一個拐點(diǎn)
    CGPoint point2 = CGPointMake(pointB.x, pointA.y);//取第二個拐點(diǎn)
    NSArray *list = data[(NSInteger)point1.x];
    NSNumber *number = list[(NSInteger)point1.y];
    if ([number integerValue] == 0) {//判斷第一個拐點(diǎn)的位置是不是通路(通路為0)
        //拿到拐點(diǎn)分別和要進(jìn)行一折連的兩個點(diǎn) 進(jìn)行直連判斷 如果都能直連 可以一折連
        BOOL flagA = [self oneConnectionWithCGPoint:point1 pointB:pointB data:data];
        BOOL flagB = [self oneConnectionWithCGPoint:point1 pointB:pointA data:data];
        if (flagA && flagB){
            NSLog(@"拐點(diǎn):%@", NSStringFromCGPoint(point1));
            NSLog(@"pointA : %@", NSStringFromCGPoint(pointA));
            NSLog(@"pointB : %@", NSStringFromCGPoint(pointB));
            return YES;
        }
    }
    
    list = data[(NSInteger)point2.x];
    number = list[(NSInteger)point2.y];
    if ([number integerValue] == 0) {//判斷第二個拐點(diǎn)的位置是不是通路(通路為0)
        //拿到拐點(diǎn)分別和要進(jìn)行一折連的兩個點(diǎn) 進(jìn)行直連判斷 如果都能直連 可以一折連
        BOOL flagA = [self oneConnectionWithCGPoint:point2 pointB:pointB data:data];
        BOOL flagB = [self oneConnectionWithCGPoint:point2 pointB:pointA data:data];
        if (flagA && flagB){
            NSLog(@"%@", NSStringFromCGPoint(point2));
            NSLog(@"pointA : %@", NSStringFromCGPoint(pointA));
            NSLog(@"pointB : %@", NSStringFromCGPoint(pointB));
            return YES;
        }
    }
    return NO;
}

一折連邏輯做了以下幾件事

1.取 A 的 x 及 B 的 y成第一個拐點(diǎn)
2.取 B 的 x 及 A 的 y成第二個拐點(diǎn)
3.分別拿兩個拐點(diǎn)和 A、B 進(jìn)行直連

二折連:
二折連.png

上面一折連跟直連產(chǎn)生了關(guān)系,那么二折連也是一樣的邏輯。遍歷其中一個點(diǎn) A 上、下、左、右的所有點(diǎn)只要與另一個點(diǎn) B 連一折連連成功,就算二折連成功

**
* 兩折連
* pointA:點(diǎn)擊的其中一個元素
* pointB:點(diǎn)擊的另一個元素
* data:數(shù)據(jù)圖
*/
+(BOOL)thirdConnectionWithCGPoint:(CGPoint)pointA pointB:(CGPoint)pointB data:(NSMutableArray *)data{
    NSInteger row = data.count;
    NSInteger col = [[data lastObject] count];
    //左
    for (NSInteger i = pointA.y - 1; i >= 0; i--) {
        NSArray *list = data[(NSInteger)pointA.x];
        NSNumber *number = list[i];
        if ([number integerValue] != 0) {
            break;
        }
        BOOL flag = [self twoConnectionWithCGPoint:CGPointMake(pointA.x, i) pointB:pointB data:data];
        if (flag) {
            return flag;
        }
    }
    //右
    for (NSInteger i = pointA.y + 1; i < col; i++) {
        NSArray *list = data[(NSInteger)pointA.x];
        NSNumber *number = list[i];
        if ([number integerValue] != 0) {
            break;
        }
        BOOL flag = [self twoConnectionWithCGPoint:CGPointMake(pointA.x, i) pointB:pointB data:data];
        if (flag) {
            return flag;
        }
    }
    //上
    for (NSInteger i = pointA.x - 1; i >= 0; i--) {
        NSArray *list = data[i];
        NSNumber *number = list[(NSInteger)pointA.y];
        if ([number integerValue] != 0) {
            break;
        }
        BOOL flag = [self twoConnectionWithCGPoint:CGPointMake(i, pointA.y) pointB:pointB data:data];
        if (flag) {
            return flag;
        }
    }
    //下
    for (NSInteger i = pointA.x + 1; i < row; i++) {
        NSArray *list = data[i];
        NSNumber *number = list[(NSInteger)pointA.y];
        if ([number integerValue] != 0) {
            break;
        }
        BOOL flag = [self twoConnectionWithCGPoint:CGPointMake(i, pointA.y) pointB:pointB data:data];
        if (flag) {
            return flag;
        }
    }
    return NO;
}

最后附上demo地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容