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有所帮助,如果本文有不足之处,欢迎大家提供建议和指点!

(0)

相关推荐

  • jQuery实现的五子棋游戏实例

    本文实例讲述了jQuery实现的五子棋游戏.分享给大家供大家参考.具体如下: 这是一款非常不错的代码,就是人工智能方面差了一点 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999

  • Javascript和HTML5利用canvas构建Web五子棋游戏实现算法

    这只是一个简单的JAVAscript和HTML5小程序,没有实现人机对战. 五子棋棋盘落子点对应的二维数组.数组的元素对应落子点.比如数组元素值为0表示该元素对应的落子点没有棋子,数组元素值为1表示该元素对应的落子点有白棋子,数组元素值为2表示该元素对应的落子点有黑棋子: 判断五子棋赢棋的算法是通过对五子棋棋盘落子点对应的二维数组的操作来实现的. 判断五子棋赢棋算法 下边的函数可以实现判断五子棋赢棋的算法,也可以按照教材中相应的算法实现. 其中函数的参数xx.yy为数组下标,chess数组实现五

  • C++面向对象实现五子棋小游戏

    尽量将面向对象的思想融入进程序中 ChessBoard.h //ChessBoard.h #pragma once #define ROW 15 #define COL 15 #include<iostream> using namespace std; class ChessBoard//棋盘类 { public: char m_cSquare[ROW][COL]; public: ChessBoard(); void show(); }; ChessBoard.cpp //ChessBoa

  • VC实现五子棋游戏的一个算法示例

    本文讲述了VC实现五子棋游戏的一个算法示例,该算法采用极大极小剪枝博弈算法,感兴趣的读者可以对程序中不完善的部分进行修改与完善. 该设计主要包括:数据结构.估值函数.胜负判断.搜索算法 程序运行界面如下: 具体实现步骤如下: 1.数据结构 //记录每步棋,可以建立链表用来进行悔棋.后退(本程序没有实现) struct Step { int x,y; //棋子坐标 int ball; //表示下子方{BLACK,WHITE} }; //记录棋盘情况,用于搜索过程 class CBoardSitua

  • java基于swing实现的五子棋游戏代码

    本文实例讲述了java基于swing实现的五子棋游戏代码.分享给大家供大家参考. 主要功能代码如下: 复制代码 代码如下: import java.awt.*; import javax.swing.*; import java.awt.event.*; public class Main extends JFrame implements ActionListener{         private static final long serialVersionUID = 1L;      

  • 基于C语言实现五子棋游戏完整实例代码

    本文实例讲述了基于C语言实现五子棋游戏的方法,代码备有比较完整的注释,可以帮助读者更好的加以理解. 五子棋游戏代码如下: /* * 使用键盘的上下左右键移动棋盘,空格键表示下棋,ESC键退出程序 */ #include <stdio.h> #include <stdlib.h> #include <bios.h> #include <graphics.h> #include<malloc.h> /* * 对应键盘键的十六进制数字 */ #defi

  • hta 实现的五子棋界面

    保存为 五子棋.hta,运行即可看到效果 <html> <title>五子棋界面 - zh159</title> <hrad> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <HTA:APPLICATION ID="MyhyliApp" APPLICATIONNAME="五子棋界面

  • java实现五子棋小游戏

    java实现五子棋小游戏 package Gomoku; import java.awt.Toolkit; import javax.swing.JFrame; public class GomokuFrame extends JFrame { //定义一个操作面板 OperatorPane op=null; public GomokuFrame() { //设置名称 this.setTitle("五子棋"); //设置窗口大小 this.setSize(510,510); //设置窗

  • 纯JS实现五子棋游戏兼容各浏览器(附源码)

    纯JS五子棋(各浏览器兼容) 效果图:  代码下载 HTML代码 复制代码 代码如下: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;"> <title>五子棋</title> <link rel="stylesheet" type="text/

  • 纯C语言实现五子棋

    正在考虑增加一个MFC界面.不是人机对战的. 五子棋.c //date 2014年7月7日09:53:24 //willows //五子棋 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <assert.h> //棋盘初始化函数 //Chessboard棋盘数组,ln=棋盘大小,成功返回Chessboard,不成功NULL void init_Chessboa

随机推荐