(轉)連連看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 楊粼波 閱讀(1447) 評論(0) 編輯 收藏 引用 所屬分類: 文章收藏