MFC制作贪吃蛇教程详解

写在前面的话

本次贪吃蛇教程主要知识点包括以下几个方面

        CView类中的消息响应

        控件的消息响应

        基于CView类内的具体游戏实现

        数组

        游戏图形的实现用CDC类实现。

    本版游戏的具体实现是在CViewl类中实现,所以其他类不用添加任何代码。

由于此次贪吃蛇需要MFC的开发环境,所以打开VisualC++新建一个MFC AppWizard单文档工程,随意取名一个工程名称。手把手教MFC贪吃蛇

 

手把手教MFC贪吃蛇



 

本次贪吃蛇基本流程与大体思想

 定义蛇类和食物类,初始化贪吃蛇各项成员变量,包括图像的出现在屏幕的初始位置,长度,以及蛇的行走方向。食物类的定义包括出现的初始位置,以及食物是否被吃掉的判断。

 用数组初始化长度为3的贪吃蛇,并且默认食物未出现

 在CView类上运用MFC提供的Windows消息中WM_TIMER消息,运用OnTimer()函数让系统提供一个时钟节拍,更新游戏

 具体游戏实现,包括蛇撞到自己和围墙都将使游戏结束,判断吃豆等,其中还包括根据蛇的长度来进行游戏难度的改变。

 具体键盘游戏操作运用到Windows消息响应中的WM_KEYDOWN,用OnKeyDown()来响应玩家的实际操作。

 

 

 

///

 

第一部分 

 

首先在已有工程下的“ClassView”中右键CView类添加以下Windows信息

1 WM_KEYDOWN

2 WM_RBUTTONDOWN

3 WM_TIMER

再右键CView类选择 “ADD Virtual Funciton”选OnInitialUpdate()

 手把手教MFC贪吃蛇

OnInitialUpdate()的功能如下:

视图窗口完全建立后第一个被框架调用的函数。框架在第一次调用OnDraw前会调用OnInitialUpdate,因此OnInitialUpdate是设置滚动视图的逻辑尺寸和映射模式的最合适的地方

时间上,两者先后顺序不同,构造函数生成本类的对象,但没有产生窗口,OnCreate后窗口产生,然后才是视图的OnInitialUpDate,一般在这里对视图的显示做初始化。简单点,就是ONCREATE只是产生VIEW的基本结构和变量而在OnInitialUpDate()中,主要初始化视图中控件等。对各个变量进行初始化操作

所以我们要用这个函数来进行贪吃蛇的初始化工作

手把手教MFC贪吃蛇

再者还要添加一个成员函数oninit()

进行贪吃蛇外观的初始化

 

 

控件的设计

 

再者是设计游戏的一些控件来控制“游戏开始” “游戏结束” 和“游戏暂停”。

我们可以点击“工作空间”的“ResourceView”进行控件的具体设计,这里我们在Menu文件夹中把“IDR_MAINFRAME”中默认的控件全部删除手把手教MFC贪吃蛇

右键其中的标题栏,点击属性,会得到一个菜单栏标题,我们分别建立1个菜单栏标题。这里我们分别建“游戏”。手把手教MFC贪吃蛇

点击并且在已有控件中的列表中点击属性,进行“菜单项目属性”的设置。我们本别建立的属性“标明”与对应的ID有

游戏开始   IDM_START

游戏暂停   IDM_PAUSE

游戏继续   IDM_CONTINUE

游戏退出   IDM_EXIT

此处控件的设计是“可见即可得”的控件操作

手把手教MFC贪吃蛇

手把手教MFC贪吃蛇

 

成功设置ID之后 我们分别右键

各项属性进行消息响应处理函数的生成

 

具体方法操作例子如下

1右键“游戏开始”

2 点击“类向导建立”

3 在Message Maps页面,在要进行消息响应的控件ID列表Object IDs中上选择对应的ID, 这里我们选择IDM_START,具体实现的环境是CView类,所以我们必须把“Class name”的默认“CMainFrame”改为“CView类”,并且在“Messages”类型设置中,用“COMMAND”设置为其为命令消息。其余各项也按照同理进行设置。

 手把手教MFC贪吃蛇

手把手教MFC贪吃蛇



PS:Windows消息的分类有3种,标准消息,命令消息,通告消息

1 标准消息除COMMAND之外,所以WM_开头都是标准消息

