Задача Майхилла для Microsoft Visual C++
Страница 6. Листинги


 

Листинг 1

Программная модель стрелка

extern LArc RiflemanTBL[];
class CRifleman : public LFsaAppl
{
public:
int GetNumber();
void SetNumber(int n);
void SetLink(CRifleman *pFsaLeft,
CRifleman
*pFsaRigtht);
CRifleman *pFsaRightMan;
CRifleman *pFsaLeftMan;
CRifleman();
CRifleman(int n, CWnd* pW, LArc
*pTBL=RiflemanTBL);
virtual ~CRifleman();
bool operator==(const CRifleman
&var) const;
bool operator<(const CRifleman
&var) const;
bool operator!=(const CRifleman
&var) const;
bool operator>(const CRifleman
&var) const;
protected:
CWnd* pParentWnd;
CFireApp *pApp; // указатель на объект
// основного класса программы
int x1(); // Is fire?
int x2(); // Is ready?
int x3(); // Number is equal to zero? Shot!
int x4(); //
void y1(); // To place number.
void y2(); // To reduce number by unit.
void y3(); // Gunshot
void y4(); //
void y5(); //
int nNumber;
int nSaveNumber;
int nLengthQueue; // Length of queue.
int nCurrentQueue; //
};
typedef vector<CRifleman*>
TIArrayRifleman;
typedef vector<CRifleman*>:
:iterator TIIteratorRifleman;
extern LArc RiflemanTBL[];
CRifleman::CRifleman():LFsaAppl() { }
CRifleman::CRifleman(int n, CWnd* pW,
LArc* pTBL):
LFsaAppl(pTBL)
{
pParentWnd = pW;
pFsaRightMan = NULL;
pFsaLeftMan = NULL;
nNumber = n;
nLengthQueue = 5;
nCurrentQueue = nLengthQueue;
if (pParentWnd)
{
pApp = (CFireApp*)AfxGetApp();
FLoad(pApp->pNetFsa,1);
}
}
bool CRifleman::operator==(const CRifleman
&var) const
{
if (nNumber==var.nNumber) return true;
else return false;
}
void CRifleman::SetLink(CRifleman
* pFsaLeft, CRifleman *
pFsaRigtht)
{
pFsaRightMan = pFsaRigtht;
pFsaLeftMan = pFsaLeft;
}
LArc RiflemanTBL[] = {
LArc("Сон", "Огонь", "x1", "y1"),
LArc("Огонь", "Готов", "x2", "y2"),
LArc("Готов", "Готов", "x3", "y2"),
LArc("Готов", "Выстрел", "^x3", "y3y4"),
LArc("Выстрел", "Выстрел", "x4", "y3y5"),
LArc("Выстрел", "Сон", "^x4", "-"),
LArc()
};
int CRifleman::x1()
{
if (!pFsaLeftMan) return false;
return string((pFsaLeftMan)-
>FGetState()) == "Огонь";
}
int CRifleman::x2()
{
if (!pFsaRightMan) return true;
else return string((pFsaRightMan)-
>FGetState()) ==
"Готов";
}
int CRifleman::x3() { return nNumber; }
int CRifleman::x4() { return nCurrentQueue; }
void CRifleman::y1()
{
int n = pFsaLeftMan->GetNumber();
SetNumber(n+1);
}
void CRifleman::y2() { nNumber-; }
void CRifleman::y3() { }
void CRifleman::y4()
{
nCurrentQueue = nLengthQueue;
}
// формирование задержки между выстрелами
void CRifleman::y5()
{
CFDelay *pCFDelay;
pCFDelay = new CFDelay(200);
pCFDelay->FCall(this);
nCurrentQueue-;
}

Листинг 2

Модель командира

class COfficer : public CRifleman
{
public:
COfficer();
virtual ~COfficer();
void SetCommand();
protected:
CFireApp *pApp; //
int x1(); // Is fire?
void y1();
bool bCommandFire;
};
extern LArc OfficerTBL[];
COfficer::COfficer():CRifleman
(0,NULL,OfficerTBL)
{
bCommandFire = false;
pApp = (CFireApp*)AfxGetApp(); //
FLoad(pApp->pNetFsa,1); // подключить
объект
к КА-сети
}
COfficer::~COfficer() { }
LArc OfficerTBL[] = {
LArc("Сон", "Огонь", "x1", "y1"),
LArc("Огонь", "Сон", "-", "-"),
LArc()
};
int COfficer::x1() { return bCommandFire; }
void COfficer::y1() { bCommandFire = false; }
void COfficer::SetCommand() { bCommandFire =
true; }

