牵着老婆满街逛

严以律己,宽以待人. 三思而后行.
GMail/GTalk: yanglinbo#google.com;
MSN/Email: tx7do#yahoo.com.cn;
QQ: 3 0 3 3 9 6 9 2 0 .

(转)连连看API版本的源代码

head.h

#define M 14
//M为连连看牌的高+2
#define N 10
//N为连连看牌的宽+2

struct point
{
 int x;
 int y;
};

/*********************************************************/

template < typename T, int m, int n > class Matrix
{
protected: 
 T matrix[M][N];
public:
 Matrix();
 Matrix( char* filename );//通过文件里的数据初始化
 void show_matrix();//输出矩阵
 void set_element( int x, int y, T num );//num为元素值
 T get_element( int x, int y );
};

/*********************************************************/

class Linker_Matrix:public Matrix < int, M, N >  //连连看的牌矩阵类
{
 /* matrix[M][N]为牌矩阵;
  从[1][1]开始,到[M-2][N-2]有效;
  外围一圈为预留的配对路径;
  值=0为无牌,即牌配对之后被消掉的的状态;
  其他值即为牌的类别,相同值的牌方可配对;  
 */
private:
 //time_t curtime;
 point p1,p2,way[ 4 ];
  //p1为起点,p2为终点,way[M+N]用于记录搜索到的路径
 int index;//路径的长度;
 int turn_count;//路径的转弯次数,>2就搜索失败;
 Matrix < int, M, N > visited;
  //是否访问过矩阵类,1:访问过 0:未访问 
public:

 Linker_Matrix();
 Linker_Matrix( int low, int high, int num );
  //随机选择元素初始化,元素值的范围在low-high,
  //每个值有num个;
 Linker_Matrix( int num );
  //随机选择元素初始化,从1开始,每个值有num个;
  
 void show_matrix();
 void count( int low, int high );//统计各个值的个数,测试用;
 bool auto_search();//自动搜索出一对配对的牌
 bool find_way( point p1, point p2 );
  //搜索路径 true-有路径 false-无;  
 void auto_play();//自动完成所有的配对;
 void init_search();//进行搜索前的初始化 
 bool man_search( point p1,  point p2);
 bool is_matched( point p1, point p2 );
  //是否配对 true-配对 false-否;
 int  get_element( int x, int y );
 void get_point(point &p1,point &p2);
  //通过p1,p2提取自动搜索出的匹配两点
 void reShuffle();//重新洗牌;
};

/*********************************************************/

head.cpp

#include "head.h"
#include<iostream.h>
#include<fstream.h>
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#include<time.h>
#include<conio.h>

template < typename T, int m, int n >
Matrix < T, m, n >::Matrix()
{
 for( int i=0; i<m; i++ )
  for( int j=0; j<n; j++ )
   matrix[i][j] = 0;
 
}

template < typename T, int m, int n >
Matrix< T, m, n >::Matrix( char* filename )
{
 ifstream infile(filename);
 
 for( int i=0; i<M; i++ )
  for( int j=0; j<N; j++ )
   infile >> matrix[i][j];
}

template < typename T, int m, int n >
void Matrix< T, m, n >::show_matrix()

 for( int i=0; i<m; i++ )
 {
  for( int j=0; j<n; j++ )
   cout<< matrix[i][j]<<'\t';
  cout<<endl;
 }
 cout<<endl;
}

template < typename T, int m, int n >
inline void Matrix< T, m, n >::set_element( int x, int y, T element )
{
 matrix[x][y] = element;
}

template < typename T, int m, int n >
T Matrix< T, m, n >::get_element( int x, int y )
{
 return matrix[x][y];
}

/*********************************************************/

Linker_Matrix::Linker_Matrix():Matrix< int, M, N >()
{
 p1.x = p1.y = 0;
 p2.x = p2.y = 0;
 index = 0;
 turn_count = 0;
 //max=0;

 for( int k=0; k<4; k++ )
  way[k].x = way[k].y = 0;
}

Linker_Matrix::Linker_Matrix( int low, int high, int num )
 :Matrix< int, M, N >()

 
 int m,n;
 time_t curtime; //记录当前时间

 p1.x = p1.y = 0;
 p2.x = p2.y = 0;
 index = 0;

 time(&curtime);//取得当前时间
 //srand(curtime);//用当前时间作种子,产生随机数

 for( int k=0; k<4; k++ )
  way[k].x = way[k].y = 0;

 for( int i=low; i<=high; i++ )
  for( int j=0; j<num; j++ )
  {
   do
   {
    m = rand()%(M-2) + 1;
    n = rand()%(N-2) + 1;
   }
   while( 0==m || 0==n || 0!=matrix[m][n] );
   matrix[m][n]=i;
  }
}