2 命令消息就是COMMAND

3 通告消息由控件产生的消息,这类信息也能以WM_COMMAND类型出现

 

最后我们回到原来的ClassView去看看我们一共添加的函数

手把手教MFC贪吃蛇

手把手教MFC贪吃蛇

所有的函数集合全部有以下手把手教MFC贪吃蛇



在此处我们可以看到我们添加的Windows消息所有的 消息响应函数的声明

手把手教MFC贪吃蛇

//

 

第二部分

    具体实现游戏、

 

Step 1

首先我们在文件开头处分别定义 蛇 和食物 的全局变量

struct Snake

{

       int x,y;

       int len;

       int direct;

}Snake[50];

struct Food

{

       int x;

       int y;

       int isfood;

}Food;

 手把手教MFC贪吃蛇


再者

void CSNAKEView::OnInitialUpdate()
{
 CView::OnInitialUpdate();
 Snake[0].x=10;
 Snake[0].y=10;
 Snake[1].x=11;
 Snake[1].y=10;
 Snake[2].x=12;
 Snake[2].y=10;
 Snake[0].direct=3;
 Snake[0].len=3;
 Food.isfood=1;
 // TODO: Add your specialized code here and/or call the base class
 
}
手把手教MFC贪吃蛇

代码说明:

     初始化贪吃蛇起初有3个节点,长度为3,起始坐标;

     食物默认为 1无0有 当然我更加喜欢0无1有手把手教MFC贪吃蛇


 

    

 

Step 2 对OnKeyDown()具体添加代码

void CSNAKEView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
 // TODO: Add your message handler code here and/or call default
 switch(nChar)
 {
 case VK_UP:if(Snake[0].direct!=2)Snake[0].direct=1;break; 
 case VK_DOWN:if(Snake[0].direct!=1)Snake[0].direct=2;break;
 case VK_LEFT:if(Snake[0].direct!=4)Snake[0].direct=3;break;  
 case VK_RIGHT:if(Snake[0].direct!=3)Snake[0].direct=4;break;  }
 CView::OnKeyDown(nChar, nRepCnt, nFlags);
 CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

 
手把手教MFC贪吃蛇
OnKeyDown函数的第一个参数 UINT nChar 是接收用户键入的信息,然后我们用switch进行选择判断
代码说明:

    Snake[0]代表的是蛇头,我们对蛇头的方向Snake[0].direct进行判断。

case VK_UP:if(Snake[0].direct!=2)Snake[0].direct=1;break; 
意思就是当Snake[0].direct的方向此时并不等于“下”的时候,才能做出“上”的操作动作,否则则忽略用户“向上”的操作按键效果

 

 

Step 3 对OnRButtonDown()具体添加代码

void CSNAKEView::OnRButtonDown(UINT nFlags, CPoint point)
{
 // TODO: Add your message handler code here and/or call default
 // TODO: Add your message handler code here and/or call default
 CString str;
 str.Format("%d,%d",point.x,point.y);
 AfxMessageBox(str);
 CView::OnRButtonDown(nFlags, point);
 CView::OnRButtonDown(nFlags, point);
 CView::OnRButtonDown(nFlags, point);
}

这个函数功能是:用鼠标右键屏幕,就会马上显示当前位置的坐标信息。

其实这个函数并不是本游戏中必要添加的函数,只是为了在后面游戏页面的设计的时候可以用鼠标右键屏幕了解大概的屏幕坐标信息,才特地做的

 

这里补充一个知识点

    WIN32坐标系有3种

世界坐标系

2 页面坐标系

3 设备坐标系

 

 世界坐标系与页面坐标系称谓“逻辑空间”,实际上就等同于我们现实生活中的数学坐标系一样。

 设备坐标系则不然,电脑屏幕就是一个用设备坐标系的,特征为以用户区窗口左上角为(0 , 0)原点,X坐标向右为正,Y坐标向下为正。


Step 4

void CSNAKEView::oninit()
{
    CDC *pDC=GetDC();
 CBrush DrawBrush=(RGB(100,100,100));
 CBrush *Drawbrush=pDC->SelectObject(&DrawBrush);
 for(int i=0;i<=Snake[0].len-1;i++)
  pDC->Rectangle(Snake[i].x*20,Snake[i].y*20,(Snake[i].x+1)*20,(Snake[i].y+1)*20);
 pDC->SelectObject(DrawBrush);
}

手把手教MFC贪吃蛇

代码说明:

    利用Windows给我们提供的CDC类来进行画图,我们首先用一个指向CDC类的指针去接受与该窗口相关联的DC句柄,然后用定义画刷一个DrawBrush对象,并且用RGB(100,100,100)来给画刷初始化颜色。并且用SelectObject(&DrawBrush);函数把对象画刷选入到设备描述表中,用for循环依次把贪吃蛇的3个节点画出来。

 void far rectangle(int left, int top, int right, int bottom);

这个函数的的功能根据

函数功能:该函数画一个矩形,用当前的画笔画矩形轮廓,用当前画刷进行填充.

 

Step 5 控件添加代码

 

void CSNAKEView::OnStart()
{
 // TODO: Add your command handler code here
 SetTimer(1,3000,NULL);
 AfxMessageBox("3秒后开始游戏!");
}

void CSNAKEView::OnPause()
{
 // TODO: Add your command handler code here
 KillTimer(1);
 AfxMessageBox("暂停游戏...");
}

void CSNAKEView::OnExit()
{
 // TODO: Add your command handler code here
 AfxMessageBox("退出游戏...");
 exit (0);
}

void CSNAKEView::OnContinue()
{
 // TODO: Add your command handler code here
 SetTimer(1,10,NULL);
}

手把手教MFC贪吃蛇

代码说明:

    由于之前我们设定了WM_TIMER消息,我们能运用计时器功能

    用WM_TIMER来设置定时器

  先请看SetTimer这个API函数的原型

  UINT_PTR SetTimer(

  HWND hWnd, // 窗口句柄

  UINT_PTR nIDEvent, // 定时器ID,多个定时器时,可以通过该ID判断是哪个定时器

  UINT uElapse, // 时间间隔,单位为毫秒

  TIMERPROC lpTimerFunc // 回调函数

  );

 

    SetTimer(m_hWnd,1,1000,NULL); //一个1秒触发一次的定时器

  在MFC程序中SetTimer被封装在CWnd类中,调用就不用指定窗口句柄了

 

所以我们这里可以只去后3个参数写成SetTimer(1,10,NULL);

1000为1秒

关于afxMessageBox的研究在本博客中有写有,这里就不在赘述

Step 6 对OnDraw()的添加代码

OnDraw()函数众所周知视图类中的输出.视图类的输出基本上都是在视图类的OnDraw函数中处理的,系统会准备好入参,然后调用OnDraw函数

本人也没有过多的去研究过次函数,仅知道一些皮毛。不过这里有个知识点那便是OnPaint()与OnDraw()的区别,OnPaint()派生于CWnd类,响应WM_PAINT消息。OnDraw是CView类的成员函数,并且没有消息响应功能,这就是为什么视图类没有只有OnDraw()而没有OnPaint()的原因。OnDraw()维护视图客户区(例如通过试表在视图中画图),而OnPaint()维护窗口的客户区

 


void CSNAKEView::OnDraw(CDC* pDC)
{
 CSNAKEDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 // TODO: add draw code for native data here
 CBrush backBrush(RGB(100,100,0));
 CBrush* pOldBrush = pDC->SelectObject(&backBrush);
 CRect rect;
 pDC->GetClipBox(&rect);
 pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(),PATCOPY);
 pDC->SelectObject(pOldBrush);
 

 pDC->Rectangle(19,19,501,501);

 oninit();
}



代码说明:

    此处是用画刷画一个背景,并且画出3个矩形区域

    函数原型:int GetClipBox(HDC hdc, LPRECT lprc);

    该函数得到一个能够完包含当前可见区域的最小矩形的大小。 

 

    函数原型:int nYLeft, int nWidth, int nHeight, DWORD dwRop); 

    该函数使用当前选入指定设备环境中的刷子绘制给定的矩形区域。

 

 

 

Step 7 对OnTime()的添加代码

 

