⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aigenerator.cpp

📁 Visual C++ 游戏开发与设计实例 源代码(所有)
💻 CPP
字号:

#include "global.h"
#include "aigenerator.h"

//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
CAiGenerator::CAiGenerator() {
	SetRect( &m_rtAvoid[0], 0, 0, 0, 0 );
	m_pAim = NULL;
	m_nAimProb = 0;
	m_nTrackProb = 3;

	m_nMaxProb = DEFMAXPROB;				
	m_nCurrentProb = 0;
	
	ZeroMemory(CmdProbs, sizeof(int)*6);

	m_nFireMaxProb = 16;	// maybe 1 shot per step of 2 block at speed of 4
	m_nFireProb = 1;

	m_bLastBlock = false;
	m_LastCmd.cmd = CMD_DOWN;		// !!!Don't change this
	m_LastCmd.fire = false;
	m_LastAim = NULL;

}

//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
CAiGenerator::~CAiGenerator() {
}

//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
bool CAiGenerator::CreateGenerator( CObjTank *ptk, RECT scope ) {
	m_pHost = ptk;
	m_rtScope = scope;
	m_LastPos = ptk->GetRect();
	return true;
}

//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
void CAiGenerator::SetAim( CMobileObject *pmo, int prob ) {
	m_pAim = pmo;
	if ( prob < 0 )
		m_nAimProb = m_nMaxProb;
	else
		m_nAimProb = prob;
}

//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
void CAiGenerator::SetAvoid ( RECT	rt ) {
	// r, d, u, l
	SetRect( &m_rtAvoid[DIR_RIGHT], 0, rt.top-24, rt.left, rt.bottom-24 );
	SetRect( &m_rtAvoid[DIR_DOWN], rt.left-24, 0, rt.right-24, rt.top );
	SetRect( &m_rtAvoid[DIR_UP], rt.left-24, rt.top, rt.right-24, g_FrameWidth );
	SetRect( &m_rtAvoid[DIR_LEFT], rt.left, rt.top-24, g_FrameWidth, rt.bottom-24 );
}

//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
TANKCMD CAiGenerator::Generator( CMobileObject **ppmos, int num )
{
	TANKCMD		curcmd, blockcmd;
	bool		analyzecmd = false;

	// Test last command's effect
	if ( m_LastCmd.cmd == CMD_NONE ) {
		blockcmd.cmd = CMD_NONE;
		analyzecmd = true;
	} 
	else {
		// straight forward
		if ( m_LastPos.left != m_pHost->GetRect().left || 
			m_LastPos.top != m_pHost->GetRect().top ) {			
			curcmd.cmd = m_LastCmd.cmd;
			if ( rand() % m_nFireMaxProb < m_nFireProb )	// 1/16
				curcmd.fire = true;
			else
				curcmd.fire = false;
			m_bLastBlock = false;
		} 
		// block just now
		else if ( !m_bLastBlock ) {					
			m_bLastBlock = true;
			curcmd.cmd = m_LastCmd.cmd;
			curcmd.fire = true;
		}
		// block already
		else {										
			m_bLastBlock = false;
			blockcmd.cmd = m_LastCmd.cmd;
			analyzecmd = true;
		}
	}

	// Analyze a new commmand according to the aims
	if ( analyzecmd ) {
		POINT	step = m_pHost->GetDirectionUnit();
		int		diff;
		bool	randcmd;

		if ( blockcmd.cmd != CMD_NONE ) {
			m_nCurrentProb = rand() % m_nMaxProb;
			if ( m_pAim && m_nCurrentProb < m_nTrackProb) {		// track aim
				if ( step.x != 0 )					// turn up/down
				{					
					diff = m_pAim->GetRect().top - m_pHost->GetRect().top;
					if ( diff > 0 )
						curcmd.cmd = CMD_DOWN;
					else if ( diff < 0 )
						curcmd.cmd = CMD_UP;
					else
						curcmd.cmd = 5 - blockcmd.cmd;	// turn back
				} 
				else if ( step.y != 0 ) 			// turn left/right	
				{
					diff = m_pAim->GetRect().left - m_pHost->GetRect().left;
					if ( diff > 0 )
						curcmd.cmd = CMD_RIGHT;
					else if ( diff < 0 )
						curcmd.cmd = CMD_LEFT;
					else
						curcmd.cmd = 5 - blockcmd.cmd;	// turn back
				}
				randcmd = false;
			} 
			else {			// no aim, but block
				m_nCurrentProb = rand() % m_nMaxProb;
				for ( int i=1; i<5; i++ ) {
					if ( i != (int)blockcmd.cmd ) {
						m_nCurrentProb -= m_nMaxProb/3;
						if ( m_nCurrentProb <= 0 ) {
							curcmd.cmd = i;
							break;
						}
					}
				}
			}
		} else {			// no blockcmd, maybe aim
			m_nCurrentProb = rand() % m_nMaxProb;
			if ( m_pAim && m_nCurrentProb < m_nTrackProb) {			// track aim
				diff = m_pAim->GetRect().top - m_pHost->GetRect().top;
				if ( diff > 0 )
					curcmd.cmd = CMD_DOWN;
				else if ( diff < 0 )
					curcmd.cmd = CMD_UP;
				else {
					diff = m_pAim->GetRect().left - m_pHost->GetRect().left;
					if ( diff > 0 )
						curcmd.cmd = CMD_RIGHT;
					else if ( diff < 0 )
						curcmd.cmd = CMD_LEFT;
					else {
						m_nCurrentProb = rand() % m_nMaxProb;
						for ( int i=1; i<5; i++ ) {
							m_nCurrentProb -= m_nMaxProb/4;
							if ( m_nCurrentProb <= 0 ) {
								curcmd.cmd = i;
								break;
							}
						}
					}
				}
			} else {		// no blockcmd, no aim
				m_nCurrentProb = rand() % m_nMaxProb;
				for ( int i=1; i<5; i++ ) {
					m_nCurrentProb -= m_nMaxProb/4;
					if ( m_nCurrentProb <= 0 ) {
						curcmd.cmd = i;
						break;
					}
				}
			}
		}

		if ( rand() % m_nFireMaxProb < m_nFireProb )	// 1/16
			curcmd.fire = true;
		else
			curcmd.fire = false;
	}

	// avoid beat base
	if ( PtInRect( &m_rtAvoid[m_LastCmd.cmd], *(POINT *)&m_LastPos ) )
		curcmd.fire = false;

	// Attack nearby

	// Store last values
	m_LastPos = m_pHost->GetRect();
	m_LastCmd = curcmd;
	return m_LastCmd;
}

//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -