欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

IOS游戏开发之五子棋OC版

程序员文章站 2023-12-12 13:17:10
先上效果图 - 功能展示 - 初高级棋盘切换效果 实现思路及主要代码详解 1.绘制棋盘 利用quartz2d绘制棋盘.代码如下 - (void)...

先上效果图

- 功能展示

IOS游戏开发之五子棋OC版

- 初高级棋盘切换效果

IOS游戏开发之五子棋OC版

实现思路及主要代码详解

1.绘制棋盘

利用quartz2d绘制棋盘.代码如下

- (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.点击棋盘落子

     1)根据落子位置求出该棋子的行号与列号.

     2)判断落子位置是否已经有棋子,有则不能下.如果没有,将棋子保存在字典中,以列号和行号组合起来的字符串为key值.

代码如下:

//点击棋盘,下棋
  - (void)tapboard:(uitapgesturerecognizer *)tap{
   
    cgpoint point = [tap locationinview:tap.view];
    //计算下子的列号行号
    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;
      //检查游戏结果
      [self checkresult:col androw:row andcolor:self.isblack];
      self.isblack = !self.isblack;
    }
  }

3.检测游戏结果

每落一个棋子就要多游戏结果进行一次检查,判断四个方向上是否有大于等于5个同色的棋子连成一线,有则提示游戏输赢结果,无则游戏继续.算法为,从当前棋子位置向前遍历,直到遇到与自己不同色的棋子,累加同色棋子的个数,再往后遍历,直到遇到与自己不同色的棋子,累加同色棋子的个数.得到该方向相连同色棋子的总个数

代码如下

//判断是否大于等于五个同色相连
  - (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) {
      //水平方向检查结果
      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;
  }

对外提供,重新开始,悔棋,切换初高级棋盘的三个接口

重新开始

- (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;
  }

悔棋

//撤回至上一步棋
  - (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 ? @"只能悔一步棋!!!" : @"请先落子!!!";
      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;
  }

切换初高级键盘

//改变键盘级别
  - (void)changeboardlevel{
     
    for (uiview * view in self.subviews) {
      [view removefromsuperview];
    }
    [self newgame];
    self.ishighlevel = !self.ishighlevel;
    [self drawbackground:self.bounds.size];
  }

demo中的一个小技巧

用字典存放棋子,以棋子的列号和行号组合起来的字符串为key值,value值为棋子view.这样处理,在判断某行某列是否有棋子就非常简单了。

总结

以上就是ios游戏开发之五子棋oc版的全部内容,希望本文对大家开发ios有所帮助,如果本文有不足之处,欢迎大家提供建议和指点!

上一篇:

下一篇: