游戏人工智能——有限状态机实验

简介: 实验四:有限状态机实验一、实验目的通过蚂蚁世界实验掌握游戏中追有限状态机算法二、实验仪器Win10下的Visualstudio三、实验原理及过程//描述有限状态机的算法原理//描述程序实现时的思路包括对每个函数模块进行详细说明有限状态机(FSM)是表示有限个状态及在这些状态之间的转移和动作等行为的数学模型,在计算机领域有着广泛的应用。通常FSM包含几个要素:状态的管理、状态的监控、状态的触发、状态触发后引发的动作。有限状态机是由寄存器组和组合逻辑构成的硬件时序电路

 实验四:有限状态机实验

一、实验目的

通过蚂蚁世界实验掌握游戏中追有限状态机算法

二、实验仪器

Win10下的Visualstudio

三、实验原理及过程

//描述有限状态机的算法原理

//描述程序实现时的思路包括对每个函数模块进行详细说明

有限状态机(FSM)是表示有限个状态及在这些状态之间的转移和动作等行为的数学模型,在计算机领域有着广泛的应用。通常FSM包含几个要素:状态的管理、状态的监控、状态的触发、状态触发后引发的动作。有限状态机是由寄存器组和组合逻辑构成的硬件时序电路。有限状态机的状态(即由寄存器组的1和0的组合状态所构成的有限个状态)只可能在同一时钟跳变沿的情况下才能从一个状态转向另一个状态。

  有限状态机的下一个状态不但取决于各个输入值,还取决于当前所在状态。这里指的是米里Mealy型有限状态机,而莫尔Moore型有限状态机的下一个状态只决于当前状态。

    1. 制作菜单

    image.gif编辑

    设置参数:点击会弹出对话框,设置一些参数,红、黑蚂蚁的家会在地图上标记出来

    运行:设置好参数后点击运行,毒药、食物、水会在地图上随机显示

    下一步:2只红蚂蚁和2只黑蚂蚁会随机出现在地图上,窗口右方还会出现红、黑蚂

    蚁当前数量的统计

    不断按下一步,有限状态机就会不断运行,使蚁群产生变化

    2)添加加速键

    资源视图中

    下方image.gif编辑

    image.gif编辑

    选择ID和键值

    image.gif编辑

    四、实验结果

    image.gif编辑

    image.gif编辑

    image.gif编辑

    image.gif编辑

    image.gif编辑

    image.gif编辑

    五、实验心得(需包括有何不足如何改进)

    //你认为你目前实现的程序有什么不足之处,如何改进

    通过有限状态机实现蚂蚁的繁殖的一个实验,代码还是有点复杂,程序还有很多需要改进的地方。代码规范还需要进一步规范,使之将代码简洁明了。

    六、主要代码

    #include "stdafx.h"

    #include "MAYI.h"

    #include "MAYIDoc.h"

    #include "MAYIView.h"

    #ifdef _DEBUG

    #define new DEBUG_NEW

    #endif

    //房子初始位置

    int kBlackHomeRow=3;

    int kBlackHomeCol=3;

    int kRedHomeRow=1;

    int kRedHomeCol=1;

          //地图参数

    #define kMaxRows 20

    #define kMaxCols 20

    #define LENGTH 20            //每格的宽度

    int terrain[kMaxRows][kMaxCols];

    //设置水,食物,毒药的数量,系统会随机分配位置

    int kMaxWater=3;    

    int kMaxPoison=3;

    int kMaxFood=6;

    //蚂蚁的状态

    #define kForage 1

    #define kGoHome 2

    #define kThirsty 3

    #define kDead 4

    //计数初始化

    int RedNum=2;

    int BlackNum=2;

    //蚂蚁组别

    #define kRedAnt 1

    #define kBlackAnt 2

    //地形值

    #define kGround 1

    #define kWater 2

    #define kBlackHome 3

    #define kRedHome 4

    #define kPoison 5

    #define kFood 6

    #define RedHomeRow 5;

    #define RedHomeCol 5;

    #define BlackHomeRow 1;

    #define BlackHomeCol  1;

    //随机函数

    int Rnd(int min, int max)

    {

          int result;

          do{

                 result=rand()%max;

          }while(result<=min);

          return result;

    }

    //蚂蚁类

    class ai_Entity{

    public:

          int type;

          int state;

          int row;

          int col;

          ai_Entity();

          ~ai_Entity() {}

         

          void New (int theType,int theState,int theRow,int theCol);

          void Forage();

          void GoHome();

          void Thirsty();

          void Dead();

    };

    ai_Entity::ai_Entity()

    {

          type=0;

          state=0;

          row=0;

          col=0;

    }

    void ai_Entity::New(int theType, int theState,int theRow,int theCol)

    {

          type=theType;

          row=theRow;

          col=theCol;

          state=theState;

    }

    #define kMaxEntities 200

    ai_Entity entityList[kMaxEntities];

    //标志位

    bool FLAG=false;

    //寻找食物的状态

    void ai_Entity::Forage()

    {

          int rowMove;

          int colMove;

          int newRow;

          int newCol;

          int foodRow;

          int foodCol;

          int poisonRow;

          int poisonCol;

          rowMove=Rnd(-1,3)-1;   //通过随机函数设定行方向要移动的距离

          colMove=Rnd(-1,3)-1;   //通过随机函数设定列方向要移动的距离

          newRow=row+rowMove;    //新的行的位置

          newCol=col+colMove;     //新的列的位置

         

          if(newRow<0)

                 return;

          if(newCol<0)

                 return;

          if(newRow>=kMaxRows)

                 return;

          if(newCol>=kMaxCols)

                 return;

          //如果下一个位置是地面或者水,不改变蚂蚁的状态,直接赋予新的位置

          if((terrain[newRow][newCol]==kGround)||(terrain[newRow][newCol]==kWater))

          {

                 row=newRow;

                 col=newCol;

          }

          //如果下一个位置是食物,在更新位置之后还要去掉食物,改变蚂蚁的状态

          if(terrain[newRow][newCol]==kFood)

          {

                 row=newRow;

                 col=newCol;

                 terrain[row][col]=kGround;

                 state=kGoHome;             //状态变为回家的状态

                 do{

                        foodRow=Rnd(-1,kMaxRows);

                        foodCol=Rnd(-1,kMaxCols);

                 }while(terrain[foodRow][foodCol]!=kGround);

                 terrain[foodRow][foodCol]=kFood;          //设置新的食物位置

          }

          if(terrain[newRow][newCol]==kPoison)

          {

                 row=newRow;

                 col=newCol;

                 terrain[row][col]=kGround;

                 state=kDead;                 //如果遇到毒药,状态变为死

                 do{

                        poisonRow=Rnd(-1,kMaxRows);

                        poisonCol=Rnd(-1,kMaxCols);

                 }while(terrain[poisonRow][poisonCol]!=kGround);

                 terrain[poisonRow][poisonCol]=kPoison;   //设置新的毒药位置

          }

    }

    void ai_Entity::GoHome()

    {

          int rowMove;

          int colMove;

          int newRow;

          int newCol;

          int homeRow;

          int homeCol;

          int poisonRow;

          int poisonCol;

          int i;

          if(type==kRedAnt)

          {

                 homeRow=RedHomeRow;

                 homeCol=RedHomeCol;

          }

          else

          {

                 homeRow=BlackHomeRow;

                 homeCol=BlackHomeCol;

          }

    //渐渐逼近家里

          if(row<homeRow)

                 rowMove=1;

          else if(row>homeRow)

                 rowMove=-1;

          else

                 rowMove=0;

          if(col<homeCol)

                 colMove=1;

          else if(col>homeCol)

                 colMove=-1;

          else

                 colMove=0;

          newRow=row+rowMove;

          newCol=col+colMove;

          if(newRow<0)

                 return;

          if(newCol<0)

                 return;

          if(newRow>=kMaxRows)

                 return;

          if(newCol>=kMaxCols)

                 return;

          if(terrain[newRow][newCol]!=kPoison)

          {

                 row=newRow;

                 col=newCol;

          }

          else

          {

                 row=newRow;

                 col=newCol;

                 terrain[row][col]=kGround;

                 state=kDead;

                 do{

                        poisonRow=Rnd(-1,kMaxRows);

                        poisonCol=Rnd(-1,kMaxCols);

                 }while(terrain[poisonRow][poisonCol]!=kGround);

                 terrain[poisonRow][poisonCol]=kPoison;             //回家的过程碰到毒药还是死

          }

          if((newRow==homeRow)&&(newCol==homeCol))

          {

                 row=newRow;

                 col=newCol;

                 state=kThirsty;//回家后状态变为饥渴

                 for(i=0;i<kMaxEntities;i++)

                        if(entityList[i].type==0)

                        {

                               entityList[i].New(type,kForage,homeRow,homeCol);//产生新的蚂蚁

                               if(type==kRedAnt)                               //如果是红蚂蚁则新蚂蚁也是红的

                                      RedNum++;

                               if(type==kBlackAnt)                                                      //如果是黑蚂蚁则新蚂蚁也是黑的

                                      BlackNum++;

                               break;

                        }

                             

          }

    }

    void ai_Entity::Thirsty()

    {

          int rowMove;

          int colMove;

          int newRow;

          int newCol;

          int foodRow;

          int foodCol;

          int poisonRow;

          int poisonCol;

          rowMove=Rnd(-1,3)-1;

          colMove=Rnd(-1,3)-1;

          newRow=row+rowMove;

          newCol=col+colMove;

          if(newRow<0)

                 return;

          if(newCol<0)

                 return;

          if(newRow>=kMaxRows)

                 return;

          if(newCol>=kMaxCols)

                 return;

          if((terrain[newRow][newCol]==kGround)||(terrain[newRow][newCol]==kFood))

          {

                 row=newRow;

                 col=newCol;

          }

          if(terrain[newRow][newCol]==kWater)

          {

                 row=newRow;

                 col=newCol;

                 terrain[row][col]=kGround;

                 state=kForage;                      //找到水后状态变为寻找

                 do{

                        foodRow=Rnd(-1,kMaxRows);

                        foodCol=Rnd(-1,kMaxCols);

                 }while(terrain[foodRow][foodCol]!=kGround);

                 terrain[foodRow][foodCol]=kWater;

          }

          if(terrain[newRow][newCol]==kPoison)

          {

                 row=newRow;

                 col=newCol;

                 terrain[row][col]=kGround;

                 state=kDead;

                 do{

                        poisonRow=Rnd(-1,kMaxRows);

                        poisonCol=Rnd(-1,kMaxCols);

                 }while(terrain[poisonRow][poisonCol]!=kGround);

                 terrain[poisonRow][poisonCol]=kPoison;

          }

    }

    //蚂蚁死后计数减少

    void ai_Entity::Dead()

    {

          if(type==kRedAnt)

                 RedNum--;

          if(type==kBlackAnt)

                 BlackNum--;

          type=0;

    }

    // CMAYIView

    IMPLEMENT_DYNCREATE(CMAYIView, CView)

    BEGIN_MESSAGE_MAP(CMAYIView, CView)

          // 标准打印命令

          ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)

          ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)

          ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)

          ON_COMMAND(ID_START, &CMAYIView::OnStart)

          ON_COMMAND(ID_SET, &CMAYIView::OnSet)

    END_MESSAGE_MAP()

    // CMAYIView 构造/析构

    CMAYIView::CMAYIView()

    {

          // TODO: 在此处添加构造代码

    }

    CMAYIView::~CMAYIView()

    {

    }

    BOOL CMAYIView::PreCreateWindow(CREATESTRUCT& cs)

    {

          // TODO: 在此处通过修改

          //  CREATESTRUCT cs 来修改窗口类或样式

          return CView::PreCreateWindow(cs);

    }

    // CMAYIView 绘制

    void CMAYIView::OnDraw(CDC* pDC)

    {

          CMAYIDoc* pDoc = GetDocument();

          ASSERT_VALID(pDoc);

          if (!pDoc)

                 return;

          // TODO: 在此处为本机数据添加绘制代码

          int i,j;

          //绘制网格

          for(i=0;i<=LENGTH*kMaxRows;i+=LENGTH)

          {

                 //画横线

                 pDC->MoveTo(0,i);

                 pDC->LineTo(LENGTH*kMaxCols,i);

          }

          for(i=0;i<=LENGTH*kMaxCols;i+=LENGTH)

          {

                 //画竖线

                 pDC->MoveTo(i,0);

                 pDC->LineTo(i,LENGTH*kMaxRows);

          }

         

               

          if(FLAG)

          {

               

                 //初始化房子

               

                 pDC->SetTextColor(RGB(0,0,0));

                 pDC->TextOutW(kBlackHomeCol*LENGTH+3,kBlackHomeRow*LENGTH+3,L"H");

               

                 pDC->SetTextColor(RGB(255,0,0));

                 pDC->TextOutW(kRedHomeCol*LENGTH+3,kRedHomeRow*LENGTH+3,L"H");

          }

          //在地图上更新水(W),毒药(P),食物(F)  

          for(i=0;i<kMaxRows;i++)

          {

                 for(j=0;j<kMaxCols;j++)

                 {

                        if(terrain[i][j]==kWater)

                        {

                               pDC->SetTextColor(RGB(0,192,255));

                               pDC->TextOutW(i*LENGTH+3,j*LENGTH+3,L"W");

                        }

                        else if(terrain[i][j]==kPoison)

                        {

                               pDC->SetTextColor(RGB(160,0,120));

                               pDC->TextOutW(i*LENGTH+3,j*LENGTH+3,L"P");

                        }

                        else if(terrain[i][j]==kFood)

                        {

                               pDC->SetTextColor(RGB(255,216,0));

                               pDC->TextOutW(i*LENGTH+3,j*LENGTH+3,L"F");

                        }

                 }    

          }

         

         

          //在地图上更新蚂蚁的位置

          for(i=0;i<kMaxEntities;i++)

          {

                 if(entityList[i].type==kRedAnt)

                 {

                        pDC->SetTextColor(RGB(255,0,0));

                        pDC->TextOutW(entityList[i].col*LENGTH+1,entityList[i].row*LENGTH+1,L"A");

                 }

                 if(entityList[i].type==kBlackAnt)

                 {

                        pDC->SetTextColor(RGB(0,0,0));

                        pDC->TextOutW(entityList[i].col*LENGTH+1,entityList[i].row*LENGTH+1,L"A");

                                     

                 }

                 //显示蚂蚁,食物,水,毒药的数量

                 CString s;

                 s.Format(_T("红色蚂蚁:%d"),RedNum);

                 pDC->TextOutW(23*LENGTH,0,s);

                 s.Format(_T("黑色蚂蚁:%d"),BlackNum);

                 pDC->TextOutW(23*LENGTH,2*LENGTH,s);

                 s.Format(_T("食物数量:%d"),kMaxFood);

                 pDC->TextOutW(23*LENGTH,4*LENGTH,s);

                 s.Format(_T("水数量:%d"),kMaxWater);

                 pDC->TextOutW(23*LENGTH,6*LENGTH,s);

                 s.Format(_T("毒药数量:%d"),kMaxPoison);

                 pDC->TextOutW(23*LENGTH,8*LENGTH,s);

         

          }

    }

    // CMAYIView 打印

    BOOL CMAYIView::OnPreparePrinting(CPrintInfo* pInfo)

    {

          // 默认准备

          return DoPreparePrinting(pInfo);

    }

    void CMAYIView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)

    {

          // TODO: 添加额外的打印前进行的初始化过程

    }

    void CMAYIView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)

    {

          // TODO: 添加打印后进行的清理过程

    }

    // CMAYIView 诊断

    #ifdef _DEBUG

    void CMAYIView::AssertValid() const

    {

          CView::AssertValid();

    }

    void CMAYIView::Dump(CDumpContext& dc) const

    {

          CView::Dump(dc);

    }

    CMAYIDoc* CMAYIView::GetDocument() const // 非调试版本是内联的

    {

          ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMAYIDoc)));

          return (CMAYIDoc*)m_pDocument;

    }

    #endif //_DEBUG

    // CMAYIView 消息处理程序

    //执行菜单的函数,根据蚂蚁的状态进入对应的函数

    void CMAYIView::OnStart()

    {

               

          // TODO: 在此添加命令处理程序代码

                 for(int i=0;i<kMaxEntities;i++)

                 {

                        switch(entityList[i].state)

                        {

                               case kForage:

                                      entityList[i].Forage();

                                      break;

                                     

                               case kGoHome:

                                      entityList[i].GoHome();

                                      break;

                               case kThirsty:

                                      entityList[i].Thirsty();

                                      break;

                               case kDead:

                                      entityList[i].Dead();

                                      break;

                               default:

                                      break;

                        }

                 }

                 Invalidate();

    }

    //设置菜单的函数

    void CMAYIView::OnSet()

    {

          // TODO: 在此添加命令处理程序代码

         

          //初始化蚂蚁位置

          entityList[0].New(kRedAnt,kForage,5,5);

          entityList[1].New(kRedAnt,kForage,8,5);

          entityList[2].New(kBlackAnt,kForage,5,8);

          entityList[3].New(kBlackAnt,kForage,9,9);

         

          //先把地图都设置成地面

          int i,j;

          for(i=0;i<kMaxRows;i++)

                 for(j=0;j<kMaxCols;j++)

                 {

                        terrain[i][j]=kGround;

                 }

          //定位红黑蚂蚁房子的坐标

          terrain[kRedHomeRow][kRedHomeCol]=kRedHome;

          terrain[kBlackHomeRow][kBlackHomeCol]=kBlackHome;

         

          srand(time(NULL)); //取系统时间为随机种子

         

          //根据程序开始定义的kMaxWater,kMaxPoison,kMaxFood,随机定位水,毒药,食物的位置

          int r,c;

          for(i=0;i<kMaxWater;i++)

          {

                 r=Rnd(-1,kMaxRows);

                 c=Rnd(-1,kMaxCols);

                 if(terrain[r][c]==kGround)

                        terrain[r][c]=kWater;

                 else

                        i--;

          }

          for(i=0;i<kMaxPoison;i++)

          {

                 r=Rnd(-1,kMaxRows);

                 c=Rnd(-1,kMaxCols);

                 if(terrain[r][c]==kGround)

                        terrain[r][c]=kPoison;

                 else

                        i--;

          }

          for(i=0;i<kMaxFood;i++)

          {

                 r=Rnd(-1,kMaxRows);

                 c=Rnd(-1,kMaxCols);

                 if(terrain[r][c]==kGround)

                        terrain[r][c]=kFood;

                 else

                        i--;

          }

          FLAG = true;  //初始化完毕后,FLAG变真

          Invalidate();

    }


    相关文章
    |
    2月前
    |
    机器学习/深度学习 人工智能 自然语言处理
    软件测试中的人工智能:改变游戏规则的革新
    在这篇技术性文章中,我们将深入探讨人工智能(AI)如何彻底改变了软件测试领域。从自动化测试到智能缺陷检测,AI不仅提高了测试的效率和准确性,还为软件开发团队提供了前所未有的洞察力。通过具体案例,本文揭示了AI在软件测试中应用的现状、挑战及未来趋势,强调了技术创新在提升软件质量与开发效率中的关键作用。
    |
    2月前
    |
    机器学习/深度学习 人工智能 自然语言处理
    软件测试中的人工智能:改变游戏规则的技术革命
    【10月更文挑战第10天】 本文深入探讨了人工智能在软件测试中的应用,揭示了它如何提高测试效率、减少人为错误,并预示了未来软件测试行业的发展趋势。通过案例分析和原理讲解,文章展现了AI技术在自动化测试、缺陷检测和性能评估等方面的巨大潜力。
    |
    4月前
    |
    机器学习/深度学习 人工智能 自然语言处理
    【机器学习】python之人工智能应用篇--游戏生成技术
    游戏生成技术,特别是生成式人工智能(Generative Artificial Intelligence, 简称Generative AI),正逐步革新游戏开发的多个层面,从内容创作到体验设计。这些技术主要利用机器学习、深度学习以及程序化内容生成(Procedural Content Generation, PCG)来自动创造游戏内的各种元素,显著提高了开发效率、丰富了游戏内容并增强了玩家体验。以下是生成式AI在游戏开发中的几个关键应用场景概述
    88 2
    |
    7月前
    |
    机器学习/深度学习 人工智能 自然语言处理
    【AI 生成式】生成式人工智能如何在虚拟现实和游戏中使用?
    【5月更文挑战第4天】【AI 生成式】生成式人工智能如何在虚拟现实和游戏中使用?
    |
    机器学习/深度学习 人工智能 TensorFlow
    人工智能实验 python tensorflow keras拟合正弦函数,工资预测,公司收益预测
    人工智能实验 python tensorflow keras拟合正弦函数,工资预测,公司收益预测
    87 0
    |
    人工智能 搜索推荐 vr&ar
    AIGC:引领人工智能和游戏产业融合的里程碑
    AIGC:引领人工智能和游戏产业融合的里程碑
    211 0
    |
    人工智能 自然语言处理
    人工智能大模型这场游戏才刚刚开始吗?还是在走下坡路?
    自人工智能研究实验室OpenAI推出chatGPT发布以来,人们对自然语言大模型的关注度倍增,国内各大厂以及各路大佬都纷纷入局,计划开发自己的人工智能大模型,或以chatGPT为基础开发自己人工智能产品。
    151 1
    |
    数据采集 人工智能 算法
    合工大-人工智能原理实验报告
    合工大-人工智能原理实验报告
    181 0
    |
    机器学习/深度学习 人工智能 自然语言处理
    英雄联盟、Dota 2等电竞游戏蓬勃发展,人工智能起大作用
    英雄联盟、Dota 2等电竞游戏蓬勃发展,人工智能起大作用
    166 0
    |
    机器学习/深度学习 人工智能 自然语言处理
    AIGC未来畅想:探讨人工智能与游戏创作的发展融合
    AIGC未来畅想:探讨人工智能与游戏创作的发展融合
    258 0