void CSNAKEView::OnTimer(UINT nIDEvent)
{
 // TODO: Add your message handler code here and/or call default
 CDC *pDC=GetDC();
 CString soure;
 
 if(Snake[0].len==2)SetTimer(1,370,NULL);
 if(Snake[0].len==3)SetTimer(1,270,NULL);
 if(Snake[0].len==6)SetTimer(1,200,NULL);
 if(Snake[0].len==9)SetTimer(1,100,NULL);
 
 soure.Format("得分:%d!",(Snake[0].len-3)*10); 
 //撞界判断
 if(Snake[0].x*20<=37||Snake[0].y*20<=37||Snake[0].x*20>=462||Snake[0].y*20>=462)
 {
  KillTimer(1);
  AfxMessageBox(soure);
 // s=0;
 }
    //蛇身相撞判断
 if(Snake[0].len>3)
  for(int sn=Snake[0].len-1;sn>0;sn--)
  {
   if(Snake[0].x*20==Snake[sn].x*20&&Snake[0].y*20==Snake[sn].y*20)
   {
    KillTimer(1);
    AfxMessageBox(soure);
  //  s=0;
   }
  }
  ///
  pDC->SelectStockObject(WHITE_PEN);
  pDC->Rectangle(Snake[Snake[0].len-1].x*20,Snake[Snake[0].len-1].y*20,(Snake[Snake[0].len-1].x+1)*20,(Snake[Snake[0].len-1].y+1)*20);
  for(int i=Snake[0].len-1;i>0;i--)
  {
   Snake[i].x=Snake[i-1].x;
   Snake[i].y=Snake[i-1].y;
  }

  //行走方向判断
  if(Snake[0].direct==1)Snake[0].y--;
  if(Snake[0].direct==2)Snake[0].y++;
  if(Snake[0].direct==3)Snake[0].x--;
  if(Snake[0].direct==4)Snake[0].x++;
  pDC->SelectStockObject(BLACK_PEN);
  
  CBrush DrawBrush=(RGB(100,100,100));
  CBrush *Drawbrush=pDC->SelectObject(&DrawBrush);
  pDC->Rectangle(Snake[0].x*20,Snake[0].y*20,(Snake[0].x+1)*20,(Snake[0].y+1)*20);
  pDC->SelectObject(DrawBrush);


  //判断吃豆的条件,撞到就吃
  if(Snake[0].x*20==Food.x*20&&Snake[0].y*20==Food.y*20)
  {
   Snake[0].len++;
   Food.isfood=1;
   Snake[Snake[0].len-1].x=Snake[Snake[0].len-2].x;
   Snake[Snake[0].len-1].y=Snake[Snake[0].len-2].y;
  }
  //如果食物被吃了 就生成
  if(Food.isfood==1)
  {
   srand((unsigned)time(NULL));
   do
   {
    for(int isfo=Snake[0].len-1;isfo>=0;isfo--)

     if(Snake[0].x*20==Snake[isfo].x*20&&Snake[0].y*20==Snake[isfo].y*20)
     {
      Food.x=rand()%25;
      Food.y=rand()%25;
     }
   }
   while(Food.x*20<70||Food.y*20<70||Food.x*20>430||Food.y*20>430);

   pDC->Rectangle(Food.x*20,Food.y*20,(Food.x+1)*20,(Food.y+1)*20);
   Food.isfood=0;
  }
 
 CView::OnTimer(nIDEvent);
}

手把手教MFC贪吃蛇

手把手教MFC贪吃蛇 

 

 手把手教MFC贪吃蛇


/

   下面由我来详细分析代码

 

 if(Snake[0].len==2)SetTimer(1,370,NULL);
 if(Snake[0].len==3)SetTimer(1,270,NULL);
 if(Snake[0].len==6)SetTimer(1,200,NULL);
 if(Snake[0].len==9)SetTimer(1,100,NULL);

此段代码的作用是根据蛇的长度来进行SetTimer()函数的定义,可以根据长度来进行游戏难度的设定,如上代码分别370ms 270ms 200ms 100ms进行一次新的移动。

 //撞界判断
 if(Snake[0].x*20<=37||Snake[0].y*20<=37||Snake[0].x*20>=462||Snake[0].y*20>=462)
 {
  KillTimer(1);
  AfxMessageBox(soure);
  }

 

这里为什么要乘以20呢?由于我们初始化的时候是

 Snake[0].x=10;
 Snake[0].y=10;
 Snake[1].x=11;
 Snake[1].y=10;
 Snake[2].x=12;
 Snake[2].y=10;

