一步一步实现五子棋3

原创 2013年12月06日 11:32:04

昨天有面试,五子棋的工作暂停了一下,今天继续。

  前面五子棋的棋盘棋子的绘制以及用鼠标下棋的功能已经实现了,下一步我们的工作就是让电脑一步一步学会如何下棋。首先要教会的是如何判断输赢,我们都知道当相同棋子在横向、纵向和斜对角方向形成五连珠者分出胜负,所以只要扫描整个棋盘发现有五连珠即可判断输赢。当然,扫描整个棋盘的方法笨了点,只关注最后落子的点是否能形成五连珠就可以了,话不多说,上代码:

BOOL Engine::isFive( int x, int y )
{
    int value = 1;
    int i = 0;


    int type = m_chessTable[x][y].type;


    // 横向
    for (i = 1; ((x + i) <= 14) && (m_chessTable[x + i][y].type == type); i++, value++);
    for (i = 1; ((x - i) >= 0)  && (m_chessTable[x - i][y].type == type); i++, value++);


    if (value >= 5)
    {
        return TRUE;
    }


    // 纵向
    value = 1;
    for (i = 1; ((y + i) <= 14) && (m_chessTable[x][y + i].type == type); i++, value++);
    for (i = 1; ((y - i) >= 0)  && (m_chessTable[x][y - i].type == type); i++, value++);


    if (value >= 5)
    {
        return TRUE;
    }


    //西北-东南向
    value = 1;
    for (i = 1; ((x + i) <= 14) && ((y + i) <= 14) && (m_chessTable[x + i][y + i].type == type); i++, value++);
    for (i = 1; ((x - i) >= 0)  && ((y - i) >= 0)  && (m_chessTable[x - i][y - i].type == type); i++, value++);


    if (value >= 5)
    {
        return TRUE;
    }


    // 西南-东北
    value = 1;
    for (i = 1; ((x + i) <= 14) && ((y - i) >= 0)  && (m_chessTable[x + i][y - i].type == type); i++, value++);
    for (i = 1; ((x - i) >= 0)  && ((y + i) <= 14) && (m_chessTable[x - i][y + i].type == type); i++, value++);


    if (value >= 5)
    {
        return TRUE;
    }


    return FALSE;
}

添加其他相关的处理以后电脑就能够判断输赢了,看效果:

  

  教会了判断输赢的规则,下面将渐渐进入重点了——告诉电脑怎么下棋。这个过程是很漫长的,我们慢慢来,先做一些前期的准备工作。

  首先建立一个独立线程,有了这个线程,当对手下棋后,这个线程就开始工作替电脑分析对策,给出指导。

class ThreadAI :
    public ThreadObject
{
public:
    ThreadAI(void);
    ~ThreadAI(void);

     void Run();

      void PushTask(Task* taskPtr);

      Task* PopTask();

private:
    std::vector<Task*> m_taskList;
    Mutex m_taskMutex;
};


  大家可能注意到了线程有两个成员m_taskList和m_taskMutex。m_taskList用来缓存任务,比如当对手落子后,主线程就会生成一个任务,加入到m_taskList中,告诉电脑“家已经下了,轮到你小子了”,电脑就会通过线程来处理这些任务。这是线程间通讯的一种很常用的方式。m_taskMutex看名字就知道是用来进行线程间同步的。这里的线程类和同步量对象都是经过封装的类,不是C++标准库里的,如果直接拷贝代码去编译肯定编译不过的。下面是run()的实现:

void ThreadAI::Run()
{
    Task *taskPtr = NULL;
    while (!IsBreak())
    {
        taskPtr = PopTask();
        if (taskPtr != NULL)
        {
            taskPtr->Run();
            delete taskPtr;
            taskPtr = NULL;
        }

        Wait(100);
    }
}

  时间过得真快,一下子就到了吃饭时间了,下午我重点研究下五子棋局面评估算法。

一步一步实现五子棋1

最近待业中,趁这段时间想实现一个VC版的五子棋软件,并且把每天的工作内容写出来当作对自己工作的总结,同时希望能达到抛砖引玉的效果,希望各位大侠多多指教。 首先建立一个MFC工程,如下图:       ...
  • ILSunny
  • ILSunny
  • 2013年12月04日 12:27
  • 891

迈出从3K到1W的重要一步——掌握设计模式

转载地址:http://blog.csdn.net/zhengzhb/article/details/7247188 IT职场的小菜经常有这样的疑问:         为什么一个相似的功能,大...

一行一步一花新:python-3:python中的random模块

Python中的random模块   Python中的random模块用于生成随机数。下面介绍一下random模块中最常用的几个函数。 random.random ra...

图片选择 Android 只需一步实现

  • 2016年01月22日 12:45
  • 6.9MB
  • 下载

C#实现“下一步”效果——示例

  • 2012年08月24日 23:26
  • 56KB
  • 下载

一个人走一个n阶的楼梯,他一步可以走1阶,2阶,3阶,这三种情况,问走完这n阶的楼梯共有多少种不同的走法?

当时脑子不够用,10级楼梯嘛,每一次至少走一步,走完10步最多10次,那么用10个循环可以搞定,够傻逼的吧,看下面。 int method_num = 0; int judge_num = 0; ...
  • xhyzdai
  • xhyzdai
  • 2013年01月28日 20:57
  • 2286
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:一步一步实现五子棋3
举报原因:
原因补充:

(最多只允许输入30个字)