Linker_Matrix::Linker_Matrix(int num ):Matrix< int, M, N >()

 
 int m,n;
 time_t curtime; //记录当前时间

 p1.x = p1.y = 0;
 p2.x = p2.y = 0;
 index = 0;

 time(&curtime);//取得当前时间
 srand(curtime);//用当前时间作种子,产生随机数

 for( int k=0; k<4; k++ )
  way[k].x = way[k].y = 0;

 for( int i=1; i<=(M-2)*(N-2)/num; i++ )
  for( int j=0; j<num; j++ )
  {
   do
   {
    m = rand()%(M-2) + 1;
    n = rand()%(N-2) + 1;
   }
   while( 0==m || 0==n || 0!=matrix[m][n] );
   matrix[m][n]=i;
  }
}

void Linker_Matrix::show_matrix()
{
 
 for( int i=1; i<M-1; i++ )
 {
  for( int j=1; j<N-1; j++ )
   cout<<matrix[i][j]<<'\t';
  cout<<endl;
 }
 cout<<endl;
}

void Linker_Matrix::count( int low, int high )
{
 int *num,k;

 //动态分配 
 num = new int[ high-low+2 ];
 //初始化
 for( k=0; k<high-low+2; k++ )
  num[k]=0;
 
 //计数
 for( int i=1; i<M-1; i++ )
  for( int j=1; j<N-1; j++ )
   num[ matrix[i][j] ]++;
  
 //输出
 for( k=0; k<high-low+2; k++ )
  cout<<k<<":"<<num[k]<<'\t';
 cout<<endl;

 //销毁
 delete[] num;
}

inline bool Linker_Matrix::is_matched( const point p1, const point p2 )
{
 return matrix[ p1.x ][ p1.y ] == matrix[ p2.x ][ p2.y ];
}

bool Linker_Matrix::auto_search()
{
 int i,j,m,n;
 //static k = 0;
 bool all_is_zero = true;//是否所有元素都为0 true:yes false:no

 for( i=1; i<M-1; i++ )
 for( j=1; j<N-1; j++ )
 {
  if( matrix[i][j]!=0 )//元素不为0时方进行配对
  {
   all_is_zero=false;
   p1.x = i; p1.y = j;

   for( m=1; m<M-1; m++ )
   for( n=1; n<N-1; n++ )
   { 
    if( i!=m || j!=n )//元素不为本身时,方进行搜索路径
    { 
     //k++;
     p2.x=m; p2.y=n;

     init_search();
     /*if(k==29)
     {
      init_search();
      show_matrix();
     }*/
     
     if ( is_matched( p1, p2 ) && find_way( p1, p2 ) )
     /*逻辑式这样写的原因是只要is_matched(p1,p2)为false,
     逻辑式必为false,find_way(p1,p2)就不会执行;
     当两元素数值相同且有路径时,执行下面
     */
     { 
       //show_matrix();
       //cout<<turn_count<<endl;
       //matrix[ p1.x ][ p1.y ] = 0;
       //matrix[ p2.x ][ p2.y ] = 0;
       //k++;
       //cout<<p1.x<<' '<<p1.y<<' '<<p2.x<<' '<<p2.y<<':'<<k<<endl;
       //show_matrix();
       //count(1,21);
       //goto jump;
       //找到一个就退出
      
       return true;
      //}
     }
     
    }/*
    if( k>MAX)//搜索次数过大,强制跳出
        return false;*/
   }
  }
  //jump:  ;
 }

 if( true==all_is_zero )//元素全部为0,返回false
  return false;
 return false;//没有匹配时,返回false
}

