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

📄 dlgaishow.cpp

📁 很经典的用C++编的空当接龙的程序
💻 CPP
字号:
// DlgAIShow.cpp : implementation file
//

#include "stdafx.h"
#include "JL.h"
#include "JLDoc.h"
#include "JLView.h"
#include "DlgAIShow.h"
#include "datatype.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDlgAIShow dialog

#define ID_TIMER 200
extern CJLDoc * AfxGetDocument();
extern CJLView * AfxGetView();

CDlgAIShow::CDlgAIShow(CWnd* pParent /*=NULL*/)
	: CDialog(CDlgAIShow::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDlgAIShow)
	m_pCurPos = 0;
	m_nElapse = 240;
	m_bPlaying = 0;
	//}}AFX_DATA_INIT
}

BEGIN_MESSAGE_MAP(CDlgAIShow, CDialog)
	//{{AFX_MSG_MAP(CDlgAIShow)
	ON_BN_CLICKED(IDB_NEXT, OnNext)
	ON_BN_CLICKED(IDB_PREV, OnPrev)
	ON_BN_CLICKED(IDB_FIRST, OnFirst)
	ON_BN_CLICKED(IDB_LAST, OnLast)
	ON_BN_CLICKED(IDB_AUTO_PLAY, OnAutoPlay)
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlgAIShow message handlers
void CDlgAIShow::OnNext() 
{
	// TODO: Add your control notification handler code here
	CancelCurMv();

	CJLDoc *pDoc = AfxGetDocument();
	if(pDoc->m_pOps->IsEmpty())
		return;

	COperations *pOpsCur = NULL;
	int cnt = pDoc->m_pOps->GetCount();
	if(m_pCurPos < cnt) {
		//取出当前的操作记录
		//指向下一个操作记录
		POSITION posCur = pDoc->m_pOps->FindIndex(m_pCurPos);
		pOpsCur = (COperations*)pDoc->m_pOps->GetAt(posCur);
		++m_pCurPos;
	}

	CObList *pOps= pOpsCur->pOps;
	POSITION pos = pOps->GetTailPosition();
	while(pos) {
		COperation *pOp = (COperation*)pOps->GetPrev(pos);
		pDoc->MoveCards(pOp->des,pOp->src,pOp->cnt);
	}

	//现在允许执行上一步
	((CButton *)GetDlgItem(IDB_PREV))->EnableWindow(TRUE);
	((CButton *)GetDlgItem(IDB_FIRST))->EnableWindow(TRUE);
	if(m_pCurPos == cnt) {
		((CButton *)GetDlgItem(IDB_NEXT))->EnableWindow(FALSE);
		((CButton *)GetDlgItem(IDB_LAST))->EnableWindow(FALSE);
		((CButton *)GetDlgItem(IDB_PREV))->SetFocus();
	}

	ShowStepInfo();
}

void CDlgAIShow::OnPrev() 
{
	// TODO: Add your control notification handler code here
	CancelCurMv();

	CJLDoc *pDoc = AfxGetDocument();
	if(pDoc->m_pOps->IsEmpty())
		return;

	COperations *pOpsCur = NULL;
	if(m_pCurPos > 0) {
		//指向上一个操作记录
		//取出上一个操作记录
		--m_pCurPos;
		POSITION posCur = pDoc->m_pOps->FindIndex(m_pCurPos);
		pOpsCur = (COperations*)pDoc->m_pOps->GetAt(posCur);
	}

	CObList *pOps= pOpsCur->pOps;
	POSITION pos = pOps->GetHeadPosition();
	while(pos) {
		COperation *pOp = (COperation*)pOps->GetNext(pos);
		pDoc->MoveCards(pOp->src,pOp->des,pOp->cnt);
	}

	//现在允许执行下一步
	((CButton *)GetDlgItem(IDB_NEXT))->EnableWindow(TRUE);
	((CButton *)GetDlgItem(IDB_LAST))->EnableWindow(TRUE);
	if(m_pCurPos == 0) {
		ShowStepInfo();

		((CButton *)GetDlgItem(IDB_PREV))->EnableWindow(FALSE);
		((CButton *)GetDlgItem(IDB_FIRST))->EnableWindow(FALSE);
		((CButton *)GetDlgItem(IDB_NEXT))->SetFocus();
	}

	ShowStepInfo();
}

