先上效果圖
- 功能展示
- 初高級(jí)棋盤切換效果
實(shí)現(xiàn)思路及主要代碼詳解
1.繪制棋盤
利用quartz2d繪制棋盤.代碼如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
- ( void )drawbackground:(cgsize)size{ self.gridwidth = (size.width - 2 * kboardspace) / self.gridcount; //1.開啟圖像上下文 uigraphicsbeginimagecontext(size); //2.獲取上下文 cgcontextref ctx = uigraphicsgetcurrentcontext(); cgcontextsetlinewidth(ctx, 0.8f); //3.1 畫16條豎線 for ( int i = 0; i <= self.gridcount; i ++) { cgcontextmovetopoint(ctx, kboardspace + i * self.gridwidth , kboardspace); cgcontextaddlinetopoint(ctx, kboardspace + i * self.gridwidth , kboardspace + self.gridcount * self.gridwidth); } //3.1 畫16條橫線 for ( int i = 0; i <= self.gridcount; i ++) { cgcontextmovetopoint(ctx, kboardspace, kboardspace + i * self.gridwidth ); cgcontextaddlinetopoint(ctx, kboardspace + self.gridcount * self.gridwidth , kboardspace + i * self.gridwidth); } cgcontextstrokepath(ctx); //4.獲取生成的圖片 uiimage *image=uigraphicsgetimagefromcurrentimagecontext(); //5.顯示生成的圖片到imageview uiimageview * imageview = [[uiimageview alloc]initwithimage:image]; [self addsubview:imageview]; uigraphicsendimagecontext(); } |
2.點(diǎn)擊棋盤落子
1)根據(jù)落子位置求出該棋子的行號(hào)與列號(hào).
2)判斷落子位置是否已經(jīng)有棋子,有則不能下.如果沒有,將棋子保存在字典中,以列號(hào)和行號(hào)組合起來的字符串為key值.
代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
//點(diǎn)擊棋盤,下棋 - ( void )tapboard:(uitapgesturerecognizer *)tap{ cgpoint point = [tap locationinview:tap.view]; //計(jì)算下子的列號(hào)行號(hào) nsinteger col = (point.x - kboardspace + 0.5 * self.gridwidth) / self.gridwidth; nsinteger row = (point.y - kboardspace + 0.5 * self.gridwidth) / self.gridwidth; nsstring * key = [nsstring stringwithformat:@ "%ld-%ld" ,col,row]; if (![self.chessmandict.allkeys containsobject:key]) { uiview * chessman = [self chessman]; chessman.center = cgpointmake(kboardspace + col * self.gridwidth, kboardspace + row * self.gridwidth); [self addsubview:chessman]; [self.chessmandict setvalue:chessman forkey:key]; self.lastkey = key; //檢查游戲結(jié)果 [self checkresult:col androw:row andcolor:self.isblack]; self.isblack = !self.isblack; } } |
3.檢測(cè)游戲結(jié)果
每落一個(gè)棋子就要多游戲結(jié)果進(jìn)行一次檢查,判斷四個(gè)方向上是否有大于等于5個(gè)同色的棋子連成一線,有則提示游戲輸贏結(jié)果,無則游戲繼續(xù).算法為,從當(dāng)前棋子位置向前遍歷,直到遇到與自己不同色的棋子,累加同色棋子的個(gè)數(shù),再往后遍歷,直到遇到與自己不同色的棋子,累加同色棋子的個(gè)數(shù).得到該方向相連同色棋子的總個(gè)數(shù)
代碼如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
//判斷是否大于等于五個(gè)同色相連 - ( bool )checkresult:(nsinteger)col androw:(nsinteger)row andcolor:( bool )isblack anddirection:(gmkdirection)direction{ if (self.samechessmanarray.count >= 5) { return yes; } uicolor * currentchessmancolor = [self.chessmandict[[nsstring stringwithformat:@ "%ld-%ld" ,col,row]] backgroundcolor]; [self.samechessmanarray addobject:self.chessmandict[self.lastkey]]; switch (direction) { //水平方向檢查結(jié)果 case gmkhorizontal:{ //向前遍歷 for (nsinteger i = col - 1; i > 0; i --) { nsstring * key = [nsstring stringwithformat:@ "%ld-%ld" ,i,row]; if (![self.chessmandict.allkeys containsobject:key] || [self.chessmandict[key] backgroundcolor] != currentchessmancolor) break ; [self.samechessmanarray addobject:self.chessmandict[key]]; } //向后遍歷 for (nsinteger i = col + 1; i < kgridcount; i ++) { nsstring * key = [nsstring stringwithformat:@ "%ld-%ld" ,i,row]; if (![self.chessmandict.allkeys containsobject:key] || [self.chessmandict[key] backgroundcolor] != currentchessmancolor) break ; [self.samechessmanarray addobject:self.chessmandict[key]]; } if (self.samechessmanarray.count >= 5) { [self alertresult]; return yes; } [self.samechessmanarray removeallobjects]; } break ; case gmkvertical:{ //向前遍歷 for (nsinteger i = row - 1; i > 0; i --) { nsstring * key = [nsstring stringwithformat:@ "%ld-%ld" ,col,i]; if (![self.chessmandict.allkeys containsobject:key] || [self.chessmandict[key] backgroundcolor] != currentchessmancolor) break ; [self.samechessmanarray addobject:self.chessmandict[key]]; } //向后遍歷 for (nsinteger i = row + 1; i < kgridcount; i ++) { nsstring * key = [nsstring stringwithformat:@ "%ld-%ld" ,col,i]; if (![self.chessmandict.allkeys containsobject:key] || [self.chessmandict[key] backgroundcolor] != currentchessmancolor) break ; [self.samechessmanarray addobject:self.chessmandict[key]]; } if (self.samechessmanarray.count >= 5) { [self alertresult]; return yes; } [self.samechessmanarray removeallobjects]; } break ; case gmkobliquedown:{ //向前遍歷 nsinteger j = col - 1; for (nsinteger i = row - 1; i >= 0; i--,j--) { nsstring * key = [nsstring stringwithformat:@ "%ld-%ld" ,j,i]; if (![self.chessmandict.allkeys containsobject:key] || [self.chessmandict[key] backgroundcolor] != currentchessmancolor || j < 0) break ; [self.samechessmanarray addobject:self.chessmandict[key]]; } //向后遍歷 j = col + 1; for (nsinteger i = row + 1 ; i < kgridcount; i++,j++) { nsstring * key = [nsstring stringwithformat:@ "%ld-%ld" ,j,i]; if (![self.chessmandict.allkeys containsobject:key] || [self.chessmandict[key] backgroundcolor] != currentchessmancolor || j > kgridcount) break ; [self.samechessmanarray addobject:self.chessmandict[key]]; } if (self.samechessmanarray.count >= 5) { [self alertresult]; return yes; } [self.samechessmanarray removeallobjects]; } break ; case gmkobliqueup:{ //向前遍歷 nsinteger j = col + 1; for (nsinteger i = row - 1; i >= 0; i--,j++) { nsstring * key = [nsstring stringwithformat:@ "%ld-%ld" ,j,i]; if (![self.chessmandict.allkeys containsobject:key] || [self.chessmandict[key] backgroundcolor] != currentchessmancolor || j > kgridcount) break ; [self.samechessmanarray addobject:self.chessmandict[key]]; } //向后遍歷 j = col - 1; for (nsinteger i = row + 1 ; i < kgridcount; i++,j--) { nsstring * key = [nsstring stringwithformat:@ "%ld-%ld" ,j,i]; if (![self.chessmandict.allkeys containsobject:key] || [self.chessmandict[key] backgroundcolor] != currentchessmancolor || j < 0) break ; [self.samechessmanarray addobject:self.chessmandict[key]]; } if (self.samechessmanarray.count >= 5) { [self alertresult]; return yes; } [self.samechessmanarray removeallobjects]; } break ; } return no; } |
對(duì)外提供,重新開始,悔棋,切換初高級(jí)棋盤的三個(gè)接口
重新開始
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
- ( void )newgame{ self.isover = no; self.lastkey = nil; [self.samechessmanarray removeallobjects]; self.userinteractionenabled = yes; [self.chessmandict removeallobjects]; for (uiview * view in self.subviews) { if ([view iskindofclass:[uiimageview class ]]) { continue ; } [view removefromsuperview]; } self.isblack = no; } |
悔棋
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
//撤回至上一步棋 - ( void )backonestep:(uibutton *)sender{ if (self.isover) return ; if (self.lastkey == nil) { sender.enabled = no; cgfloat width = screen_width * 0.4 * screen_width_ratio; uiview * tip = [[uiview alloc]initwithframe:cgrectmake(0, 0, width, 0.6 * width)]; tip.backgroundcolor = [uicolor colorwithwhite:1 alpha:0.8]; tip.layer.cornerradius = 8.0f; [self addsubview:tip]; tip.center = cgpointmake(self.width * 0.5, self.height * 0.5); uilabel * label = [[uilabel alloc]init]; label.text = self.chessmandict.count > 0 ? @ "只能悔一步棋!!!" : @ "請(qǐng)先落子!!!" ; label.font = [uifont systemfontofsize:15]; [label sizetofit]; label.center = cgpointmake(tip.width * 0.5, tip.height * 0.5); [tip addsubview:label]; self.userinteractionenabled = no; dispatch_after(dispatch_time(dispatch_time_now, (int64_t)(2.0 * nsec_per_sec)), dispatch_get_main_queue(), ^{ self.userinteractionenabled = yes; sender.enabled = yes; [tip removefromsuperview]; }); return ; } [self.chessmandict removeobjectforkey:self.lastkey]; [self.subviews.lastobject removefromsuperview]; self.isblack = !self.isblack; self.lastkey = nil; } |
切換初高級(jí)鍵盤
1
2
3
4
5
6
7
8
9
10
|
//改變鍵盤級(jí)別 - ( void )changeboardlevel{ for (uiview * view in self.subviews) { [view removefromsuperview]; } [self newgame]; self.ishighlevel = !self.ishighlevel; [self drawbackground:self.bounds.size]; } |
demo中的一個(gè)小技巧
用字典存放棋子,以棋子的列號(hào)和行號(hào)組合起來的字符串為key值,value值為棋子view.這樣處理,在判斷某行某列是否有棋子就非常簡單了。
總結(jié)
以上就是ios游戲開發(fā)之五子棋oc版的全部內(nèi)容,希望本文對(duì)大家開發(fā)ios有所幫助,如果本文有不足之處,歡迎大家提供建議和指點(diǎn)!