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)调试:

❤菜鸟程序 如有错误,请帮忙指出❤

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wyn_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值