BOOL CDlgAIShow::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	//把窗口移动到主窗框的顶部

	CRect r,wr;
	AfxGetApp()->GetMainWnd()->GetWindowRect(r);
	GetWindowRect(wr);
	MoveWindow(r.left, r.top-wr.Height(), wr.Width(), wr.Height());
	
	((CButton *)GetDlgItem(IDB_PREV))->EnableWindow(FALSE);
	((CButton *)GetDlgItem(IDB_FIRST))->EnableWindow(FALSE);

	SetTimer(ID_TIMER,m_nElapse,NULL);
	m_bPlaying = 0;

	ShowStepInfo();
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}
//显示进度
void CDlgAIShow::ShowStepInfo()
{
	CJLDoc* pDoc = AfxGetDocument();

	CString step_info;
	step_info.Format("进度【 %d / %d 】",
		m_pCurPos,
		pDoc->m_pOps->GetCount());
	SetWindowText(step_info);
}
 
void CDlgAIShow::OnFirst() 
{
	// TODO: Add your control notification handler code here
	while(m_pCurPos > 0) OnPrev();
}

void CDlgAIShow::OnLast() 
{
	// TODO: Add your control notification handler code here
	CJLDoc *pDoc = AfxGetDocument();
	while(m_pCurPos < pDoc->m_pOps->GetCount()) OnNext();
}

void CDlgAIShow::OnAutoPlay() 
{
	// TODO: Add your control notification handler code here
	if(m_bPlaying) { 
		//暂停时,也要把回放过程的当前步骤取消
		CancelCurMv();
	}
	m_bPlaying = !m_bPlaying ? 1 : 0;
	SetDlgItemText(IDB_AUTO_PLAY, m_bPlaying ? "暂停(&T)" : "回放(&A)");
}

void CDlgAIShow::CancelCurMv()
{
	//如果正在回放,则先把回放过程的当前步骤取消
	while(m_bPlaying) {
		if(m_bPlaying < 7) {
			OnTimer(ID_TIMER);//这里是为了恢复已反色的区域
		} else {
			// 现在m_bPlaying==5,下次调用OnTimer则m_bPlaying==1
			// 所以为了使不完成本次的移动,直接给m_bPlaying赋值1
			m_bPlaying = 1;
			break;
		}
	}
}

void CDlgAIShow::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	if(!m_bPlaying) return;//暂停演示

	CJLDoc *pDoc = AfxGetDocument();
	if(m_pCurPos == pDoc->m_pOps->GetCount()) {
		m_bPlaying = 0; //设置暂停标志
		SetDlgItemText(IDB_AUTO_PLAY,"回放(&A)");
	}
	else if(m_bPlaying == 7) { 
		OnNext();//移动
		m_bPlaying = 1;
	}
	else if(m_bPlaying < 5){
		CJLDoc *pDoc = AfxGetDocument();
		COperations *pOpsCur = NULL;
		int cnt = pDoc->m_pOps->GetCount();

		//取出当前的操作记录
		POSITION posCur = pDoc->m_pOps->FindIndex(m_pCurPos);//位置
		pOpsCur = (COperations*)pDoc->m_pOps->GetAt(posCur);//指针
		CObList *pOps= pOpsCur->pOps;//步骤链
		//此链记录了移动动作和自动扔牌动作
		//最末尾的数据记录的是移动动作
		POSITION pos = pOps->GetTailPosition();
		COperation *pOp = (COperation*)pOps->GetPrev(pos);
		//对将要移动的牌进行反色,明确提示玩家下一步的动作
		CClientDC cdc(AfxGetView());
		int nSrc = pDoc->CntCardsIn(pOp->src);
		cdc.InvertRect( pDoc->RectOf( pOp->src, nSrc - pOp->cnt + 1, pOp->cnt ) );
		int nDes = pDoc->CntCardsIn(pOp->des);
		cdc.InvertRect( pDoc->RectOf( pOp->des, max(nDes,1), 1 ) );
		//状态计数
		m_bPlaying++;
	} else {
		//状态计数
		m_bPlaying++;
	}

	CDialog::OnTimer(nIDEvent);
}

void CDlgAIShow::OnCancel() 
{
	// TODO: Add extra cleanup here
	OnLast();//结束回放时,停在游戏结束的地方
	KillTimer(ID_TIMER);
	CDialog::OnCancel();
}

⌨️ 快捷键说明

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