一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - IOS - IOS游戲開發(fā)之五子棋OC版

IOS游戲開發(fā)之五子棋OC版

2021-01-23 16:57iOS開發(fā)網(wǎng) IOS

五子棋是大家比較熟悉的一款小游戲,相信很多人用多種語言寫過五子棋小游戲,本文試著用OC實(shí)現(xiàn)了一下,在這里給大家分享一下。有需要的可以參考學(xué)習(xí)。

先上效果圖

- 功能展示

IOS游戲開發(fā)之五子棋OC版

- 初高級(jí)棋盤切換效果

IOS游戲開發(fā)之五子棋OC版

實(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)!

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产suv精品 | 亚洲丁香网| 超级碰碰免费视频 | 91污无限制破解安卓2021 | 国产特黄一级一片免费 | 久久亚洲午夜牛牛影视 | 欧美贵妇vs高跟办公室 | 91伊人网| 嘉嘉的丝袜美腿白丝 | 福利一区二区在线观看 | 国产一区二区三区高清视频 | 59日本人xxxxxxxxx69 | 美女张开腿黄网站免费精品动漫 | 美女撒尿部位无遮挡 | 欧美 国产 日韩 第一页 | 国产小情侣自拍 | 动漫jk美女被爆羞羞漫画 | 91精品国产高清久久久久久91 | 亚洲成在人线视频 | 50度灰破解版v5.7.0 | 红色播放器 | 毛片网站免费观看 | eeuss18影院www国产 | 日本一区二区三区在线 视频 | 国产香蕉一区二区在线网站 | 免费观看二十女人一摸是水 | 娇喘高潮教室h | 亚洲AV久久无码精品九号软件 | 办公室里被迫高h | 大乳一级一区二区三区 | 欠操h | 亚洲精品www久久久久久 | 冰雪奇缘1完整版免费观看 变形金刚第一部 | 大桥未久一区二区 | 5566中文字幕亚洲精品 | 亚洲国产日韩欧美一区二区三区 | 特黄a大片免费视频 | 亚洲午夜精品久久久久久人妖 | 午夜dj影院在线视频观看完整 | 国产麻豆在线观看网站 | 袖珍人与大黑人性视频 |