在學習ios開發的過程中,用一般的方式用oc寫了一個練練看的小游戲,沒有用到cocos2d編程.自己做的思路如下:
程序的關鍵在於判斷用戶連續點擊的兩個圖案能否消除。兩個圖片可以消除的條件有兩個:
(1) 圖案相同
(2) 圖案間連線的轉角數不得超過2
所以連通的算法分為:
(1) 直連型 (2) 一個拐角連通 (3) 兩個拐角連通
將圖片所在的view看為一個棋盤,然后根據棋盤的行列進行相關的判斷.
首先探討下直連型:分為水平直連(橫坐標相等)和豎直直連(縱坐標相等),且兩者之間沒有其他的圖案.
可以看出A -- B橫縱向連通,oc代碼如下:(dict是根據圖案的坐標,判斷該位置是否有圖案,有的話值為1,否則為0)
/** 1.直連型 */ - (BOOL)verticalWith:(CGPoint)pointA point:(CGPoint)pointB{ int rowA = [[NSString stringWithFormat:@"%f",pointA.x] intValue]; int colA = [[NSString stringWithFormat:@"%f",pointA.y] intValue]; int rowB = [[NSString stringWithFormat:@"%f",pointB.x] intValue]; int colB = [[NSString stringWithFormat:@"%f",pointB.y] intValue]; //1.直連型 if (rowA == rowB){//同一行 int minCol = colA < colB ? colA : colB;//最小列號 int maxCol = colA > colB ? colA : colB;//最大列號 for (int j = minCol+1; j<maxCol; j++) { CGPoint point = CGPointMake(rowA, j); NSString *key = NSStringFromCGPoint(point); if ([self.dict[key] intValue] != 0) {//兩個圖案之間存在其他的圖案 return NO; } } return YES; }else if(colA == colB){//同一列 int minRow = rowA < rowB ? rowA : rowB;//最小行號 int maxRow = rowA > rowB ? rowA : rowB;//最大行號 for (int i = minRow+1; i<maxRow; i++) { CGPoint point = CGPointMake(i, colA); NSString *key = NSStringFromCGPoint(point); if ([self.dict[key] intValue] != 0) {//兩個圖案之間存在其他的圖案 return NO; } } return YES; } else{ return NO; } }
2. 一折連通:其實相當於兩個圖片划出一個矩形,這兩個圖片是一對對角頂點,另外兩個頂點如果可以同時和這兩個棋子直連,那就說明可以"一折連通"。
找出C,D兩點,然后判斷C,D處是否有圖案,若存在圖案直接返回no.如果其中一個沒有,判斷與A,B是否連通
/** 2.一折型 */ - (BOOL)oneCorner:(CGPoint)pointA button:(CGPoint)pointB{ //找出拐角點的坐標 CGPoint pointC = CGPointMake(pointA.x, pointB.y); CGPoint pointD = CGPointMake(pointB.x, pointA.y); //判斷C點是否有元素 if ([self.dict[NSStringFromCGPoint(pointC)] intValue] == 0) { return [self verticalWith:pointA point:pointC] && [self verticalWith:pointC point:pointB]; } //判斷D點是否有元素 if ([self.dict[NSStringFromCGPoint(pointD)] intValue] == 0) { return [self verticalWith:pointA point:pointD] && [self verticalWith:pointD point:pointB]; } //其他情況 return NO; }
3 兩折連通:判斷圖案A與圖案B能否經過有兩個轉角的路徑連通,實質上可以轉化為判斷能否找到一個點C,這個C點與A可以直線連通,且C與B可以通過有一個轉角的路徑連通。若能找到這樣一個C點,那么A與B就可以經過有兩個轉角的路徑連通 。
判斷是否經兩個轉角連通的算法需要做兩個方向上的掃描:水平掃描和垂直掃描。
水平掃描。如下圖所示,為了判斷A,B能否通過2個轉角連通,則從A開始在水平方向上向左右掃描,並判斷經過的點能否與B點經過1個轉角連通。顯然C點能與B點經1個轉角連通,故A,B能經2個轉角連通。
垂直掃描。如下圖所示,為了判斷A,B能否通過2個轉角連通,則從A開始在垂直方向上下掃描,並判斷經過的點能否與B點經過1個轉角連通。顯然C點能與B點經1個轉角連通,故A,B能經2個轉角連通。
oc代碼:
/** 3.兩折型 */ /* 判斷A和B是否兩折連通 * (1) 水平方向: 從A水平方向左右掃描,並判斷經過的點能否與B通過1折連通; * (2) 垂直方向: 從A垂直方向上下掃描,並判斷經過的點能否與B通過1折連通; */ - (BOOL)twoCorner:(CGPoint)pointA button:(CGPoint)pointB maxRow:(int)maxRow maxCol:(int)maxCol{ //得到A點的所在行列 int rowA = [[NSString stringWithFormat:@"%f",pointA.x] intValue]; int colA = [[NSString stringWithFormat:@"%f",pointA.y] intValue]; //初始化C點 CGPoint pointC = CGPointMake(0, 0); // 1. 水平方向(列) // 1.1 左 if (colA != 0){//A點不在最左邊 for (int i = colA - 1; i >= 0; i--) { pointC = CGPointMake(rowA, i); //判斷C點是否為空 if ([self.dict[NSStringFromCGPoint(pointC)] intValue] == 0) { if ([self oneCorner:pointC button:pointB]){ return YES; } }else{//不為空的話,直接跳出 break; } } } // 1.2 右 if (colA != maxCol - 1){//A點不在最右邊 for (int i = colA + 1; i < maxCol; i++) { pointC = CGPointMake(rowA, i); //判斷C點是否為空 if ([self.dict[NSStringFromCGPoint(pointC)] intValue] == 0) { if ([self oneCorner:pointC button:pointB]){ return YES; } }else{//不為空的話,直接跳出 break; } } } // 2. 垂直方向(行) // 2.1 上 if (rowA != 0){//A點不在最上邊 for (int i = rowA - 1; i >= 0; i--) { pointC = CGPointMake(i, colA); //判斷C點是否為空 if ([self.dict[NSStringFromCGPoint(pointC)] intValue] == 0) { if ([self oneCorner:pointC button:pointB]){ return YES; } }else{//不為空的話,直接跳出 break; } } } // 2.2 下 if (rowA != maxRow - 1){//A點不在最下邊 for (int i = rowA + 1; i < maxRow; i++) { pointC = CGPointMake(i, colA); //判斷C點是否為空 if ([self.dict[NSStringFromCGPoint(pointC)] intValue] == 0) { if ([self oneCorner:pointC button:pointB]){ return YES; } }else{//不為空的話,直接跳出 break; } } } //其他情況 return NO; }
總的調用函數來調用:
/** 1.直連型 */ if ([self verticalWith:pointA point:pointB]) {//是否存在直線,存在返回yes //連接成功 return YES; } /** 2.一折型 */ if([self oneCorner:pointA button:pointB]){ return YES; }else{ /** 3.兩折型 */ return [self twoCorner:pointA button:pointB maxRow:rowCount maxCol:columnCount]; }