(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
*/
### 不同单片机及相关实时操作系统的概述 #### 51 单片机的技术特点与应用案例 51 单片机是一种经典的 8 位微控制器架构,广泛应用于嵌入式系统开发中。其主要特点是结构简单、成本低且易于学习,适合初学者入门。常见的应用场景包括家用电器控制、工业自动化设备中的数据采集模块以及简单的通信接口设计[^1]。 ```c #include <reg52.h> void delay(unsigned int time){ while(time--); } void main(){ P1 = 0xFF; // 初始化端口P1为高电平 while(1){ P1_0 = ~P1_0; // 反转P1.0引脚状态 delay(6000); // 延时函数调用 } } ``` 上述代码展示了如何通过编程实现 LED 的闪烁功能,在实际项目中可以扩展到更多复杂的功能实现上。 --- #### STM32 系列单片机的特点及其典型用途 STM32 是基于 ARM Cortex-M 内核的一类高性能 32 位 MCU 家族产品线之一。它具有丰富的外设资源(如 SPI、I²C 和 USB 接口),强大的计算能力和较低功耗特性使其成为物联网(IoT)节点的理想选择对象。 下面是一个使用 HAL 库初始化串口并发送字符串的例子: ```c #include "stm32f1xx_hal.h" UART_HandleTypeDef huart1; int main(void){ HAL_Init(); MX_USART1_UART_Init(); char *msg="Hello World!"; HAL_UART_Transmit(&huart1,(uint8_t*) msg,strlen(msg),HAL_MAX_DELAY); while (1){} } static void SystemClock_Config(void){...} /* 配置系统时钟 */ static void MX_GPIO_Init(void){...} /* GPIO 初始设置 */ static void MX_USART1_UART_Init(void){...}/* USART1 UART 设置*/ ``` 此程序片段说明了利用官方提供的硬件抽象层(HAL Library),简化驱动编写过程的同时提高了可移植性和可靠性。 --- #### STM8S207 特定型号介绍及其实战经验分享 作为 STMicroelectronics 生产的一款经济高效的解决方案——STM8S207 提供高达 128KB Flash 存储空间和多种通讯协议支持选项。对于预算有限但又追求一定性能水平的应用场合非常合适,比如电机速度调节器或者环境监测仪器等领域都可见它的身影. --- #### PY32F003 芯片亮点解析 PY32F003 属于超值型系列成员之一,专为满足低成本需求而优化设计而成;尽管如此,该器件仍然保留了一些关键特性的优势,例如内置 ADC 功能用于模拟信号处理能力等方面表现出色。因此非常适合那些对价格敏感的小规模生产制造企业采用. --- #### GD32F103 性能参数对比分析 GD32F103 是由兆易创新推出的兼容性强的通用MCU平台,具备良好的性价比表现。除了常规的任务执行效率之外,还特别强调能源管理方面的改进措施,从而延长电池供电产品的续航时间。这使得它们成为了便携电子消费品市场的热门选手之一. --- #### FreeRTOS 实时操作系统基础概念讲解 FreeRTOS 是一种轻量级开源 RTOS ,专门为小型嵌入式目标构建。它允许开发者创建多任务应用程序,并提供诸如队列、互斥锁之类的同步机制来协调这些任务之间的交互行为模式。由于源码完全公开可用的缘故,所以可以根据具体项目的特殊要求自由裁剪定制版本大小以便适应不同的存储容量限制条件下的运行环境. 以下是启动两个独立任务的一个基本实例演示: ```c TaskHandle_t Task1, Task2 ; void vTaskFunction1(void *pvParameters ){ for (;;){ printf("Task1 Running\n"); vTaskDelay(pdMS_TO_TICKS(500)); } } void vTaskFunction2(void *pvParameters ){ for (;;){ printf("Task2 Running\n"); vTaskDelay(pdMS_TO_TICKS(1000)); } } int main() { xTaskCreate(vTaskFunction1,"task1",configMINIMAL_STACK_SIZE,NULL ,1,&Task1 ); xTaskCreate(vTaskFunction2,"task2",configMINIMAL_STACK_SIZE,NULL ,1,&Task2 ); vTaskStartScheduler(); return 0; } ``` --- #### μC/OS-II & III 主要区别探讨 μC/OS-II 和 μC/OS-III 同属 Micrium 开发维护的产品序列,二者均属于商业性质较强的硬实时内核类别。不过随着技术进步迭代更新之后诞生的新一代产物即 μC/OS-III,则进一步增强了原有框架下所能承载的最大优先级数量范围上限至多达 256 级别之多,同时还引入了许多现代化软件工程实践理念进去,像动态内存分配策略调整等等都是其中比较重要的改动方向所在之处. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值