vc++ 24点小游戏

简介: 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、 输入数据计算。



五、页面设计:


1.png1.png


六、类的设计


1.png1.png1.png1.png1.png




七、主要代码:


#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)测试:


1.png1.png1.png1.png


2)调试:


1.png1.png1.png1.png



相关文章
|
7月前
|
Java Android开发
大鱼吃小鱼【小游戏】
大鱼吃小鱼【小游戏】
142 0
|
6月前
|
开发者 Python
小游戏实战丨基于Tkinter的五子棋小游戏
小游戏实战丨基于Tkinter的五子棋小游戏
101 4
|
7月前
|
Linux C语言
|
Python
实现一个2048小游戏
要实现一个2048小游戏,你需要使用Python编程语言和图形用户界面(GUI)库。下面是一个使用Tkinter库来创建2048小游戏的基本步骤
491 3
|
7月前
贪吃蛇小游戏
贪吃蛇小游戏
312 5
点这里,玩小蚂蚁的小游戏
对于很多人来说(比如说我自己),平时没有大段的时间和精力去玩一个大游戏,这些人需要一些简单好玩的小游戏,拿起来就能玩几下,在忙碌的生活中寻求片刻的放松,随时又可以放下,继续回归到生活。如果你也是这些人的话,那么这些小游戏就是为你而做的,希望你能够喜欢。
107 0
点这里,玩小蚂蚁的小游戏
小蚂蚁的小游戏系列
对于很多人来说(比如说我自己),平时没有大段的时间和精力去玩一个大游戏,这些人需要一些简单好玩的小游戏,拿起来就能玩几下,在忙碌的生活中寻求片刻的放松,随时又可以放下,继续回归到生活。如果你也是这些人的话,那么这些小游戏就是为你而做的,希望你能够喜欢。
109 0
小蚂蚁的小游戏系列
|
移动开发
H5贪吃蛇小游戏
H5贪吃蛇小游戏
|
算法
2048小游戏(变态版哦)
2048小游戏(变态版哦)
248 0