本文共 21927 字,大约阅读时间需要 73 分钟。
head.h
#define M 14
//M为连连看牌的高+2 #define N 10 //N为连连看牌的宽+2struct 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:nofor( 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) ;
}转载地址:http://cyana.baihongyu.com/