|
连连看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) ;
- }
复制代码
|
|