所以只是把贪吃蛇的起始位置“搬移”到20倍的位置 当然可以等价于

 Snake[0].x=10*20;
 Snake[0].y=10*20;
 Snake[1].x=11*20;
 Snake[1].y=10*20;
 Snake[2].x=12*20;
 Snake[2].y=10*20;

蛇的一节身体为一个矩形块,这样表示每个矩形块只需起点坐标x y身体是不断增长的,所以用数组存放每一节的坐标

//蛇身相撞判断
 if(Snake[0].len>3)
  for(int sn=Snake[0].len-1;sn>0;sn--)
  {
   if(Snake[0].x*20==Snake[sn].x*20&&Snake[0].y*20==Snake[sn].y*20)
   {
    KillTimer(1);
    AfxMessageBox(soure);
  // s=0;
   }
  }

这段是最好理解的了,由于判断蛇自己是否咬到了自己,根据蛇长sn,进行sn次for sn-1次循环

并且和Snake[0].x进行比较(之所以进行sn-1次那肯定是不包括蛇头而且蛇的长度也必须大于3才会发生自己咬自己的情况)

KillTimer(1);是停止计时器;和之前的SetTime()对应而已

AfxMessageBox(soure);这里不深究,总之就是输出一个原样输出内容

  pDC->SelectStockObject(WHITE_PEN);//把白色的“PEN”选入设备进行画图
  pDC->Rectangle(Snake[Snake[0].len-1].x*20,Snake[Snake[0].len-1].y*20,
     (Snake[Snake[0].len-1].x+1)*20,(Snake[Snake[0].len-1].y+1)*20);//让它去画最后一个节点
  for(int i=Snake[0].len-1;i>0;i--)//贪吃蛇的蛇身移动
  {
   Snake[i].x=Snake[i-1].x;
   Snake[i].y=Snake[i-1].y;
  }

 

这段的知识点要严重的说明一下

1 为什么要专门用白笔画最后一个呢?因为我们的游戏界面是用白色的,贪吃蛇移动的时候,肯定是蛇头向前走一单位,而尾部肯定要“擦除”掉一个单位,那怎么擦除呢?我们只能用和背景色一样的画笔。原来蛇的位置和新蛇的位置差一个单位,所以看起来蛇会多一节身体,所以将蛇的最后一节用背景色覆盖SelectStockObject(WHITE_PEN) 让它起到“消失”最后一个节点的功能

让我们以为蛇是向前走了。

如 假设现在贪吃蛇有4个单位0123

Snake[Snake[0].len-1].x*20 <=>Snake[Snake[0].4-1].x*20 =Snake[3].x*20

数组3 恰好是最后一个节点的下标,别忘了数组是从0开始算的

 

请仔细领悟

2

 for(int i=Snake[0].len-1;i>0;i--)
  {
   Snake[i].x=Snake[i-1].x;
   Snake[i].y=Snake[i-1].y;
  }

进行次数为"长度-1"次的循环