Листинг 3

Модель пули

extern LArc BulletTBL[];
class CBullet : public TBounce
{
public:
void SetAddrMan (LFsaAppl
*pFsaAppl);
CBullet();
CBullet(CWnd* pW, int nNum,
CSize sz=CSize(10,10),
LArc *pTBL=BulletTBL);
virtual ~CBullet();
void SetCenter(int x, int y);
void SetMove(int cx, int cy);
protected:
int x1();
int x2();
int x3();
void y4();
protected:
LFsaAppl *pFsaShot;
};
typedef vector<CBullet*>
TIArrayBullet;
typedef vector<CBullet*>:
:iterator
TIIteratorBullet;
CBullet::CBullet(CWnd* pW, int nNum,
CSize sz, LArc *pTBL)
:TBounce(pW, nNum, sz, pTBL)
{
pFsaShot = NULL;
}
CBullet::CBullet():TBounce()
{ pFsaShot = NULL; }
CBullet::~CBullet() { }
void CBullet::SetAddrMan(LFsaAppl
* pFsaAppl) { pFsaShot =
pFsaAppl; }
//
LArc BulletTBL[] = {
LArc("st","b1", "x1", "y4"),
LArc("b1","b1", "^x2", "y1"),
LArc("b1","st", "x2", "y4"),
LArc()
};
int CBullet::x1()
{
if (!pFsaShot) return false;
return string((pFsaShot)-
>FGetState()) == "выстрел";
}
int CBullet::x2()
{
return m_ptCenter.y + m_sizeRadius.cy >=
rcClient.bottom;
}
int CBullet::x3()
{
return nNumBounce;
}
void CBullet::y4() { SetCenter(0,10); }
void CBullet::SetCenter(int x, int y)
{
if (y) m_ptCenter.y = y;
if (x) m_ptCenter.x = x;
}
void CBullet::SetMove(int cx, int cy)
{
m_sizeMove.cx = cx;
m_sizeMove.cy = cy;
}

Листинг 4

Модель цепи стрелков

