分享
 
 
 

连连看API版本的源代码

王朝vc·作者佚名  2006-01-10
窄屏简体版  字體: |||超大  

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) ;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有