`

(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
分享到:
评论

相关推荐

    通用有限状态机(FSM: Finite-state machine)自动代码生成器

    通用有限状态机(FSM: Finite-state machine)自动代码生成器. 可以根据配置文件,自动生成状态机代码(C++)。配置文件中只需要定义状态,跃迁条件。然后完善每个状态的动作即可。省去开发过程中手写状态机的麻烦。...

    简单状态机控制步进电机

    状态机是一种用于描述系统行为的模型,它按照预定义的一系列状态进行转换,每个状态对应于特定的操作或行为。 首先,我们来看看状态机的基本概念。状态机由一系列状态和转移条件组成。在步进电机控制的上下文中,...

    java实现有限状态机

    用java语言实现有限状态机,这个简单地实例能全面地诠释状态机的思想

    有限状态机(FSM)的设计与实现

    有限状态机(FSM)是表示有限个状态及在这些状态之间的转移和动作等行为的数学模型,在计算机领域有着广泛的应用。通常FSM包含几个要素:状态的管理、状态的监控、状态的触发、状态触发后引发的动作。本文主要阐述...

    C# 状态机实现

    在编程领域,状态机是一种非常重要的设计模式,它被广泛应用于各种复杂的逻辑控制流程中。在C#中,我们可以利用面向对象的特性来实现状态机,以管理对象在不同状态之间的转换。本篇将深入探讨如何在C#中实现状态机,...

    有限状态机实例

    有限状态机实例(DFA、NFA)PPT中有三个实例,过程详细。

    MSP430X2XX系列用户指南

    操作模式是指导单片机运行状态的设置,MSP430X2XX系列单片机支持不同的操作模式,如低功耗模式,这对于延长电池寿命非常重要。 6. CPU寄存器和指令集 CPU是微控制器的大脑,它负责执行指令和处理数据。MSP430X2XX...

    有限状态机的java例子

    用java编写的一个有限状态机的小程序,模拟一个机器人的活动。

    状态机资料

    状态机可以分为有限状态机(FSM)和无限状态机,其中有限状态机更常见,因为它更容易理解和实现。 2. **状态与事件**:状态是系统在特定时刻的行为表现,而事件则是触发状态转换的外部输入或内部条件。理解状态和...

    用状态机原理进行软件设计

    状态机是实现这种模块化的一种有效方法,因为它允许我们将复杂的逻辑结构转化为一系列清晰的状态转换。 状态机通常有两种类型:有限状态机(FSM)和有向无环图状态机(DFA或NFA)。有限状态机有固定数量的状态,每...

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

    状态机通常由一系列状态和事件触发的转换构成,每个状态代表系统的一个特定阶段,而转换则定义了在不同状态之间如何进行。 1. **状态机的基本结构**:一个状态机包含初始化状态、终结状态以及若干中间状态。每个...

    UML层次状态机详解

    ### UML层次状态机详解 #### 一、引言 随着软件工程的发展,特别是软件复用技术的进步,设计可复用的应用框架变得越来越重要。应用框架不仅有助于提高软件的复用性,还能够显著减少软件开发过程中的重复劳动,提高...

    EDA 有限 状态机

    在xilinx 环境下 编写程序通过控制发光二极管 显示状态机的状态。

    FSM有限状态机设计英文原版教材

    Introduction to Finite-State Machines and state Diagrams for the Design of Electronic Circuits and System。

    fsm有限状态机简单例子

    状态机原理实例,仿照比葫芦画瓢,初学者比较适合,只要明白原理接下来自己搞就比较容易,强烈推荐看看,自己再仿照练习一下

    tm16xx系列驱动程序

    例如,它可能定义了与TM16XX芯片通信的I/O端口映射,如`#define TM16XX_DATA_PIN`和`#define TM16XX_CLK_PIN`,以及相关的枚举类型来表示不同命令和状态。 在实际应用中,开发者可以根据具体使用的单片机型号,如...

    状态机源码

    它会创建一个状态机实例,初始化状态,然后处理一系列事件,展示状态机的运行过程。 在实际应用中,状态机广泛用于各种场景,如网络协议处理、硬件设备控制、游戏逻辑、任务调度等。其优点在于将状态和行为解耦,...

    从MSP430 F2xx 和 G2xx 系列迁移到 MSP430 FR4xx 和 FR2xx 系列 (Rev. E)

    由于FRAM的物理特性与闪存不同,因此FR4xx和FR2xx系列提供了不同的内存保护机制,包括内存写保护位和内存等待状态等。 6. 引导加载程序(BSL) MSP430 FR4xx和FR2xx系列提供了具有不同安全特性的BSL,用以支持...

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

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

Global site tag (gtag.js) - Google Analytics