class CChainShot
{
public:
CChainShot(CWnd *pW);
virtual ~CChainShot();
void SetLink();
void SetCommand();
void OnSize(int cx, int cy);
CRifleman* GetAddrRifleman(int n);
CBullet* GetAddrBullet(int n);
protected:
CWnd *pWnd;
COfficer *pCOfficer;
TIArrayRifleman IArrayRifleman;
TIArrayBullet IArrayBullet;
};
CChainShot::CChainShot(CWnd *pW)
{
pWnd = pW;
pCOfficer = new COfficer();
for (int i=1; i<=4; i++) {
IArrayRifleman.push_back(new CRifleman(i,pWnd));
IArrayBullet.push_back(new CBullet(pWnd,i));
}
SetLink();
}
CChainShot::~CChainShot()
{
if (pCOfficer) delete pCOfficer;
TIIteratorRifleman iterRifleman =
IArrayRifleman.begin();
while (iterRifleman != IArrayRifleman.end())
delete *iterRifleman++;
IArrayRifleman.erase(IArrayRifleman.begin(),
IArrayRifleman.end());
TIIteratorBullet iterBullet = IArrayBullet
.begin();
while (iterBullet!=IArrayBullet.end()) delete
*iterBullet++;
IArrayBullet.erase(IArrayBullet.begin()
,IArrayBullet.end());
}
void CChainShot::SetCommand()
{
if (pCOfficer) pCOfficer->SetCommand();
}
CRifleman* CChainShot::GetAddrRifleman(int n)
{
CRifleman* currentRifleman=NULL;
CRifleman vs(n, NULL);
TIIteratorRifleman iterRifleman
= IArrayRifleman.begin();
while (iterRifleman != IArrayRifleman.end()) {
currentRifleman= *iterRifleman++;
if (*currentRifleman==vs) break;
}
return currentRifleman;
}
CBullet* CChainShot::GetAddrBullet(int n)
{
CBullet* currentBullet=NULL;
CBullet vs(NULL, n);
if (!IArrayBullet.empty()) {
TIIteratorBullet iterBullet = IArrayBullet
.begin();
while (iterBullet != IArrayBullet.end()) {
currentBullet= *iterBullet++;
if (*currentBullet==vs) break;
}
}
return currentBullet;
}
void CChainShot::SetLink()
{
LFsaAppl *currentRifleman;
TIIteratorRifleman iterRifleman =
IArrayRifleman.begin();
int n =1;
CRifleman *pFsaLeft = NULL;
CRifleman *pFsaRight = NULL;
while (iterRifleman != IArrayRifleman.end())
{
if (n==1)
{
currentRifleman= *iterRifleman++;
((CRifleman*)currentRifleman)-
>SetNumber(n);
n++;
pFsaLeft = pCOfficer;
pFsaRight= *iterRifleman++;
((CRifleman*)pFsaRight)->SetNumber(n);
n++;
((CRifleman*)currentRifleman)->
SetLink(pFsaLeft, pFsaRight);
}
else
{
pFsaLeft = currentRifleman;
if (iterRifleman != IArrayRifleman.end())
{
currentRifleman = pFsaRight;
pFsaRight= *iterRifleman++;
((CRifleman*)pFsaRight)->SetNumber(n);
n++;
((CRifleman*)currentRifleman)->
SetLink(pFsaLeft, pFsaRight);
}
}
}
pFsaLeft = currentRifleman;
currentRifleman = pFsaRight;
pFsaRight= NULL;
((CRifleman*)currentRifleman)-
>SetLink(pFsaLeft,
pFsaRight);
TIIteratorBullet iterBullet =
IArrayBullet.begin();
while (iterBullet != IArrayBullet.end()) {
CBullet* currentBullet= *iterBullet++;
CRifleman* pRf=GetAddrRifleman
(currentBullet->GetNum());
currentBullet->SetAddrMan(pRf);
}
}
void CChainShot::OnSize(int cx, int cy)
{
int n=1;
CBullet* currentBullet;
TIIteratorBullet iterBullet =
IArrayBullet.begin();
while (iterBullet != IArrayBullet.end()) {
currentBullet= *iterBullet++;
currentBullet->Size(CSize(cx/n,cy/n));
currentBullet->SetCenter(400/n-20,10);
currentBullet->SetMove(0,1);
// currentBullet->SizeBounce(CSize(20,20));
n++;
}
}

Листинг 5

Объект окна-отображения

void CFireView::OnFire()
{
pChainShot->SetCommand();
}
int CFireView::OnCreate(LPCREATESTRUCT
lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
pChainShot = new CChainShot(this);
CFireApp *pApp = (CFireApp*)AfxGetApp(); //
pApp->pNetFsa->go_task(); // запуск
КА-объекта
return 0;
}
void CFireView::OnSize(UINT nType,
int cx, int cy)
{
pChainShot->OnSize(cx, cy);
CView::OnSize(nType, cx, cy);
}
void CFireView::OnFast()
{
CFireApp *pApp = (CFireApp*)AfxGetApp();
pApp->lCountTime=0;
}
void CFireView::OnSlow()
{
CFireApp *pApp = (CFireApp*)AfxGetApp();
pApp->lCountTime=1000;
}

Листинг 6

Действие y3 модели стрелка

void CRifleman::y3()
{
CRect r;
pParentWnd->GetClientRect(r);
CSize cz = r.Size();
int x1, y1;
x1=cz.cx/nSaveNumber;
y1= cz.cy/nSaveNumber;
CBullet *currentBullet =
new CBullet(pParentWnd, 0);
// задание начального положения
пули и ее размеров
currentBullet->SetCenter(x1-50,10);
currentBullet->SetMove(0,3);//
интервал между пулями
// currentBullet->SetMove(nCurrentQueue,3);
// стрельба
// веером
currentBullet->SizeBounce(CSize(2,5));
// передача адреса стрелка новой пуле
currentBullet->SetAddrMan(this);
// currentBullet->FCall(this);
}

Листинг 7

Таблица переходов "автоматной" пули

LArc BulletTBL[] = {
LArc("st","b1", "x1x3", "y4"),
LArc("st","b1", "^x3", "y4"),
LArc("b1","b1", "^x2", "y1"),
LArc("b1","st", "x2x3", "y4"),
LArc("b1","00", "x2^x3","-"),
LArc()
};
 
Следующая статья »