为什么要进行长度-1次呢?我这里要说明一下,这里是不包括蛇头的进行的平移,用数组赋值的方法,把前一节点保存在后一个结点,然后头结点向前移动。

 

  //方向判断
  if(Snake[0].direct==1)Snake[0].y--;
  if(Snake[0].direct==2)Snake[0].y++;
  if(Snake[0].direct==3)Snake[0].x--;
  if(Snake[0].direct==4)Snake[0].x++;
  pDC->SelectStockObject(BLACK_PEN);
  
  CBrush DrawBrush=(RGB(100,100,100));
  CBrush *Drawbrush=pDC->SelectObject(&DrawBrush);
  pDC->Rectangle(Snake[0].x*20,Snake[0].y*20,(Snake[0].x+1)*20,(Snake[0].y+1)*20);
  pDC->SelectObject(DrawBrush);
 

  “1234”本别代表“上下左右” x++,y++进行移动,然后用选定画刷画出一个新节点的矩形作为头结点

 //食物判断

  if(Food.isfood==0)
  {
   srand((unsigned)time(NULL));
   do
   {
    for(int isfo=Snake[0].len-1;isfo>=0;isfo--)

     if(Snake[0].x*20==Snake[isfo].x*20&&Snake[0].y*20==Snake[isfo].y*20)
     {
      Food.x=rand()%;
      Food.y=rand()%;
     }
   }
   while(Food.x*20<70||Food.y*20<70||Food.x*20>430||Food.y*20>430);

   pDC->Rectangle(Food.x*20,Food.y*20,(Food.x+1)*20,(Food.y+1)*20);
   Food.isfood=1;
  

这里关于

srand((unsigned)time(NULL));

rand()

的用法 在本博客有研究帖 这里不再赘述。

当食物被吃了指定食物的地方出现的地方在小于70 和大于430的矩形区域内

并且把食物属性更改为 “存在”


原博主那的博文里面代码有点小小的错误,在这里我已经修改好了。可能还存在不足之处,望多包涵!奋斗

 

 

//

 转载:http://blog.sina.com.cn/s/blog_6cbbf04b0100m49k.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/492470.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

人们对社会与金钱奖赏的预期共享神经环路

来源&#xff1a;神经科技摘要&#xff1a;在日常生活中&#xff0c;作为多种多样的目标导向行为的诱因&#xff0c;社会性奖赏与物质性奖赏扮演着同样重要的角色。2019年2月23日&#xff0c;国际神经科学杂志《Neuroscience & Biobehavioral Reviews》(影响因子&#xff1…

埃塞俄比亚空难,人机控制权争夺后的悲剧

来源&#xff1a;姬扬科学网博客2019年3月10日&#xff0c;埃塞俄比亚航空客机起飞后6分钟突然坠毁&#xff0c;机上157人死难、无人生还&#xff0c;包括8名来自中国大陆的旅客。这次失事的飞机是刚投入使用不久的波音737-MAX8&#xff0c;与去年十月份印度尼西亚航空失事的飞…

MFC制作员工信息管理系统

1.在MFC中建立如下的对话框。 2.修改相关控件的ID如下&#xff1a; 添加按钮的ID为&#xff1a;IDC_ADD,删除按钮的ID为&#xff1a;IDC_DEL&#xff0c;修改按钮的ID为&#xff1a;IDC_MOD。 三个编辑框的ID分别为&#xff1a;IDC_NUMB,IDC_NAME,IDC_SALA。列表控件的ID为&a…

中国AI创新者论坛将于3月21日在清华大学举办

来源&#xff1a;网易智能创新者是如何改变世界的&#xff1f;史蒂夫乔布斯生前在苹果产品发布会上&#xff0c;经常会用同一张幻灯片作为总结&#xff0c;在他身后的大屏幕上会出现一个路标&#xff0c;上面标示着“技术”&#xff08;Technology&#xff09;和“人文”&#…

边缘计算:5G 时代的万亿市场

来源&#xff1a;安信证券摘要&#xff1a;边缘计算将能力从云端下沉至边缘&#xff0c;有效支撑对时延等指标要求较高的城市、交通、家居、制造等场景应用落地&#xff0c;带来边缘节点、服务商两个核心增量机遇。▌边缘计算&#xff0c;5G时代的万亿市场边缘计算成为物理世界…

MFC创建模式对话框与非模式对话框

一、创建模式对话框 1、分别添加如下三个对话框&#xff0c;其ID分别为IDD_ABOUT、IDD_CHAT、IDD_MFCTEST_DIALOG 双击”关于“按钮&#xff0c;添加相应的消息函数如下&#xff1a; void CMFCTestDlg::OnAbout() {// TODO: Add your control notification handler code here…

Mobdata:2019大数据行业研究报告

来源&#xff1a;网络大数据未来智能实验室是人工智能学家与科学院相关机构联合成立的人工智能&#xff0c;互联网和脑科学交叉研究机构。未来智能实验室的主要工作包括&#xff1a;建立AI智能系统智商评测体系&#xff0c;开展世界人工智能智商评测&#xff1b;开展互联网&…

怎样在MySQL中显示中文,而不出现乱码?

1、首先修改MySQL的服务器的编码方式为utf8。具体怎样修改&#xff0c; 可以参考http://blog.csdn.net/ywxk1314/article/details/51280839 2、修改好之后&#xff0c;如果我们想查看数据表中的内容&#xff0c;我们会发现&#xff0c;表中原来的中文会出现部分乱码。如下图所示…

全球回报最好的 40 个 VC 投资案例,我们可以从中学到什么?

来源&#xff1a;IT桔子&#xff08;itjuzi521&#xff09;美国知名创投研究机构 CBInsights 日前发布文章《From Alibaba to Zynga: 40 Of The Best VC Bets Of All Time And What We Can Learn From Them》&#xff0c;统计了他们所认为的 VC 最好回报的 40 个案例&#xff0…

php 实现同一个账号同时只能一个人登录

php 实现同一个账号同时只能一个人登录 张映 发表于 2015-01-22 分类目录&#xff1a; php 标签&#xff1a;mysql, nginx, openfire, php, redis 以前考虑过这个问题&#xff0c;今天实现了一下&#xff0c;挺快的&#xff0c;从研究到开发完成差不多4个小时。有点类似QQ&…

空间简史-人类认识空间的旅程与其对强化学习的启示

来源&#xff1a;混沌巡洋舰摘要&#xff1a;本文是对okeefe 1978(栅格细胞发现者&#xff0c; 2014诺贝尔奖得主)的论文 cognitive map 的总结和延申。一 空间的先验与后验之争对于我们在其中生存和繁衍的空间&#xff0c; 是如何在我们的心理世界表达的&#xff0c; 这是一…

MFC中文件打开与保存

1、文件打开与保存 // NotePad01Dlg.cpp : implementation file //#include "stdafx.h" #include "NotePad01.h" #include "NotePad01Dlg.h"#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] __FILE__; #endif/ …

《经济学人》万字长文:DeepMind和谷歌的AI拉锯战

大数据文摘出品来源&#xff1a;Economics编译&#xff1a;橡树_hiangsug、林安安、小七、张秋玥摘要&#xff1a;Deepmind或许是当今世界对AGI影响最深远的公司。《经济学人》近日长文撰写了这家明星AI公司及其创始人的故事。通过对二十余名内部人士的采访&#xff0c;研究了这…

MFC制作计算器

1、代码如下&#xff1a; // zsjsqDlg.cpp : implementation file //#include "stdafx.h" #include "zsjsq.h" #include "zsjsqDlg.h"#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] __FILE__; #endif/ // CAb…

AI2:预计2030年中国AI研究或领跑全球

来源&#xff1a;网络大数据据美国科技媒体GeekWire报道&#xff0c;美国西雅图艾伦人工智能研究所(AI2)的一项最新分析表明&#xff0c;到2030年&#xff0c;中国有望成为人工智能领域的全球领跑者。A12研究所对人工智能领域最具影响力的研究论文加以统计&#xff0c;并利用语…

MFC中树形控件的应用——电话簿

一、电话薄的代码如下&#xff1a; 1、 // PhoneDlg.cpp : implementation file //#include "stdafx.h" #include "Phone.h" #include "PhoneDlg.h" #include "AddDlg.h" #include "ModifyDlg.h" #ifdef _DEBUG #define ne…

一口气逛完AWE的10个展馆 我观察出了三大趋势

来源&#xff1a;网易智能走进任何一个展位&#xff0c;你都可以感受到人工智能大脑的神奇之处。3月14日&#xff0c;中国家电及消费电子博览会&#xff08;AWE&#xff09;在上海开幕&#xff0c;如果说2018年AWE是AI赋能的开局之年&#xff0c;那对于2019年而言&#xff0c;A…

下一次工业革命:计算生物学与生物平台

来源&#xff1a;资本实验室人类科技的进步一直离不开两个方向的并行&#xff1a;一是不断扩大对外部世界的探索&#xff0c;例如新元素与新材料的发现、月球与火星探险、极地气候变化研究&#xff1b;一个是不断深化对我们自身身体与生命的认识&#xff0c;例如手术技术开发、…

MFC制作打地鼠小游戏

一、游戏说明如下&#xff1a; 打中老鼠加一分&#xff0c;当得分值小于10分时&#xff0c;老鼠每0.8秒出现一次&#xff0c;当得分值大于等于10分并且小于50分时&#xff0c;老鼠每0.6秒出现一次。当得分值大于等于50分时&#xff0c;老鼠每0.4秒出现一次。这个游戏是参考别人…

人机大战三周年:围棋界发生了哪些巨变?

来源&#xff1a;弈客围棋三年前的2016年3月15日&#xff0c;举世瞩目的第一次“人机大战”结束&#xff0c;代表人类出战的棋手李世石九段1比4不敌横空出世的围棋人工智能AlphaGo&#xff0c;正式宣告了围棋AI时代的开启。三年后的现在&#xff0c;围棋界的生态环境与三年前相…