bool Linker_Matrix::find_way(  point p1, point p2 )
{
 /*
 本方法是本程序的核心算法,
 作用是以p1为起点,p2为终点进行路径的搜索;*/
 /*采用水平垂直扫描法,先确定两个转折点之间是否相通,再判断
 转折点与相应端点间是否相通
 */

 int i,j;
 int px1,px2,py1,py2;
 int temp;
 bool x_across,y_across;

 //如果相邻
 if( ( p1.x+1==p2.x && p1.y==p2.y )
  || ( p1.x==p2.x && p1.y+1==p2.y )
  || ( p1.x-1==p2.x && p1.y==p2.y )
  || ( p1.x==p2.x && p1.y-1==p2.y ) )
 {
  //把路径记录下来
  //起点
  way[0].x=p1.x;
  way[0].y=p1.y;
  //直线转折点为0
  way[1].x=0;
  way[1].y=0;
  way[2].x=0;
  way[2].y=0;
  //终点
  way[3].x=p2.x;
  way[3].y=p2.y;

  return true;
 }

 //直线连通
 //如果在水平方向上
 if( p1.x==p2.x )
 {
  if(p1.y>p2.y)
  {
   temp=p1.y;
   p1.y=p2.y;
   p2.y=temp;
  }

  for(j=p1.y+1; j<p2.y; j++ )
  {
   if( matrix[p1.x][j]!=0)
   {
    break;
   }
  }

  //如果两点之间相通
  if(j==p2.y &&  matrix[p1.x][j-1]==0 )
  {
   
   //把路径记录下来
   //起点
   way[0].x=p1.x;
   way[0].y=p1.y;
   //直线转折点为0
   way[1].x=0;
   way[1].y=0;
   way[2].x=0;
   way[2].y=0;
   //终点
   way[3].x=p2.x;
   way[3].y=p2.y;

   return true;
  }
 }

 //如果在垂直方向上
 if( p1.y==p2.y )
 {
  if(p1.x>p2.x)
  {
   temp=p1.x;
   p1.x=p2.x;
   p2.x=temp;
  }

  for(i=p1.x+1; i<p2.x; i++ )
  {
   if( matrix[i][p1.y]!=0)
   {
    break;
   }
  }
  //如果两点之间相通
  if(i==p2.x &&  matrix[i-1][p1.y]==0 )
  {


   //把路径记录下来
   //起点
   way[0].x=p1.x;
   way[0].y=p1.y;
   //直线转折点为0
   way[1].x=0;
   way[1].y=0;
   way[2].x=0;
   way[2].y=0;
   //终点
   way[3].x=p2.x;
   way[3].y=p2.y;

   return true;
  }
 }


 
 //折线连通
 /*if( p1.x!=p2.x && p1.y!=p2.y)
 {*/
  if(p1.y>p2.y)
  {
   //两点交换
   temp=p1.x;
   p1.x=p2.x;
   p2.x=temp;

   temp=p1.y;
   p1.y=p2.y;
   p2.y=temp;


  }


 //横向扫描
 for(i=0;i<=M-1;i++)
 {  
  x_across=true;

  //是否水平连通
  for(j=p1.y+1; j<=p2.y-1; j++ )
  {
   if(matrix[i][j]!=0 )
   {
    x_across=false;
    break;
   }
  }

  if(matrix[i][p1.y]!=0  )
  {
   if( i!=p1.x )
    x_across=false;
  }
  if(matrix[i][p2.y]!=0  )
  {
   if( i!=p2.x )
    x_across=false;
  } 
   
  if(x_across)
  {//水平连通才执行下面
  /* for(j=1; j<N-2; j++ )
   {*/
    //检验在垂直上是否连通

   px1=px2=i;
   py1=p1.y;
   py2=p2.y;
   while( px1!=p1.x || px2!=p2.x )
   {
    //如果当前点不空且不为p1点,就跳出循环,从下一行开始检测
    if( matrix[px1][py1]!=0 && (px1!=p1.x || py1!=p1.y) )
     break;

    //如果当前点不空且不为p2点,就跳出循环,从下一行开始检测
    if( matrix[px2][py2]!=0 && (px2!=p2.x || py2!=p2.y) )
     break;

    //如果两点都为空
    //垂直向p1点靠近一格
    if(px1<p1.x)
     px1++;
    else if(px1>p1.x)
     px1--;
    //垂直向p2点靠近一格
    if(px2<p2.x)
     px2++;
    else if(px2>p2.x)
     px2--;
   }
     
   //如果能到达两个端点
   if(px1==p1.x && py1==p1.y && px2==p2.x && py2==p2.y )
   {
    //起点
    way[0].x=p1.x;
    way[0].y=p1.y;
    //两个转折点
    way[1].x=i;
    way[1].y=p1.y;
    way[2].x=i;
    way[2].y=p2.y;
    //终点
    way[3].x=p2.x;
    way[3].y=p2.y; 
    return true;
   }

  }
 }

 if(p1.x>p2.x)
  {
   //两点交换
   temp=p1.x;
   p1.x=p2.x;
   p2.x=temp;

   temp=p1.y;
   p1.y=p2.y;
   p2.y=temp;


  }
 //纵向扫描
 for(j=0;j<=N-1;j++)
 {  
  y_across=true;
  //是否垂直连通
  for(i=p1.x+1; i<=p2.x-1; i++ )
  {
   if(matrix[i][j]!=0)
   {
    y_across=false;
    break;
   }
  }

  if(matrix[p1.x][j]!=0  )
  {
   if( j!=p1.y )
    y_across=false;
  }
  if(matrix[p2.x][j]!=0  )
  {
   if( j!=p2.y )
    y_across=false;
  }
    
  if(y_across)
  {//垂直连通才执行下面
  /* for(j=1; j<N-2; j++ )
   {*/
    //检验在水平上是否连通

   py1=py2=j;
   px1=p1.x;
   px2=p2.x;
   while( py1!=p1.y || py2!=p2.y)
   {
    //如果当前点不空且不为p1点,就跳出循环,从下一行开始检测
    if( matrix[px1][py1]!=0 && (px1!=p1.x || py1!=p1.y) )
     break;

    //如果当前点不空且不为p2点,就跳出循环,从下一行开始检测
    if( matrix[px2][py2]!=0 && (px2!=p2.x || py2!=p2.y) )
     break;

    //如果两点都为空
    //水平向p1点靠近一格
    if(py1<p1.y)
     py1++;
    else if(py1>p1.y)
     py1--;
    //水平向p2点靠近一格
    if(py2<p2.y)
     py2++;
    else if(py2>p2.y)
     py2--;
   }
     
   //如果能到达两个端点
   if(px1==p1.x && py1==p1.y && px2==p2.x && py2==p2.y )
   {
    //起点
    way[0].x=p1.x;
    way[0].y=p1.y;
    //两个转折点
    way[1].x=p1.x;
    way[1].y=j;
    way[2].x=p2.x;
    way[2].y=j;
    //终点
    way[3].x=p2.x;
    way[3].y=p2.y; 
    return true;
   }

  }
 }
 //} 
 return false;

}

