2KB项目,专业的源码交易网站 帮助 收藏 每日签到

实现 iOS 上的井字游戏

  • 时间:2019-01-23 18:33 编辑:2KB 来源:2KB.COM 阅读:296
  • 扫一扫,手机访问
  • 分享
摘要:
iOS 英文原文:Implementing Tic Tac Toe on iOS

Sample Image - maximum width is 600 pixels

简介

本文介绍如何用 MVC 模式在 iOS 上实现双人对战的井字游戏. 读者最好有一些 iOS 编程基础, 以便更好的理解本文的代码. 希望这篇文章对提高读者的 iOS 和 MVC 编程水平有所帮助.

背景

井字游戏

关于游戏的规则我就不多说了, 相信大家都知道怎么玩. (如果不清楚游戏规则, 请点 这里). 下面要介绍的是人和人对战的井字游戏, 至于人机对战不属于本文讨论的范围.

MVC 模式

MVC 是 iOS 开发中常用的一种设计模式. MVC 把应用程序中的对象分成三类:

  • Model: 只负责程序中的数据部分, 与用户界面无关.

  • View: 负责程序界面的显示和用户交互部分.

  • Controller: 是连接 Model 和 View 的一条纽带. 比如, 它把用户输入的数据传给 Model, 或者把 Model 的数据传给 View. 

我们的游戏将使用 MVC 模式来实现. 下面的图片是 MVC 各部分之间的关系:

 

mvc

MVC 的更多内容请点 这里.

实现

Model

我们已经讲过, Model 对象与用户界面无关.  游戏项目中, 有个类 (TTTicTacToe.m), 跟用户界面没有半毛钱关系, 纯粹是用来实现游戏逻辑, 保存游戏状态的. 比如:  棋盘 - 一个简单的 char 二维数组, 保存玩家每一步走法的函数, 判断有没有玩家胜出的函数等等. 而 View 则通过 UIButton 把游戏的状态显示出来.

数组跟按钮之间的映射

我们已经讲过, 游戏的状态保存在 Model 类的一个二维数组中. 而棋盘则用 UIButton 对象实现. 当 View 要在用户界面显示游戏状态的时候, 需要找个方法, 把二维数组跟 UIButton 对象关联起来. 由于 UIButton 对象通过 tag (也就是 ID) 访问, 我们从 1 到 16, 给它编个号. 然后再想办法跟数组关联起来就可以了.  Model 的二维数组看起来像酱紫:

mat

通过这个公式: buttonID = i*4 + j + 1, 就能把数组元素[i,j] 跟 UIButton 对象的 ID 关联起来. 比如: 数组元素[2,3]对应的是 ID(也叫tag) 为 12 的 UIButton 对象.

View Controller

下面, 我们讲下这个实现游戏逻辑的函数(包括用户界面). 当用户按下某个按钮(UIButton 对象)时, 该函数就会被调用(我们把按钮的坐标当作参数传给它). 代码已经写了详细的注释, 我再简单说下. View 调用 Model 对象(self.game 是 TTTicTacToe.m 类的对象)保存玩家下棋的数据的.   然后调用 redrawTable 函数, 把 Model 中的游戏状态显示出来(这个函数后面再讲). 最后调用 self.game checkForWin 函数判断有没有玩家获胜.

-(void) userMoveX:(int)x andY:(int)y
{
    BoardCoord pos;
    pos.x = x;
    pos.y = y;
    
    //由 x 和 y 坐标推算出按钮的 ID.
    int buttonID = 4 * y + x + 1;
    
    // 玩家最多走 16 步棋.
    if(self.counter > 15)
        return;
    
    // 保存玩家下棋的状态.
    [self.game updateBoardAtPos:pos withPlayer:((self.counter) % 2)];
    
    // 更新用户界面
    [self redrawTable];
    
    // 判断有没有玩家胜出?
    if([self.game checkForWin:pos])
    {
        if((self.counter % 2) == 0)
        {
            NSLog(@"Win X");
            self.status.text = @"Player X wins!";
        }
        else
        {
            self.status.text = @"Player O wins!";
            NSLog(@"Win O");
        }
        
        // 如果其中一个玩家获胜, 游戏结束
        // 禁用所有按钮(Disabled)
        for(int i=1; i<=16; i++)
        {
            //通过 tag 获取按钮对象
            UIButton *b = (UIButton*)[self.view viewWithTag:i];
            // 禁用按钮
            b.enabled = NO;
        }        
    }
    
    // 玩家当前点到的按钮也要禁用
    UIButton *b = (UIButton*)[self.view viewWithTag:buttonID];
    b.enabled = NO;

    // counter 增 1
    self.counter++;
}

注意: (self.counter) % 2 这行代码中, self.counter 表示玩家总共已经下了几步棋. 对 2 求余, 结果是 0 表示玩家 X, 1 表示玩家 O . 

最后就剩下这个用按钮显示棋盘的函数了:

-(void) redrawTable
{
    for(int i=0; i < SIZE; i++)
        for(int j=0; j < SIZE; j++)
        {
            // 获取按钮的 handle
            UIButton*b = (UIButton*) [self.view viewWithTag:(i*4+j+1)];
            
            UIImage *btnImage;
            if([self.game objectAtX:j andY:i] == &apos;X&apos;)
            {
                 // 设为 X 图标
                 btnImage = [UIImage imageNamed:@"xIcon.png"];
            }else
            {
                if([self.game objectAtX:j andY:i] == &apos;O&apos;)
                {
                    // 设为 O 图标
                    btnImage = [UIImage imageNamed:@"oIcon.png"];
                }
            }
        
            // 在按钮上面显示图标
            // 如果 btnImage 为 nil, 则不用显示
            [b setImage:btnImage forState:UIControlStateNormal];
        } 
}

历史

  •  Version 1.00 - Initial release

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。 2KB翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。


2KB项目(www.2kb.com,源码交易平台),提供担保交易、源码交易、虚拟商品、在家创业、在线创业、任务交易、网站设计、软件设计、网络兼职、站长交易、域名交易、链接买卖、网站交易、广告买卖、站长培训、建站美工等服务

  • 全部评论(0)
资讯详情页最新发布上方横幅
最新发布的资讯信息
【计算机/互联网|】Nginx出现502错误(2020-01-20 21:02)
【计算机/互联网|】网站运营全智能软手V0.1版发布(2020-01-20 12:16)
【计算机/互联网|】淘宝这是怎么了?(2020-01-19 19:15)
【行业动态|】谷歌关闭小米智能摄像头,因为窃听器显示了陌生人家中的照片(2020-01-15 09:42)
【行业动态|】据报道谷歌新闻终止了数字杂志,退还主动订阅(2020-01-15 09:39)
【行业动态|】康佳将OLED电视带到美国与LG和索尼竞争(2020-01-15 09:38)
【行业动态|】2020年最佳AV接收机(2020-01-15 09:35)
【行业动态|】2020年最佳流媒体设备:Roku,Apple TV,Firebar,Chromecast等(2020-01-15 09:31)
【行业动态|】CES 2020预览:更多的流媒体服务和订阅即将到来(2020-01-08 21:41)
【行业动态|】从埃隆·马斯克到杰夫·贝佐斯,这30位人物定义了2010年代(2020-01-01 15:14)
联系我们

Q Q: 7090832

电话:400-0011-990

邮箱:7090832@qq.com

时间:9:00-23:00

联系客服
商家入住 服务咨询 投拆建议 联系客服
0577-67068160
手机版

扫一扫进手机版
返回顶部