`

(00XX系列)搞搞有限状态机

阅读更多
        需要修改游戏中的一些AI,自己做了个小模型。一些头/源文件随便塞了。严格来说FSM不算是一个AI的思路。
        对于一个FSM,基本的要有如下的东西:
一些若干的状态指示变量;一张状态转换表;一个根据状态转换表进行描述行为的函数。如果还有其他需求也是根据以上进行增加额外的数据。比如游戏的一些NPC通常有不同的AI选择,但是行为表是一样的,所以就得增加一张根据NPC查询到AI的索引表。示例代码里简化为了一张。比如你还可以加一些从坑里爬出拍手,眩晕,平衡度等状态。
        在该代码里总的表示如下:一个人在路上走的状态,根据路况不同,做出不同反应。
// 编译环境VS2008
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//

#pragma once

#include "targetver.h"

#include <iostream>

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <stdlib.h>


/*
  人的类别,有聪明,傻子等
  这里值的索引从0开始,跟最后的fsm_table匹配。你也可以设成自己喜欢的值,麻烦的是自己加个映射的转换
*/
namespace ROLE_TYPE
{
    const int ROLE_TYPE_Bright = 0;     
    const int ROLE_TYPE_Average = 1;
    const int ROLE_TYPE_Stupid = 2;   
};

/*
  FSM_ROLE_ACTION,FSM_ROAD_ACTION这两个空间表示人和道路的动作(你可以把道路看成一个活的)
*/

namespace FSM_ROLE_ACTION
{
    const int ROLE_ACTION_Normal = 101;     //状态--无状态,表示正常行走
    const int ROLE_ACTION_DropHole = 102;   //状态--掉入坑中
    const int ROLE_ACTION_ClimbHole = 103;  //过程--爬出坑外
    const int ROLE_ACTION_RoundHole = 104;  //过程--绕过坑
};

namespace FSM_ROAD_ACTION
{
    const int ROAD_ACTION_End = -1;       //道路结束
    const int ROAD_ACTION_Normal = 0;     //平坦的道路
    const int ROAD_ACTION_Hole = 1;       //有坑
};

using namespace std;
using namespace FSM_ROLE_ACTION;
using namespace FSM_ROAD_ACTION;
using namespace ROLE_TYPE;

// TODO: 在此处引用程序需要的其他头文件


// 1.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"


/*
  最终的一个动作指示表
*/
const int ROAD_ACTION = 3;		//路况指示
int fsm_state_table[][ROAD_ACTION]=		  
		  /*平坦的道路		   有坑					  采取的措施*/
{
/*聪明人*/{ROLE_ACTION_Normal, ROLE_ACTION_RoundHole, ROLE_ACTION_Normal},
/*略聪明*/{ROLE_ACTION_Normal, ROLE_ACTION_DropHole,  ROLE_ACTION_ClimbHole},
/*笨人  */{ROLE_ACTION_Normal, ROLE_ACTION_DropHole,  ROLE_ACTION_DropHole}
};

/*
  简单的一个人物FSM类,为了模拟一些有意思的状态
  可以做为一个组合给最终的人物类。
*/
class CRole_Buffoon_Fsm
{
public:
	int IQ;
	int ActionPendingIndex;		//待处理的状态,相当于输入,即道路的状态索引
	int ActionCurrent;			//当前人物状态
	int ActionCurrentTime;		//当前人物状态维持的时间,比如爬,掉等。这里统一设成2秒
	//int nCountAcionCurrent;	//处于当前状态几次

	CRole_Buffoon_Fsm(int iq)
	{
		IQ = iq;
		//nCountAcionCurrent = 0;
		ActionCurrentTime = 0;
		ActionPendingIndex = 0;
		ActionCurrent = ROLE_ACTION_Normal;
	}


	void Say();             //根据当前状态和次数说一些有意思的话
	void SetPendingTime();  //根据状态设置时间
	void fsm_driver();		//状态转换(俗称的一个对应状态转换函数) 
	void fsm_fame_role();
};

void CRole_Buffoon_Fsm::SetPendingTime()
{
	//估计该动作时间,这里可以直接映射时间参数
	if( ROLE_ACTION_Normal==ActionCurrent || ROLE_ACTION_DropHole==ActionCurrent )
	{
		ActionCurrentTime = 0;
	}
	else
	{
		ActionCurrentTime = 2;
	}	
}

void CRole_Buffoon_Fsm::Say()
{
	switch (ActionCurrent)
	{
	case ROLE_ACTION_Normal:
		cout<<"很正常。。"<<endl;
		break;
	case ROLE_ACTION_DropHole:
		cout<<"咋掉进来了"<<endl;
		break;
	case ROLE_ACTION_ClimbHole:
		cout<<"还在爬呢."<<endl;
		break;
	case ROLE_ACTION_RoundHole:
		cout<<"狗日的,哪个给弄了个坑,爷我慢慢绕过去!"<<endl;
		break;
	default:
		
		break;
	}
}


void CRole_Buffoon_Fsm::fsm_driver()
{
	//从输入的路况中取得人物的动作
	ActionCurrent = fsm_state_table[IQ][ActionPendingIndex];
	SetPendingTime();	
}

void CRole_Buffoon_Fsm::fsm_fame_role()
{
	switch (ActionCurrent)
	{
	case ROLE_ACTION_Normal:
		//正常,无动作
		break;
	case ROLE_ACTION_DropHole:
		//掉入坑了,给他措施的动作
		ActionCurrent = fsm_state_table[IQ][2];
		SetPendingTime();
		break;

	case ROLE_ACTION_ClimbHole:
		if( ActionCurrentTime>0 )
		{
			if( 0==--ActionCurrentTime )
			{
				ActionCurrent = ROLE_ACTION_Normal;
			}
		}
		break;

	case ROLE_ACTION_RoundHole:
		if( ActionCurrentTime>0 )
		{
			if( 0==--ActionCurrentTime )
			{
				ActionCurrent = ROLE_ACTION_Normal;
			}
		}
		break;

	default:
		break;
	}

	Say();
}

int _tmain(int argc, _TCHAR* argv[])
{
	CRole_Buffoon_Fsm RoleBright(ROLE_TYPE_Bright);
	CRole_Buffoon_Fsm RoleStupid(ROLE_TYPE_Stupid);
	CRole_Buffoon_Fsm RoleAverage(ROLE_TYPE_Average);

	CRole_Buffoon_Fsm* pRole[] = { &RoleBright, &RoleStupid, &RoleAverage};

	//模拟一张道路图,假设是输入的状况
	//路况分别是     正常,坑,正常,坑
	int map_road[]={ROAD_ACTION_Normal, ROAD_ACTION_Hole};

	int nCountTimes=0;
	for(int i = 0; i<_countof(pRole); ++i)
	{
		int j;
		j=-1;
		while( nCountTimes<10 )
		{
			//当人物状态为正常时,才输入下一个道路情况
			if( pRole[i]->ActionCurrent == ROLE_ACTION_Normal )
			{
				if( ++j >= _countof(map_road) )
				{
					break;
				}
				pRole[i]->ActionPendingIndex = map_road[j];
				pRole[i]->fsm_driver();
			}
			pRole[i]->fsm_fame_role();

			Sleep(1000);
			++nCountTimes;
		}

		cout<<"role:"<<i<<"花费时间:"<<nCountTimes<<endl<<endl;
		nCountTimes=0;
	}

	return 0;
}



/*输出结果
很正常。。
狗日的,哪个给弄了个坑,爷我慢慢绕过去!
很正常。。
role:0花费时间:3

很正常。。
咋掉进来了
咋掉进来了
咋掉进来了
咋掉进来了
咋掉进来了
咋掉进来了
咋掉进来了
咋掉进来了
咋掉进来了
role:1花费时间:10

很正常。。
还在爬呢.
还在爬呢.
很正常。。
role:2花费时间:4
*/
1
0
分享到:
评论

相关推荐

    C语言高效有限状态机(FSM)详细设计说明书.docx

    有限状态机(Finite State Machine, FSM)是一种模型理论,它将一个系统的行为描述为一系列可切换的状态,以及这些状态之间的转换。这种模型在IT领域中广泛应用,特别是在嵌入式系统、软件工程、硬件设计、编译器...

    一个有趣的有限状态机的JAVA实现

    在Java中实现有限状态机,我们通常会定义一个枚举类来表示状态,一个类来表示状态机,以及一系列方法来处理状态间的转换。例如,我们可以创建一个`State`枚举,包含“打开冰箱”、“放入大象”和“关闭冰箱”等状态...

    C++实现的分层有限状态机v0.1

    《C++实现的分层有限状态机v0.1详解》 在计算机科学中,有限状态机(Finite State Machine, FSM)是一种模型,用于描述一个系统的行为,它根据当前状态和输入来决定如何转移到下一个状态。分层有限状态机...

    一个有限状态机的例子

    有限状态机(Finite State Machine, FSM)是一种计算模型,它由一组状态、一个初始状态、一组转换规则以及一个或多个终止状态组成。在计算机科学中,有限状态机被广泛应用于各种领域,包括编译器设计、网络协议解析...

    从STM32F4xx系列移植到GD32F4xx系列移值的差异.pdf

    从STM32F4xx系列移植到GD32F4xx系列的移植说明,主要涉及到对国产MCU(微控制器单元)的了解,以及如何在不同厂商的产品之间进行转换。以下是详细的知识点说明: 1. 移植背景和简介 STM32F4xx系列是基于ARM® ...

    状态机的C语言编程

    "状态机的C语言编程" 状态机是一种重要的工具,在软件领域中广泛应用于硬件控制电路设计和软件处理方法。...状态机的C语言编程需要了解状态机的实现方式、状态机的两种写法和有限状态机的工作原理。

    最好的状态机源代码

    状态机的核心思想是将对象的行为分解为一系列可识别的状态,并定义了状态之间的转换规则。在C#中实现状态机,通常有两种方式:枚举型状态机和类型态机。这个5星评价的源代码可能采用了其中一种或两种方法,甚至可能...

    基于STM32 状态机工程.zip

    在这个提供的工程中,文件“状态机程序”很可能包含了状态机的实现代码,可能包括状态枚举、状态处理函数以及状态切换的逻辑。为了充分利用这个资源,你需要打开源代码,理解现有的状态机结构,然后根据你的应用程序...

    【Cocos2d-x 状态机篇】第03章源码

    状态机是一种行为设计模式,它将一个对象的行为分解为一系列可枚举的状态,并定义了这些状态之间的转换规则。在Cocos2d-x中,状态机常用于处理角色、NPC(非玩家角色)或者游戏场景的各种行为,如行走、攻击、防御、...

    一个简单好用的labview状态机

    在这个“一个简单好用的labview状态机”中,我们将深入探讨如何利用LabVIEW构建高效、灵活的状态机模型,以及它在各种项目中的应用。 状态机是一种设计模式,用于描述系统或对象在不同时间的行为变化。在LabVIEW中...

    C语言实现的状态机

    状态机是一种设计模式,常用于处理具有不同状态和行为转换的系统。在C语言中,我们可以用多种方式来实现状态机,包括使用`switch-case`结构和查表法。这两种方法各有优缺点,适用于不同的场景。 首先,让我们讨论`...

    C语言实现有限状态机之模拟程序2

    C语言实现有限状态机之模拟程序2,网上直接COPY的,面向对象的

    一段、两端、三段式状态机设计原理详解

    状态机设计原理是数字逻辑设计中的一个重要概念,它以一种结构化的方法来设计电路,使得电路能够按照预定的规则和状态序列进行工作。状态机根据其结构和功能的不同,可以被分为多种类型,其中最典型的有摩尔(Moore)...

    Sick激光扫描仪(1XX系列和5XX系列)数据协议

    根据给定的文件信息,以下是Sick激光扫描仪(1XX系列和5XX系列)数据协议的详细知识点: 首先,Sick LMS 1XX和5XX系列激光扫描仪是工业领域中常见的测量设备,它们通过激光脉冲对周围环境进行精确的测距和检测。...

    基于状态机的嵌入式系统开发

    基于状态机的嵌入式系统开发是当前流行、前景广阔的嵌入式系统开发方法。本书是基于状态机的嵌入式系统开发的入门指导书,兼顾理论性与实践性,介绍了嵌入式系统及状态机的基础知识,同时加入了生动的实际案例程序。...

    用状态机原理进行软件设计.pdf 及源码

    状态机通常分为两种类型:确定性有限状态机(DFSM)和非确定性有限状态机(NFDM),在实际应用中,我们主要使用确定性有限状态机。 1. **状态**:状态是系统在特定时刻的属性集合,代表了系统的一种行为模式。例如...

    状态机方式实现多个独立按键扫描

    状态机是一种设计模式,常用于处理具有多种状态和转换条件的系统,比如在嵌入式系统中用于按键扫描。在本程序中,我们利用状态机的方式实现对STM32F429单片机上多个独立按键的扫描。STM32F429是一款高性能的ARM ...

    状态机按键 多个独立按键识别 单击 双击 长按 2019.12.30.zip

    状态机,全称为有限状态机(Finite State Machine,FSM),是一种模型化复杂逻辑行为的有效工具。在按键识别中,状态机通过切换不同的状态来响应按键的不同事件,如按下、释放以及连续按下等。状态机的每个状态代表...

    VisualState6.2 状态机图形化工具

    《VisualState 6.2:状态机图形化设计利器》 在嵌入式软件开发领域,状态机(Finite State Machine, FSM)作为一种强大的设计模式,被广泛应用以处理系统中的复杂逻辑和状态转换。VisualState 6.2 正是这样一款专为...

    NXP_S32K1xx EEPROM中文使用手册

    【NXP S32K1xx EEPROM中文使用手册】提供了关于恩智浦S32K系列微控制器中集成EEPROM的详细使用指南。S32K1xx EEPROM是一种高效的存储解决方案,它允许用户灵活地配置片上闪存作为增强型EEPROM、额外闪存或者两者的...

Global site tag (gtag.js) - Google Analytics