📄 dlgaishow.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 + -