vc++ 24点小游戏
一、常见游戏规则:
从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。
二、游戏攻略
1)相连数的计算方法
1>两个相连数可看作1 ⑵两个相连数可以不参与计算,如:3、8、2、3和4、6、8、7。 ⑶两个相连数也可以相乘,但是数较大时不宜采用 2> 三个数相连 ⑴可以看成三个相连数中最前面一个数。如:4、5、6、6和3、4、5、8。 ⑵可以看成三个相连数中中间一个数。如:3、7、8、9和2、3、4、8。 ⑶可以看成三个相连数中最后面一个数。如:2、3、4、6和6、7、8、3。 ⑷可以看成三个相连数中最前面一个数减去1。如:4、5、6、8和5、6、7、6。 ⑸可以看成三个相连数中最后面一个数加上1。如:3、4、5、4和5、6、7、3。 ⑹可以看成三个相连数中中间一个数的2倍数。如:2、3、4、4和7、8、9、8。 ⑺可以看成三个相连数中中间一个数的3倍数。如:6、7、8、3和8、9、10、3。 ⑻三个数相连时,有时可以看作是两组两个数相连,如3、4、5可看作3与4或4与5两组两个数相连,计算时具体用哪个组合要看另一张牌的数。 3>四个数相连:四个数相连的概率极小,一共只有7个组合,每个组合都有解,不难。
2)相同数的计算方法
1、 两个数相同 ⑴两个数相同可以看作1。如5、5、2、8和7、7、3、6。 ⑵两个数相同可以看作0。如7、7、3、8和9、9、4、6。 ⑶两个数相同可以看作这个数的2倍。如5、5、2、7和4、4、2、6。 ⑷两个数相同可以看作乘积,数较大时不宜使用。如5、5、2、1和3、3、6、8。 2、 三个数相同 ⑴三个数相同时可以看作是其中的一个数,如3、3、3、8和4、4、4、6。 ⑵三个数相同时可以看作是其中的一个数加上1,如5、5、5、4和7、7、7、3 ⑶三个数相同时可以看作是其中的一个数减去1,如5、5、5、6和9、9、9、3。 3、 四个数相同:四个数相同出现的概率较少,一共有10个。这些组合中,只有四 个3、4、5、6能够解答,其余的都没有解。
3)单数的计算方法
1、 一个单数当出现一张单数时,应根据这张单数的数目和另外三张双数之间的关系来做灵活调整。因为有3×8=24的基本算法,所以如单数是3,一般可以考虑把三个双数处理成8。如3、10、2、4有3×(10+2-4)=24或3、2、2、4有3×(2+2+4)=24。如单数不是3,双数中有8时,可以将单数和其他两个双数处理成3。例如9、4、2、8有8×(9-2-4)=24或者9、10、2、8有8×(10-9+2)=24。单数既不是3,双数不是8呢,有时可以将通过一个单数与2个双数和一个双数进行匀算后出现3和8,如9、6、4、4有(9-6)×(4+4)=24或9、6、2、4有(9-6)×2×4=24。用以上方法不能求解时,就要考虑其他方法了。可将单数乘上双数变成一个双数后再和另外两个双数一起运算。在单数较大时可先减掉一个双数再乘上一个双数变成双数,再和另外一个双数运算。通常就是乘减或乘加运算。如3、4、6、6有3×4+6+6=24。3、4、2、6有3×4+2×6=24,9、6、4、2有(9-6)×2×4=24。 2、 二个单数:可以通过二个单数之间相加或相减变成双数。如3、3、2、2有(3+3)×(2+2)=24,9、3、8、2有(9-3)×8+2=24。一般两个单数之间不宜相乘,因为相乘后又是单数。且数目较大,但是有例外。如7、7、1、2有(7×7-1)÷2=24。但是两个单数可以相除的话,不妨一试。如9、3、2、6有9÷3×(2+6)=24或9、3、4、4有9÷3×(4+4)=24。
三、要求:
基本要求: 随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式,用擅长的语言(C/C++/Java或其他均可)实现程序解决问题。
1.程序风格良好(使用自定义注释模板)
2.列出表达式无重复。
提高要求:用户初始生命值为一给定值(比如3),初始分数为0。随机生成4个代表扑克牌牌面的数字或字母,由用户输入包含这4个数字或字母的运算表达式(可包含括号),如果表达式计算结果为24则代表用户赢了此局。
1. 程序风格良好(使用自定义注释模板)
2.使用计时器要求用户在规定时间内输入表达式,如果规定时间内运算正确则加分,超时或运算错误则进入下一题并减少生命值(不扣分)。
3.所有成绩均可记录在TopList.txt文件中。
四、设计思路:
24点游戏的算法,其中最主要的思想就是穷举法。所谓穷举法就是列出4个数字加减乘除的各种可能性。我们可以将表达式分成以下几种:首先我们将4个数设为a,b,c,d,,将其排序列出四个数的所有排序序列组合(共有A44=24种组合)。再进行符号的排列表达式,其中算术符号有+,—,*,/,(,)。其中有效的表达式有a*(b-c/b),a*b-c*d,等等。列出所有有效的表达式。其中我们用枚举类型将符号定义成数字常量。下面介绍下穷举法的主要实现,要实现24点的算法,就是通过4个数字,4个运算符号和2对括号(最多为2对),通过各种组合判断其结果是否为24。我们用a,b,c,d代替4个数字。考虑每种可能,总的算法就有7种可能。分别为:
1没括号的(形如a*b*c*d);
2有括号的(形如(a * b) * c * d);
3有括号的(形如(a * b * c) * d);
4有括号的(形如a * (b * c) * d);
5有括号的(形如(a * b) * (c * d));
6有括号的(形如((a * b) * c) * d);
7有括号的(形如(a * (b * c)) * d)。
接下来就是对每一种进行分析判断。
以上就是穷举法的基本实现算法
首先穷举的可行性问题。我把表达式如下分成三类:
1、 列出四个数的所有排序序列组合(共有A44=24种组合)。
2、 构筑一个函数,列出所有运算表达式。
3、 输入数据计算。
五、页面设计:
六、类的设计
七、主要代码:
#include "stdafx.h"
#include "24DianGame.h"
#include "24DianGameDlg.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "time.h"
#include "tip.h"
#include "MMSYSTEM.H"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMy24DianGameDlg dialog
CMy24DianGameDlg::CMy24DianGameDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMy24DianGameDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CMy24DianGameDlg)
m_round = _T("0");
m_score = _T("0");
m_TotalRound = _T("0");
m_input = _T("");
m_cTime = _T("");
m_cWarm = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDI_MAINFRAME);
}
void CMy24DianGameDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMy24DianGameDlg)
DDX_Control(pDX, IDC_PROGRESS, m_progress);
DDX_Text(pDX, IDC_ROUND, m_round);
DDX_Text(pDX, IDC_SCORE, m_score);
DDX_Text(pDX, IDC_TOTAL_ROUND, m_TotalRound);
DDX_Text(pDX, IDC_INPUT, m_input);
DDX_Text(pDX, IDC_STATIC_TIME, m_cTime);
DDX_Text(pDX, IDC_STATIC_WARM, m_cWarm);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMy24DianGameDlg, CDialog)
//{{AFX_MSG_MAP(CMy24DianGameDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_COMMAND(IDM_ABOUT, OnAbout)
ON_BN_CLICKED(IDC_CALC, OnCalc)
ON_EN_CHANGE(IDC_INPUT, OnChange)
ON_BN_CLICKED(IDC_TIP, OnTip)
ON_BN_CLICKED(IDC_DEAL, OnDeal)
ON_WM_TIMER()
ON_CBN_SELCHANGE(IDC_COMBO1, OnSelchangeCombo1)
ON_COMMAND(ID_EASY, OnEasy)
ON_COMMAND(ID_HARD, OnHard)
ON_COMMAND(ID_NORMAL, OnNormal)
ON_BN_CLICKED(IDC_HELP, OnHelp)
ON_BN_CLICKED(ID_NULL, OnNull)
ON_BN_CLICKED(IDC_GIVEUP, OnGiveup)
ON_BN_CLICKED(IDC_CHECK, OnCheck)
ON_COMMAND(IDM_DEAL, OnMenuDeal)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMy24DianGameDlg message handlers
BOOL CMy24DianGameDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
i_Round=0;
i_TotalRound=0;
i_Score=0;
bIsDeal=false;
bIsSelect=false;
bIsNull=false;
// ((CButton*)GetDlgItem(IDC_CHECK))->SetCheck(1);
GetDlgItem(IDC_CALC)->EnableWindow(FALSE);
GetDlgItem(IDC_TIP)->EnableWindow(FALSE);
GetDlgItem(ID_NULL)->EnableWindow(FALSE);
GetDlgItem(IDC_GIVEUP)->EnableWindow(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
}
void CMy24DianGameDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CMy24DianGameDlg::OnPaint() //将扑克牌显示在界面上
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CMy24DianGameDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CMy24DianGameDlg::OnAbout()
{
CAboutDlg Dlg;
Dlg.DoModal();
}
void CMy24DianGameDlg::OnChange()
{
UpdateData(TRUE);
}
void CMy24DianGameDlg::OnHelp()
{
CAboutDlg dlg;
dlg.DoModal();
}
void CMy24DianGameDlg::OnOK()
{
if( ((CButton*)GetDlgItem(IDC_CALC))->IsWindowEnabled() )
OnCalc();
}
void CMy24DianGameDlg::Calculate1() //计算的实现
{
float x1,x2,x; //定义三个变量
char p; //定义一个指针
p=CStack[--cStackPos]; //指针指向栈
x2=IStack[--iStackPos];
x1=IStack[--iStackPos];
switch(p) //选择四种加减乘除运算
{
case '+': x=x1+x2; break;
case '-': x=x1-x2; break;
case '*': x=x1*x2; break;
case '/':
if(!x2) //如果x被作为除数,则显示错误
AfxMessageBox("0不能作被除数!");
x=x1/x2; break;
}
IStack[iStackPos++]=x;
}
void CMy24DianGameDlg::Calculate2(char *f)
{
float Number;
iStackPos=cStackPos=0;
char *p=f;
while(*p!='\0')
{
switch(*p)
{
case '(':
CStack[cStackPos++]='(';
p++;
break;
case ')':
while(CStack[cStackPos-1]!='(')
Calculate1();
cStackPos--;
p++;
break;
case '+':
case '-':
case '*':
case '/':
if(CStack[cStackPos-1]=='+'||CStack[cStackPos-1]=='-')
{
if(*p=='+'||*p=='-')
Calculate1();
CStack[cStackPos++]=*p;
}
else
{
if(iStackPos<1)
{
AfxMessageBox("运算符输入错误!");
// exit(0);
}
else if(iStackPos==1)
CStack[cStackPos++]=*p;
else if(iStackPos>1)
{
if(CStack[cStackPos-1]!='(')
do
{
Calculate1();
}while(CStack[cStackPos-1]!='(');
CStack[cStackPos++]=*p;
}
}
p++;
break;
default:
Number=0;
do
{
Number=10*Number+*p-'0';
p++;
}while(*p>='0'&&*p<='9');
IStack[iStackPos++]=Number;
}
}
CString str1,str2;
str1.Format("%.f",IStack[0]);
if(IStack[0]==24)
{
KillTimer(0);//回答正确,停止计时
i_Round++;//统计正确局数
i_TotalRound++;//统计总局数
m_round.Format("%d",i_Round);
m_TotalRound.Format("%d",i_TotalRound);
switch(((CComboBox*)GetDlgItem(IDC_COMBO1))->GetCurSel())//本局得分
{
case 2: i_Score+=20; break;
case 1: i_Score+=10; break;
case 0: i_Score+=5; break;
}
m_score.Format("%d",i_Score);
str2="您的表达式"+m_input+"结果为:"+str1+",恭喜您回答正确,点击发牌进入下一局!";
AfxMessageBox(str2);
m_cWarm="";//取消“没时间了”提示
OnCheck();
GetDlgItem(IDC_DEAL)->EnableWindow(TRUE);
GetDlgItem(IDC_COMBO1)->EnableWindow(TRUE);
GetDlgItem(IDC_CALC)->EnableWindow(FALSE);
GetDlgItem(ID_NULL)->EnableWindow(FALSE);
GetDlgItem(IDC_GIVEUP)->EnableWindow(FALSE);
}
else
{
str2="您的表达式"+m_input+"结果为:"+str1+",很抱歉,您回答错误,请您再想一下!";
AfxMessageBox(str2);
}
UpdateData(FALSE);
}
bool CMy24DianGameDlg::bIslegal(CString M_INPUT)
{
bool bIsOverFlow=false;
if(!bIsDeal)
{ AfxMessageBox("请先发牌!"); return false; }
else
{
if(M_INPUT=="")
{ AfxMessageBox("请输入算式!"); return false; }
else
{
LPCSTR m_cSwithed=(LPCSTR)(LPCTSTR)M_INPUT; //CString to char*
/////////////////////判断括号是否匹配,操作数是否>4个,并且是否为牌面值
int Number=0;
int bTemp[MAX_SIZE];//表达式中的操作数
char *temp=new char(MAX_SIZE);
strcpy(temp,m_cSwithed);
iStackPos=cStackPos=0;
// AfxMessageBox(temp);
while(*temp!='\0')
{
if(*temp>='0'&&*temp<='9')
{
Number=0;
do{
Number=10*Number + *temp - '0';
temp++;
}while(*temp>='0' && *temp<='9');
bTemp[iStackPos++]=Number;
if(*temp==')')
goto la;
}
else if(*temp=='(')
{
CStack[cStackPos++]='(';
char t=CStack[cStackPos-1];
}
else if(*temp==')')
{
la: if(cStackPos && CStack[cStackPos-1]=='(')
cStackPos--;
else
{
AfxMessageBox(_T("您输入的表达式括号不匹配,请重新输入!"));
return false;
}
}
else if(*temp>=65)//ASCII值大于65即含英文字符,非法
bIsOverFlow=true;
temp++;
}//end of while
if(cStackPos!=0)//如果符号栈不为空,表达式错误
{
AfxMessageBox(_T("您输入的表达式括号不匹配,请重新输入!"));
return false;
}
if(iStackPos==4)
{
if( ((CardPos[1]-10000)%13!=bTemp[0]%13 && (CardPos[1]-10000)%13!=bTemp[1]%13 && (CardPos[1]-10000)%13!=bTemp[2]%13 && (CardPos[1]-10000)%13!=bTemp[3]%13 )||
((CardPos[2]-10000)%13!=bTemp[0]%13 && (CardPos[2]-10000)%13!=bTemp[1]%13 && (CardPos[2]-10000)%13!=bTemp[2]%13 && (CardPos[2]-10000)%13!=bTemp[3]%13 )||
((CardPos[3]-10000)%13!=bTemp[0]%13 && (CardPos[3]-10000)%13!=bTemp[1]%13 && (CardPos[3]-10000)%13!=bTemp[2]%13 && (CardPos[3]-10000)%13!=bTemp[3]%13 )||
((CardPos[4]-10000)%13!=bTemp[0]%13 && (CardPos[4]-10000)%13!=bTemp[1]%13 && (CardPos[4]-10000)%13!=bTemp[2]%13 && (CardPos[4]-10000)%13!=bTemp[3]%13 ))
{
AfxMessageBox("您输入的数据与牌面不符!");
return false;
}
}
else
{
if(iStackPos<4)
AfxMessageBox(_T("操作数少于4个,请重新输入!"));
else
{
if(*temp!=bTemp[3])
AfxMessageBox(_T("操作数大于4个,请重新输入!"));
}
return false;
}
if(bIsOverFlow)
{ AfxMessageBox(_T("表达式含非法字符,请重新输入!")); return false; }
}
}
return true;
}
///////////////////////////////////////////////////////////////////////////////////////
void CMy24DianGameDlg::OnDeal() //发牌功能的实现
{
if(!bIsSelect)
AfxMessageBox(_T("请选择难度等级!"));
else
{
srand((unsigned)time(NULL));
for(int k=0;k<5;k++)
CardPos[k]=10001+(int)(51*rand()/(RAND_MAX+1));//10001~10052的随机数
HBITMAP hbitmap[4];
for(int i=0;i<4;i++)
hbitmap[i]=::LoadBitmap(::AfxGetInstanceHandle(),MAKEINTRESOURCE(CardPos[i+1]));
((CStatic *)GetDlgItem(IDC_CARD1))->SetBitmap(hbitmap[0]);//一定要加(CStatic*)强制转化
((CStatic *)GetDlgItem(IDC_CARD2))->SetBitmap(hbitmap[1]);
((CStatic *)GetDlgItem(IDC_CARD3))->SetBitmap(hbitmap[2]);
((CStatic *)GetDlgItem(IDC_CARD4))->SetBitmap(hbitmap[3]);
CComboBox* combo=(CComboBox*)GetDlgItem(IDC_COMBO1);
int index=combo->GetCurSel();
switch(index)
{
case 0:
iTime=120; break;
case 1:
iTime=60; break;
case 2:
iTime=30; break;
}
m_cTime.Format("%d s",iTime);
SetTimer(0,1000,NULL);
bIsDeal=true;
bIsNull=false;
if(! ( (CButton*)GetDlgItem(IDC_CHECK) )->GetCheck() )
OnCheck();
GetDlgItem(IDC_DEAL)->EnableWindow(FALSE);//发牌后不能再发,直到下一题
GetDlgItem(IDC_CALC)->EnableWindow(TRUE);//发牌后计算按钮可用,时间耗尽后不可用
GetDlgItem(ID_NULL)->EnableWindow(TRUE);//发牌后无解按钮可用,之前不可用
GetDlgItem(IDC_TIP)->EnableWindow(FALSE);//刚刚发牌,提示不可用,最后15S可用
GetDlgItem(IDC_COMBO1)->EnableWindow(FALSE);//发牌后难度不可用,直到下一题
GetDlgItem(IDC_GIVEUP)->EnableWindow(TRUE);
}
UpdateData(FALSE);
}
void CMy24DianGameDlg::OnCalc() //计算算式,判断是否等于24
{
if(bIslegal(m_input))
{
char *m_cOperate=new char(MAX_SIZE);
strcpy(m_cOperate,"(");
strcat(m_cOperate,m_input);
strcat(m_cOperate,")");
Calculate2(m_cOperate);
}
m_input="";
UpdateData(FALSE);
}
void CMy24DianGameDlg::OnGiveup()
{
if(bIsDeal)
{
if(MessageBox("您真的要放弃本局,进入下局吗?","提示",1)==IDOK)
{
i_TotalRound++;//统计总局数
m_TotalRound.Format("%d",i_TotalRound);
if(( (CButton*)GetDlgItem(IDC_CHECK) )->GetCheck() )
OnCheck();
OnDeal();
}
}
else
AfxMessageBox(_T("请先发牌!"));
UpdateData(FALSE);
}
void CMy24DianGameDlg::OnTip() //提示,给出所有结果
{
if(!bIsDeal)
AfxMessageBox(_T("请先发牌!"));
else
{
CTip dlg;
for(int i=0;i<4;i++)
{
if((CardPos[i+1]-10000)%13==0)
dlg.a[i]=13;
else
dlg.a[i]=(CardPos[i+1]-10000)%13;
}
dlg.DoModal();
if(dlg.bIsNull)
bIsNull=true;
}
}
void CMy24DianGameDlg::OnNull()
{
if(bIsNull)
{
i_Round++;
i_TotalRound++;
m_round.Format("%d",i_Round);
m_TotalRound.Format("%d",i_TotalRound);
switch(((CComboBox*)GetDlgItem(IDC_COMBO1))->GetCurSel())
{
case 0: i_Score+=5; break;
case 1: i_Score+=10; break;
case 2: i_Score+=20; break;
}
m_score.Format("%d",i_Score);
KillTimer(0);
AfxMessageBox(_T("恭喜您回答正确!"));
m_cWarm="";
OnCheck();
GetDlgItem(IDC_DEAL)->EnableWindow(TRUE);
GetDlgItem(IDC_CALC)->EnableWindow(FALSE);
GetDlgItem(ID_NULL)->EnableWindow(FALSE);
GetDlgItem(IDC_COMBO1)->EnableWindow(TRUE);
GetDlgItem(IDC_GIVEUP)->EnableWindow(FALSE);
}
else
AfxMessageBox("请再想想哦!");
UpdateData(FALSE);
}
void CMy24DianGameDlg::OnTimer(UINT nIDEvent)
{
if(bIsDeal)
{
if(nIDEvent==0)
{
iTime--;
m_cTime.Format("%d s",iTime);
switch(((CComboBox*)GetDlgItem(IDC_COMBO1))->GetCurSel())//得到当前难度
{
case 0: m_progress.SetRange(0, 120); break;
case 1: m_progress.SetRange(0, 60); break;
case 2: m_progress.SetRange(0, 30); break;
}
m_progress.SetStep(1);
m_progress.SetPos(iTime);
}
if(iTime<=20)//最后20s时,提示功能可用
GetDlgItem(IDC_TIP)->EnableWindow(TRUE);
if(iTime<=15)
{
m_cWarm="快点哦,没时间了!";
PlaySound(MAKEINTRESOURCE(IDR_WAVE1),AfxGetResourceHandle(),
SND_ASYNC|SND_RESOURCE|SND_NODEFAULT|SND_LOOP);
}
if(iTime<=0)//时间到
{
KillTimer(0);
i_TotalRound++;//总局数加1
m_TotalRound.Format("%d",i_TotalRound);
m_cWarm="";//取消“没时间了”提示
AfxMessageBox(_T("时间到了,你输了!!!"));
OnCheck();
GetDlgItem(IDC_CALC)->EnableWindow(FALSE);//时间到,不能继续做题
GetDlgItem(IDC_DEAL)->EnableWindow(TRUE);//时间到,可以为下一句发牌
GetDlgItem(ID_NULL)->EnableWindow(FALSE);//时间到,无解按钮不可用
GetDlgItem(IDC_COMBO1)->EnableWindow(TRUE);//时间到,可以为下一句选择难度
GetDlgItem(IDC_GIVEUP)->EnableWindow(FALSE);
}
}
CDialog::OnTimer(nIDEvent);
UpdateData(FALSE);
}
void CMy24DianGameDlg::OnSelchangeCombo1()
{
switch(((CComboBox*)GetDlgItem(IDC_COMBO1))->GetCurSel())
{
case 0: iTime=120; break;
case 1: iTime=60; break;
case 2: iTime=30; break;
}
bIsSelect=true;
m_cTime.Format("%d s",iTime);
UpdateData(FALSE);
}
void CMy24DianGameDlg::OnEasy()
{
if(GetDlgItem(IDC_COMBO1)->IsWindowEnabled())
{
iTime=120;
bIsSelect=true;
m_cTime.Format("%d s",iTime);
GetDlgItem(IDC_COMBO1)->SetWindowText("简单");
UpdateData(FALSE);
}
}
void CMy24DianGameDlg::OnHard()
{
if(GetDlgItem(IDC_COMBO1)->IsWindowEnabled())
{
iTime=30;
bIsSelect=true;
m_cTime.Format("%d s",iTime);
GetDlgItem(IDC_COMBO1)->SetWindowText("困难");
UpdateData(FALSE);
}
}
void CMy24DianGameDlg::OnNormal()
{
if(GetDlgItem(IDC_COMBO1)->IsWindowEnabled())
{
iTime=60;
bIsSelect=true;
m_cTime.Format("%d s",iTime);
GetDlgItem(IDC_COMBO1)->SetWindowText("一般");
UpdateData(FALSE);
}
}
void CMy24DianGameDlg::OnCheck()
{
CButton* pBtn = (CButton*)GetDlgItem(IDC_CHECK);
int state = pBtn->GetCheck();
if(state)
PlaySound(MAKEINTRESOURCE(IDR_WAVE2),AfxGetResourceHandle(),
SND_ASYNC|SND_RESOURCE|SND_NODEFAULT|SND_LOOP);
else
PlaySound(NULL,NULL,NULL);
}
void CMy24DianGameDlg::OnMenuDeal()
{
if( GetDlgItem(IDC_DEAL)->IsWindowEnabled() )
OnDeal();
}
八、调试及测试结果
1)测试:
2)调试:
❤菜鸟程序 如有错误,请帮忙指出❤