void Linker_Matrix::init_search()
{
 visited = Matrix< int, M, N >();
 index = 0;
 turn_count = 0;
}

void Linker_Matrix::auto_play()
{
  while( auto_search() );
}

bool Linker_Matrix::man_search(const point p1, const point p2)
{
 init_search();
 if( find_way( p1, p2 ) )
 {
  matrix[p1.x][p1.y]=0;
  matrix[p2.x][p2.y]=0;
  return true;
 }
 return false;
}

 int Linker_Matrix::get_element( int x, int y )
 {
  return matrix[x][y];
 }

void Linker_Matrix::get_point(point &p1,point &p2)
{
 //if( auto_search() )
 //{
  p1=this->p1;
  p2=this->p2;
  //return true;
 //}
 
 //return false;
}

void Linker_Matrix::reShuffle()
{
 int m,n,k;
 time_t curtime; //记录当前时间

 //p1.x = p1.y = 0;
 //p2.x = p2.y = 0;
 //index = 0;

 time(&curtime);//取得当前时间
 srand(curtime);//用当前时间作种子,产生随机数

 //for( int k=0; k<4; k++ )
 // way[k].x = way[k].y = 0;

 for( int i=1; i<=(M-2); i++ )
 for( int j=1; j<=(N-2); j++ )
 {
  if(matrix[i][j]!=0)
  {
   do
   {
    m = rand()%(M-2) + 1;
    n = rand()%(N-2) + 1;
   }
   while( 0==matrix[m][n] );

   k=matrix[i][j];
   matrix[i][j]=matrix[m][n];
   matrix[m][n]=k;
  }
 }
}

linker.cpp

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include <windows.h>

#include "head.h"
#include "resource.h"

TCHAR szAppName[] = TEXT ("Linker") ;//程序名称
const int xsize=610,ysize=520;
const int TimerID=1;


LRESULT CALLBACK WndProc ( HWND, UINT, WPARAM, LPARAM ) ;

int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow )
{
 HWND         hwnd ;
 MSG          msg ;
 WNDCLASS     wndclass ;
 HACCEL hAccel ;//快捷键表


 wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
 wndclass.lpfnWndProc   = WndProc ;
 wndclass.cbClsExtra    = 0 ;
 wndclass.cbWndExtra    = 0 ;
 wndclass.hInstance     = hInstance ;
 wndclass.hIcon         = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ICON)) ;
 wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
 wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
 wndclass.lpszMenuName  = szAppName ;
 wndclass.lpszClassName = szAppName ;

 if (!RegisterClass (&wndclass))
 {
  MessageBox (NULL, TEXT ("This program requires Windows NT!"),
    szAppName, MB_ICONERROR) ;
  return 0 ;
 }
    
 hwnd = CreateWindow ( szAppName,  // window class name
                          TEXT ("连连看 V1.08.18.01"), // window caption
                          WS_OVERLAPPEDWINDOW &
     ~WS_MAXIMIZEBOX & ~WS_SIZEBOX,// window style
     //没有最大化按钮和无法改变窗口大小
                          CW_USEDEFAULT,  // initial x position
                          CW_USEDEFAULT,  // initial y position
                          xsize,  // initial x size
                          ysize,  // initial y size
                          NULL,    // parent window handle
                          NULL,    // window menu handle
                          hInstance,   // program instance handle
                          NULL ) ;   // creation parameters
    
 ShowWindow (hwnd, iCmdShow) ;
 UpdateWindow (hwnd) ;
    
 hAccel = LoadAccelerators (hInstance, TEXT ("MY_ACCELERATOR")) ;

 while(GetMessage (&msg, NULL, 0, 0))
 {
  if(!TranslateAccelerator (hwnd, hAccel, &msg))
  {
                  TranslateMessage (&msg) ;
                  DispatchMessage (&msg) ;
  }
 }

 return msg.wParam ;
}

BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message,
                            WPARAM wParam, LPARAM lParam)
{
     switch (message)
     {
     case WM_INITDIALOG :
          return TRUE ;
         
     case WM_COMMAND :
          switch (LOWORD (wParam))
          {
          case IDOK :
          case IDCANCEL :
               EndDialog (hDlg, 0) ;
               return TRUE ;
          }
          break ;
     }
     return FALSE ;
}

LRESULT CALLBACK WndProc ( HWND hwnd, UINT message,
    WPARAM wParam, LPARAM lParam )
{
 HDC  hdc,hdcMem;
 //HBRUSH hBrush ;
 PAINTSTRUCT ps ;//绘图结构
 static RECT  rect,rect2 ;//矩形
 static HBITMAP hBitmap1,hBitmap2;//两个位图文件句柄
 HBITMAP hBitmap3;
 BITMAP  bitmap ;//位图文件
 static int cxBack,cyBack,cxPre,cyPre,cxStart,cyStart;
    //cxBack,cyBack:背景图片大小
    //cxPre,cyPre:牌面图片大小  
 int x,y,i,j,num;

 bool find;//是否有路径标志
 static bool first_started=false;//是否是刚打开程序
 static bool bPrompt=false;//是否提示
 TCHAR    szBuffer[14];
 static HINSTANCE hInstance ;
 static HMENU  hMenu ;//菜单句柄
 static int  iCurrentLevel = IDM_APP_LOW ;//记录游戏难度
 static int  iTime = 100 ;//记录游戏的剩余时间
 static  int  iShuffle=0,iPrompt=0;
  //iShuffle:重新洗牌的剩余次数,iPrompt:提示的剩余次数
 static int iCount=0;//统计消去的对数,用于判断是否胜利
 static Linker_Matrix linker ;//连连看的运算矩阵
 static point  pSelected[2] ;//用于记录选择的两个点
    
 switch (message)
 {
 case WM_CREATE://进行初始化;
  //PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
  //GetClientRect(hwnd,&rect);

  MoveWindow(hwnd,(GetSystemMetrics(SM_CXSCREEN)-xsize)/2,(GetSystemMetrics(SM_CYSCREEN)-ysize)/2,xsize,ysize,false);
  //将窗口移置屏幕中间

  hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;
  hMenu = GetMenu (hwnd) ;
  pSelected[0].x=pSelected[0].y=0;
  pSelected[1].x=pSelected[1].y=0;

  hBitmap1 = LoadBitmap (hInstance, TEXT ("IDB_BITMAP_BACK"));
  hBitmap2 = LoadBitmap (hInstance, TEXT ("IDB_BITMAP_PRE"));
  

  GetObject (hBitmap1, sizeof (BITMAP), &bitmap) ;

  cxBack = bitmap.bmWidth ;
  cyBack = bitmap.bmHeight/7 ;
  GetObject (hBitmap2, sizeof (BITMAP), &bitmap) ;

  cxPre = bitmap.bmWidth/2 ;
  cyPre = bitmap.bmHeight/42 ;

  //SendMessage(hwnd,WM_COMMAND,IDM_APP_START,0);
  first_started=true;
  
  return 0 ;

 case WM_TIMER:
  if(iTime>0)
   iTime--;

  //使字体所在区域无效化,重绘
  rect.left = 0;
  rect.right = xsize;
  rect.top  = 0;
  rect.bottom = 20;
  InvalidateRect (hwnd, &rect, true) ;
  rect.left = 0;
  rect.right = 0;
  rect.top  = 0;
  rect.bottom = 0;

  if( iTime<=0 )
  {
   iCount=0;
   KillTimer (hwnd, TimerID) ;
   MessageBox (hwnd, TEXT ("时间到,你输了!!"),szAppName, MB_OK | MB_ICONQUESTION) ;
   

   SendMessage(hwnd,WM_COMMAND,IDM_APP_START,0);

   linker=Linker_Matrix();
   InvalidateRect (hwnd, NULL, true) ;
  }
  


  return 0;

  

 case WM_PAINT:
  hdc = BeginPaint (hwnd, &ps) ;
  
  //GetClientRect (hwnd, &rect) ;
  hdcMem = CreateCompatibleDC (hdc) ;
   
  

  //绘制牌面
  for(i=1; i<=M-2; i++ )
   for(j=1; j<=N-2; j++ )
   {
    num=linker.get_element(i,j);
    if( num!=0 )
    {
    x=i*(cxBack-3);
    y=j*(cyBack-4)-30;
    SelectObject (hdcMem, hBitmap1) ;
    BitBlt (hdc, x, y, cxBack, cyBack, hdcMem, 0, cyBack*(num%6+1), SRCCOPY) ;
    SelectObject (hdcMem, hBitmap2) ;
    BitBlt (hdc, x+1, y+6, cxPre, cyPre, hdcMem,  cxPre, cyPre*num, SRCAND) ;
    BitBlt (hdc, x+1, y+6, cxPre, cyPre, hdcMem,  0, cyPre*num, SRCPAINT) ;
   
    }
   }
  
  //当选中第一张牌时,在上面画个圈
  if(rect.left!=0 && rect.right!=0 && rect.top!=0 && rect.bottom!=0 && bPrompt==false)
  {
   SelectObject (hdc, GetStockObject (GRAY_BRUSH)) ;
   Ellipse(hdc,rect.left ,rect.top ,rect.left+10 ,rect.top+10 );
   rect.left=0;
   rect.right=0 ;
   rect.top=0;
   rect.bottom=0;

  }
  if( first_started==false)
  {
   sprintf(szBuffer,"剩余时间: %d 秒",iTime);
   TextOut (hdc, 0, 0, szBuffer, strlen (szBuffer)) ;
   TextOut (hdc, xsize/5, 0, TEXT("每消去一对剩余时间+2秒"), strlen (TEXT("每消去一对剩余时间+3秒"))) ;
   sprintf(szBuffer,"剩余洗牌次数: %d 次",iShuffle);
   TextOut (hdc, xsize/2+10, 0, szBuffer, strlen (szBuffer)) ;
   sprintf(szBuffer,"剩余提示次数: %d 次",iPrompt);
   TextOut (hdc, xsize/4*3, 0, szBuffer, strlen (szBuffer)) ;
  }

  if(first_started)
  {//第一次打开程序

   /*SendMessage(hwnd,WM_COMMAND,IDM_APP_ABOUT,0);
   //发送 单击关于菜单 消息
   SendMessage(hwnd,WM_COMMAND,IDM_APP_START,0);
   //发送 单击开始游戏菜单 消息,询问是否开始;*/
   hBitmap3 = LoadBitmap (hInstance, TEXT ("IDB_BITMAP_START"));
   GetObject (hBitmap3, sizeof (BITMAP), &bitmap) ;
   cxStart = bitmap.bmWidth;
   cyStart = bitmap.bmHeight;

   SelectObject (hdcMem, hBitmap3) ;
   StretchBlt  (hdc, 0, 0, xsize, ysize, hdcMem, 0,0, cxStart, cyStart,MERGECOPY) ;
   PlaySound (TEXT ("start.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
   //first_started=false;
  }
 
  if(bPrompt)
  {
   SelectObject (hdc, GetStockObject (BLACK_BRUSH)) ;
   Ellipse(hdc,rect.left ,rect.top ,rect.left+10 ,rect.top+10 );
   Ellipse(hdc,rect2.left ,rect2.top ,rect2.left+10 ,rect2.top+10 );
   rect.left=0;
   rect.right=0 ;
   rect.top=0;
   rect.bottom=0;
   rect2.left=0;
   rect2.right=0 ;
   rect2.top=0;
   rect2.bottom=0;

   bPrompt=false;
  }

  DeleteDC (hdcMem) ;
  EndPaint (hwnd, &ps) ;

  return 0 ;
 case WM_INITMENUPOPUP:

  if( first_started==false )
  {
   EnableMenuItem ((HMENU) wParam, IDM_APP_RESHUFFLE,   MF_ENABLED) ;
   EnableMenuItem ((HMENU) wParam, IDM_APP_PROMPT,   MF_ENABLED) ;
  }

  if(iShuffle==0)
   EnableMenuItem ((HMENU) wParam, IDM_APP_RESHUFFLE,  MF_GRAYED) ;
  if(iPrompt==0)
   EnableMenuItem ((HMENU) wParam, IDM_APP_PROMPT,  MF_GRAYED) ;

  
  break;

 case WM_COMMAND :
  switch (LOWORD (wParam))
  {

  case IDM_APP_START://单击开始游戏菜单
   if ( IDYES == MessageBox (hwnd, TEXT ("开始游戏吗?"),
    szAppName, MB_YESNO | MB_ICONQUESTION) )
   //弹出确认窗口,按YES开始游戏
   {
    if ( iCurrentLevel==IDM_APP_LOW )
    {//难度为低
     iTime=90;
     iPrompt=3;
     iShuffle=2;
     linker=Linker_Matrix(6);
    
    }

    if ( iCurrentLevel==IDM_APP_MIDDLE )
    {//难度为中
     iTime=90;
     iPrompt=3;
     iShuffle=2;
     linker=Linker_Matrix(4);
     
    }
    
    if ( iCurrentLevel==IDM_APP_HIGH )
    {//难度为高
     iTime=60;
     iPrompt=3;
     iShuffle=1;
     linker=Linker_Matrix(4);
    
    }
   
    SetTimer (hwnd, TimerID, 1000, NULL) ;
    InvalidateRect (hwnd, NULL, TRUE) ;
    first_started=false;
    iCount=0;

   }
   else
    SendMessage(hwnd,WM_CLOSE,0,0);
   break;

  case IDM_APP_EXIT ://单击退出游戏菜单
   SendMessage(hwnd,WM_CLOSE,0,0);
   break;

  case IDM_APP_ABOUT ://单击关于菜单
   DialogBox (hInstance, TEXT ("AboutBox"), hwnd, AboutDlgProc) ;
   break ;

  case IDM_APP_LOW:
  case IDM_APP_MIDDLE:
  case IDM_APP_HIGH:
   //单击难度菜单
   CheckMenuItem (hMenu, iCurrentLevel, MF_UNCHECKED) ;
   iCurrentLevel = LOWORD (wParam) ;
   CheckMenuItem (hMenu, iCurrentLevel, MF_CHECKED) ;
   break;

  case IDM_APP_RESHUFFLE://单击重新洗牌按钮
   if(iShuffle>0 )
   { 
    iShuffle--;
    linker.reShuffle();
   }
   //if(iShuffle==0)
    //EnableMenuItem ((HMENU) wParam, IDM_APP_RESHUFFLE,  MF_GRAYED) ;
   
   //使文字所在区域无效化,重绘
   /*rect.left = 0;
   rect.right = xsize;
   rect.top  = 0;
   rect.bottom = 20;*/
   InvalidateRect (hwnd, NULL , true) ;
   rect.left = 0;
   rect.right = 0;
   rect.top  = 0;
   rect.bottom = 0;
   break;

  case IDM_APP_PROMPT:
   if(iPrompt>0 && linker.auto_search() )//提示次数>0,且找到匹配
   {
    //pSelected[0].x=pSelected[0].y=0;
    linker.get_point(pSelected[0],pSelected[1]);
    iPrompt--;

    //使文字所在区域无效化,重绘
    rect.left = 0;
    rect.right = xsize;
    rect.top  = 0;
    rect.bottom = 20;
    InvalidateRect (hwnd, &rect, true) ;
    rect.left = 0;
    rect.right = 0;
    rect.top  = 0;
    rect.bottom = 0;
     
    //sprintf(szBuffer," %d %d %d %d",pSelected[0].x,pSelected[0].y,pSelected[1].x,pSelected[1].y);
    //MessageBox (hwnd, szBuffer,szAppName, MB_OK | MB_ICONQUESTION) ;
    
    rect.left = pSelected[0].x*(cxBack-3);
    rect.right = rect.left+(cxBack-3)+3;
    rect.top  = pSelected[0].y *(cyBack-4)-30;
    rect.bottom = rect.top + (cyBack-4)+4;
    //Ellipse(hdc,rect.left ,rect.top ,rect.right ,rect.bottom );
    InvalidateRect (hwnd, &rect, true) ;
    
    rect2.left = pSelected[1].x *(cxBack-3);
    rect2.right = rect2.left+(cxBack-3)+3;
    rect2.top  = pSelected[1].y *(cyBack-4)-30;
    rect2.bottom = rect2.top + (cyBack-4)+4;
    //Ellipse(hdc,rect.left ,rect.top ,rect.right ,rect.bottom );
    InvalidateRect (hwnd, &rect2, true) ;
 
    pSelected[0].x=0;
    pSelected[0].y=0;
    pSelected[1].x=0;
    pSelected[1].y=0;

   }

   bPrompt=true;
   //if(iPrompt==0)
    //EnableMenuItem ((HMENU) wParam, IDM_APP_PROMPT,  MF_GRAYED) ;
   break;
  }
  return 0 ;
 case WM_LBUTTONUP:
  //取得鼠标坐标
  x= LOWORD (lParam)/(cxBack-3);
  y= ( HIWORD (lParam)+30)/(cyBack-4);
  if (x>=1 && x<=M-2 && y>=1 && y<=N-2 && linker.get_element(x,y)!=0 )
  {
  /*
  sprintf(szBuffer,"%d",y);
  MessageBox (hwnd, TEXT (szBuffer),
    szAppName, MB_YESNO | MB_ICONQUESTION) ;*/
  //如果是在第一张牌按下鼠标
  if(pSelected[0].x==0 && pSelected[0].y==0 )
  {
   //hBrush = GetStockObject (GRAY_BRUSH) ;
   //SelectObject (hdc, hBrush) ;
   
   //hdc = BeginPaint (hwnd, &ps) ;
   //SelectObject (hdc, GetStockObject (BLACK_PEN)) ;

   //在该牌上画圆
    rect.left = x *(cxBack-3);
    rect.right = rect.left+(cxBack-3)+3;
    rect.top  = y *(cyBack-4)-30;
    rect.bottom = rect.top + (cyBack-4)+4;
    //Ellipse(hdc,rect.left ,rect.top ,rect.right ,rect.bottom );
    InvalidateRect (hwnd, &rect, true) ;
    //EndPaint (hwnd, &ps) ;
   //把牌的位置记录下来
   pSelected[0].x=x;
   pSelected[0].y=y;
  }
  else
  { //如果是第二张牌上按鼠标

   //把牌的位置记录下来
   pSelected[1].x=x;
   pSelected[1].y=y;

  
   if( (pSelected[0].x!=pSelected[1].x ||
    pSelected[0].y!=pSelected[1].y) &&
    linker.is_matched(pSelected[0],pSelected[1]) )
   {//如果不是同一张牌并且花色一致
    
    //寻找路径
    find=linker.man_search(pSelected[0],pSelected[1])
     || linker.man_search(pSelected[1],pSelected[0]);;

    if(find)
    {//找到

     //GetClientRect (hwnd, &rect) ;
     rect.left = pSelected[0].x *(cxBack-3);
     rect.right = rect.left+(cxBack-3)+3;
     rect.top  = pSelected[0].y *(cyBack-4)-30;
     rect.bottom = rect.top + (cyBack-4)+4;
     InvalidateRect (hwnd, &rect, true) ;

     rect.left = pSelected[1].x *(cxBack-3);
     rect.right = rect.left+(cxBack-3)+3;
     rect.top  = pSelected[1].y *(cyBack-4)-30;
     rect.bottom = rect.top + (cyBack-4)+4;
     InvalidateRect (hwnd, &rect, true) ;

     rect.left=0;
     rect.right=0 ;
     rect.top=0;
     rect.bottom=0;

     iCount++;
     iTime+=2;

     PlaySound (TEXT ("yes.wav"), NULL, SND_FILENAME | SND_ASYNC) ;

     //InvalidateRect (hwnd, NULL, true) ;

    }
    else
    {//没找到
    /*
     sprintf(szBuffer,"%d",find);
     MessageBox (hwnd, TEXT (szBuffer),
     szAppName, MB_YESNO | MB_ICONQUESTION) ;*/

     rect.left = pSelected[0].x *(cxBack-3);
     rect.right = rect.left+(cxBack-3)+3;
     rect.top  = pSelected[0].y *(cyBack-4)-30;
     rect.bottom = rect.top + (cyBack-4)+4;
     InvalidateRect (hwnd, &rect, true) ;

     rect.left=0;
     rect.right=0 ;
     rect.top=0;
     rect.bottom=0;
     PlaySound (TEXT ("no.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
    
    }
    pSelected[0].x=0;
    pSelected[0].y=0;
    pSelected[1].x=0;
    pSelected[1].y=0;

    
   }
   else
   {//同一张牌或花色不一致

    rect.left = pSelected[0].x *(cxBack-3);
    rect.right = rect.left+(cxBack-3)+3;
    rect.top  = pSelected[0].y *(cyBack-4)-30;
    rect.bottom = rect.top + (cyBack-4)+4;
    InvalidateRect (hwnd, &rect, true) ;

    pSelected[0].x=x;
    pSelected[0].y=y;
    pSelected[1].x=0;
    pSelected[1].y=0;

    rect.left = pSelected[0].x *(cxBack-3);
    rect.right = rect.left+(cxBack-3)+3;
    rect.top  = pSelected[0].y *(cyBack-4)-30;
    rect.bottom = rect.top + (cyBack-4)+4;
    InvalidateRect (hwnd, &rect, true) ;
    /*
    rect.left=0;
    rect.right=0 ;
    rect.top=0;
    rect.bottom=0;*/
   }
  

  }
  }

  if( iCount==(M-2)*(N-2)/2 )
  { 
   iCount=0;
   KillTimer (hwnd, TimerID) ;
   MessageBox (hwnd, TEXT ("恭喜你,你赢了!!"),szAppName, MB_OK | MB_ICONQUESTION) ;


   SendMessage(hwnd,WM_COMMAND,IDM_APP_START,0);
  }
  return 0;
  

 case WM_CLOSE://用户关闭程序
  if ( IDYES == MessageBox (hwnd, TEXT ("确认关闭程序"),
    szAppName, MB_YESNO | MB_ICONQUESTION) )
  //弹出确认窗口,按YES退出程序
  {
   PlaySound (TEXT ("close.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
   KillTimer (hwnd, TimerID) ;
   DestroyWindow (hwnd) ;
   Sleep(2000);
  }
  return 0 ;
 case WM_DESTROY:
  
  PostQuitMessage (0) ;
  return 0 ;
 }

 return DefWindowProc (hwnd, message, wParam, lParam) ;
}

posted on 2006-09-17 21:48 杨粼波 阅读(1442) 评论(0)  编辑 收藏 引用 所属分类: 文章收藏


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理