依星源码资源网,依星资源网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

【好消息,好消息,好消息】VIP会员可以发表文章赚积分啦 !
查看: 289|回复: 0

连连看API版本的源代码

[复制链接] 主动推送

2076

主题

2083

帖子

3214

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3214
发表于 2024-6-30 20:58:02 | 显示全部楼层 |阅读模式
连连看API版本的源代码
  1. head.h

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

  6. struct point
  7. {
  8. int x;
  9. int y;
  10. };

  11. /*********************************************************/

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

  23. /*********************************************************/

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

  41. Linker_Matrix();
  42. Linker_Matrix( int low, int high, int num );
  43. //随机选择元素初始化,元素值的范围在low-high,
  44. //每个值有num个;
  45. Linker_Matrix( int num );
  46. //随机选择元素初始化,从1开始,每个值有num个;

  47. void show_matrix();
  48. void count( int low, int high );//统计各个值的个数,测试用;
  49. bool auto_search();//自动搜索出一对配对的牌
  50. bool find_way( point p1, point p2 );
  51. //搜索路径 true-有路径 false-无;
  52. void auto_play();//自动完成所有的配对;
  53. void init_search();//进行搜索前的初始化
  54. bool man_search( point p1,  point p2);
  55. bool is_matched( point p1, point p2 );
  56. //是否配对 true-配对 false-否;
  57. int  get_element( int x, int y );
  58. void get_point(point &p1,point &p2);
  59. //通过p1,p2提取自动搜索出的匹配两点
  60. void reShuffle();//重新洗牌;
  61. };

  62. /*********************************************************/

  63. head.cpp

  64. #include "head.h"
  65. #include<iostream.h>
  66. #include<fstream.h>
  67. #include<stdlib.h>
  68. #include<stdio.h>
  69. #include<math.h>
  70. #include<time.h>
  71. #include<conio.h>

  72. template < typename T, int m, int n >
  73. Matrix < T, m, n >::Matrix()
  74. {
  75. for( int i=0; i<m; i++ )
  76. for( int j=0; j<n; j++ )
  77.   matrix[i][j] = 0;

  78. }

  79. template < typename T, int m, int n >
  80. Matrix< T, m, n >::Matrix( char* filename )
  81. {
  82. ifstream infile(filename);

  83. for( int i=0; i<M; i++ )
  84. for( int j=0; j<N; j++ )
  85.   infile >> matrix[i][j];
  86. }

  87. template < typename T, int m, int n >
  88. void Matrix< T, m, n >::show_matrix()
  89. {
  90. for( int i=0; i<m; i++ )
  91. {
  92. for( int j=0; j<n; j++ )
  93.   cout<< matrix[i][j]<<´\t´;
  94. cout<<endl;
  95. }
  96. cout<<endl;
  97. }

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

  103. template < typename T, int m, int n >
  104. T Matrix< T, m, n >::get_element( int x, int y )
  105. {
  106. return matrix[x][y];
  107. }

  108. /*********************************************************/

  109. Linker_Matrix::Linker_Matrix():Matrix< int, M, N >()
  110. {
  111. p1.x = p1.y = 0;
  112. p2.x = p2.y = 0;
  113. index = 0;
  114. turn_count = 0;
  115. //max=0;

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

  119. Linker_Matrix::Linker_Matrix( int low, int high, int num )
  120. :Matrix< int, M, N >()
  121. {

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

  124. p1.x = p1.y = 0;
  125. p2.x = p2.y = 0;
  126. index = 0;

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

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

  131. for( int i=low; i<=high; i++ )
  132. for( int j=0; j<num; j++ )
  133. {
  134.   do
  135.   {
  136.   m = rand()%(M-2) + 1;
  137.   n = rand()%(N-2) + 1;
  138.   }
  139.   while( 0==m || 0==n || 0!=matrix[m][n] );
  140.   matrix[m][n]=i;
  141. }
  142. }

  143. Linker_Matrix::Linker_Matrix(int num ):Matrix< int, M, N >()
  144. {

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

  147. p1.x = p1.y = 0;
  148. p2.x = p2.y = 0;
  149. index = 0;

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

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

  154. for( int i=1; i<=(M-2)*(N-2)/num; i++ )
  155. for( int j=0; j<num; j++ )
  156. {
  157.   do
  158.   {
  159.   m = rand()%(M-2) + 1;
  160.   n = rand()%(N-2) + 1;
  161.   }
  162.   while( 0==m || 0==n || 0!=matrix[m][n] );
  163.   matrix[m][n]=i;
  164. }
  165. }

  166. void Linker_Matrix::show_matrix()
  167. {

  168. for( int i=1; i<M-1; i++ )
  169. {
  170. for( int j=1; j<N-1; j++ )
  171.   cout<<matrix[i][j]<<´\t´;
  172. cout<<endl;
  173. }
  174. cout<<endl;
  175. }

  176. void Linker_Matrix::count( int low, int high )
  177. {
  178. int *num,k;

  179. //动态分配
  180. num = new int[ high-low+2 ];
  181. //初始化
  182. for( k=0; k<high-low+2; k++ )
  183. num[k]=0;

  184. //计数
  185. for( int i=1; i<M-1; i++ )
  186. for( int j=1; j<N-1; j++ )
  187.   num[ matrix[i][j] ]++;

  188. //输出
  189. for( k=0; k<high-low+2; k++ )
  190. cout<<k<<":"<<num[k]<<´\t´;
  191. cout<<endl;

  192. //销毁
  193. delete[] num;
  194. }

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

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

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

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

  218.    init_search();
  219.    /*if(k==29)
  220.    {
  221.    init_search();
  222.    show_matrix();
  223.    }*/
  224.    
  225.    if ( is_matched( p1, p2 ) && find_way( p1, p2 ) )
  226.    /*逻辑式这样写的原因是只要is_matched(p1,p2)为false,
  227.    逻辑式必为false,find_way(p1,p2)就不会执行;
  228.    当两元素数值相同且有路径时,执行下面
  229.    */
  230.    {
  231.     //show_matrix();
  232.     //cout<<turn_count<<endl;
  233.     //matrix[ p1.x ][ p1.y ] = 0;
  234.     //matrix[ p2.x ][ p2.y ] = 0;
  235.     //k++;
  236.     //cout<<p1.x<<´ ´<<p1.y<<´ ´<<p2.x<<´ ´<<p2.y<<´:´<<k<<endl;
  237.     //show_matrix();
  238.     //count(1,21);
  239.     //goto jump;
  240.     //找到一个就退出
  241.    
  242.     return true;
  243.    //}
  244.    }
  245.    
  246.   }/*
  247.   if( k>MAX)//搜索次数过大,强制跳出
  248.     return false;*/
  249.   }
  250. }
  251. //jump:  ;
  252. }

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

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

  265. int i,j;
  266. int px1,px2,py1,py2;
  267. int temp;
  268. bool x_across,y_across;

  269. //如果相邻
  270. if( ( p1.x+1==p2.x && p1.y==p2.y )
  271. || ( p1.x==p2.x && p1.y+1==p2.y )
  272. || ( p1.x-1==p2.x && p1.y==p2.y )
  273. || ( p1.x==p2.x && p1.y-1==p2.y ) )
  274. {
  275. //把路径记录下来
  276. //起点
  277. way[0].x=p1.x;
  278. way[0].y=p1.y;
  279. //直线转折点为0
  280. way[1].x=0;
  281. way[1].y=0;
  282. way[2].x=0;
  283. way[2].y=0;
  284. //终点
  285. way[3].x=p2.x;
  286. way[3].y=p2.y;

  287. return true;
  288. }

  289. //直线连通
  290. //如果在水平方向上
  291. if( p1.x==p2.x )
  292. {
  293. if(p1.y>p2.y)
  294. {
  295.   temp=p1.y;
  296.   p1.y=p2.y;
  297.   p2.y=temp;
  298. }

  299. for(j=p1.y+1; j<p2.y; j++ )
  300. {
  301.   if( matrix[p1.x][j]!=0)
  302.   {
  303.   break;
  304.   }
  305. }

  306. //如果两点之间相通
  307. if(j==p2.y &&  matrix[p1.x][j-1]==0 )
  308. {
  309.   
  310.   //把路径记录下来
  311.   //起点
  312.   way[0].x=p1.x;
  313.   way[0].y=p1.y;
  314.   //直线转折点为0
  315.   way[1].x=0;
  316.   way[1].y=0;
  317.   way[2].x=0;
  318.   way[2].y=0;
  319.   //终点
  320.   way[3].x=p2.x;
  321.   way[3].y=p2.y;

  322.   return true;
  323. }
  324. }

  325. //如果在垂直方向上
  326. if( p1.y==p2.y )
  327. {
  328. if(p1.x>p2.x)
  329. {
  330.   temp=p1.x;
  331.   p1.x=p2.x;
  332.   p2.x=temp;
  333. }

  334. for(i=p1.x+1; i<p2.x; i++ )
  335. {
  336.   if( matrix[i][p1.y]!=0)
  337.   {
  338.   break;
  339.   }
  340. }
  341. //如果两点之间相通
  342. if(i==p2.x &&  matrix[i-1][p1.y]==0 )
  343. {


  344.   //把路径记录下来
  345.   //起点
  346.   way[0].x=p1.x;
  347.   way[0].y=p1.y;
  348.   //直线转折点为0
  349.   way[1].x=0;
  350.   way[1].y=0;
  351.   way[2].x=0;
  352.   way[2].y=0;
  353.   //终点
  354.   way[3].x=p2.x;
  355.   way[3].y=p2.y;

  356.   return true;
  357. }
  358. }



  359. //折线连通
  360. /*if( p1.x!=p2.x && p1.y!=p2.y)
  361. {*/
  362. if(p1.y>p2.y)
  363. {
  364.   //两点交换
  365.   temp=p1.x;
  366.   p1.x=p2.x;
  367.   p2.x=temp;

  368.   temp=p1.y;
  369.   p1.y=p2.y;
  370.   p2.y=temp;


  371. }


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

  376. //是否水平连通
  377. for(j=p1.y+1; j<=p2.y-1; j++ )
  378. {
  379.   if(matrix[i][j]!=0 )
  380.   {
  381.   x_across=false;
  382.   break;
  383.   }
  384. }

  385. if(matrix[i][p1.y]!=0  )
  386. {
  387.   if( i!=p1.x )
  388.   x_across=false;
  389. }
  390. if(matrix[i][p2.y]!=0  )
  391. {
  392.   if( i!=p2.x )
  393.   x_across=false;
  394. }
  395.   
  396. if(x_across)
  397. {//水平连通才执行下面
  398. /* for(j=1; j<N-2; j++ )
  399.   {*/
  400.   //检验在垂直上是否连通

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

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

  412.   //如果两点都为空
  413.   //垂直向p1点靠近一格
  414.   if(px1<p1.x)
  415.    px1++;
  416.   else if(px1>p1.x)
  417.    px1--;
  418.   //垂直向p2点靠近一格
  419.   if(px2<p2.x)
  420.    px2++;
  421.   else if(px2>p2.x)
  422.    px2--;
  423.   }
  424.    
  425.   //如果能到达两个端点
  426.   if(px1==p1.x && py1==p1.y && px2==p2.x && py2==p2.y )
  427.   {
  428.   //起点
  429.   way[0].x=p1.x;
  430.   way[0].y=p1.y;
  431.   //两个转折点
  432.   way[1].x=i;
  433.   way[1].y=p1.y;
  434.   way[2].x=i;
  435.   way[2].y=p2.y;
  436.   //终点
  437.   way[3].x=p2.x;
  438.   way[3].y=p2.y;
  439.   return true;
  440.   }

  441. }
  442. }

  443. if(p1.x>p2.x)
  444. {
  445.   //两点交换
  446.   temp=p1.x;
  447.   p1.x=p2.x;
  448.   p2.x=temp;

  449.   temp=p1.y;
  450.   p1.y=p2.y;
  451.   p2.y=temp;


  452. }
  453. //纵向扫描
  454. for(j=0;j<=N-1;j++)
  455. {
  456. y_across=true;
  457. //是否垂直连通
  458. for(i=p1.x+1; i<=p2.x-1; i++ )
  459. {
  460.   if(matrix[i][j]!=0)
  461.   {
  462.   y_across=false;
  463.   break;
  464.   }
  465. }

  466. if(matrix[p1.x][j]!=0  )
  467. {
  468.   if( j!=p1.y )
  469.   y_across=false;
  470. }
  471. if(matrix[p2.x][j]!=0  )
  472. {
  473.   if( j!=p2.y )
  474.   y_across=false;
  475. }
  476.   
  477. if(y_across)
  478. {//垂直连通才执行下面
  479. /* for(j=1; j<N-2; j++ )
  480.   {*/
  481.   //检验在水平上是否连通

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

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

  493.   //如果两点都为空
  494.   //水平向p1点靠近一格
  495.   if(py1<p1.y)
  496.    py1++;
  497.   else if(py1>p1.y)
  498.    py1--;
  499.   //水平向p2点靠近一格
  500.   if(py2<p2.y)
  501.    py2++;
  502.   else if(py2>p2.y)
  503.    py2--;
  504.   }
  505.    
  506.   //如果能到达两个端点
  507.   if(px1==p1.x && py1==p1.y && px2==p2.x && py2==p2.y )
  508.   {
  509.   //起点
  510.   way[0].x=p1.x;
  511.   way[0].y=p1.y;
  512.   //两个转折点
  513.   way[1].x=p1.x;
  514.   way[1].y=j;
  515.   way[2].x=p2.x;
  516.   way[2].y=j;
  517.   //终点
  518.   way[3].x=p2.x;
  519.   way[3].y=p2.y;
  520.   return true;
  521.   }

  522. }
  523. }
  524. //}
  525. return false;

  526. }

  527. void Linker_Matrix::init_search()
  528. {
  529. visited = Matrix< int, M, N >();
  530. index = 0;
  531. turn_count = 0;
  532. }

  533. void Linker_Matrix::auto_play()
  534. {
  535. while( auto_search() );
  536. }

  537. bool Linker_Matrix::man_search(const point p1, const point p2)
  538. {
  539. init_search();
  540. if( find_way( p1, p2 ) )
  541. {
  542. matrix[p1.x][p1.y]=0;
  543. matrix[p2.x][p2.y]=0;
  544. return true;
  545. }
  546. return false;
  547. }

  548. int Linker_Matrix::get_element( int x, int y )
  549. {
  550.   return matrix[x][y];
  551. }

  552. void Linker_Matrix::get_point(point &p1,point &p2)
  553. {
  554. //if( auto_search() )
  555. //{
  556. p1=this->p1;
  557. p2=this->p2;
  558. //return true;
  559. //}

  560. //return false;
  561. }

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

  566. //p1.x = p1.y = 0;
  567. //p2.x = p2.y = 0;
  568. //index = 0;

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

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

  573. for( int i=1; i<=(M-2); i++ )
  574. for( int j=1; j<=(N-2); j++ )
  575. {
  576. if(matrix[i][j]!=0)
  577. {
  578.   do
  579.   {
  580.   m = rand()%(M-2) + 1;
  581.   n = rand()%(N-2) + 1;
  582.   }
  583.   while( 0==matrix[m][n] );

  584.   k=matrix[i][j];
  585.   matrix[i][j]=matrix[m][n];
  586.   matrix[m][n]=k;
  587. }
  588. }
  589. }

  590. linker.cpp

  591. #include<stdlib.h>
  592. #include<stdio.h>
  593. #include<string.h>
  594. #include <windows.h>

  595. #include "head.h"
  596. #include "resource.h"

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


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

  601. int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  602.            PSTR szCmdLine, int iCmdShow )
  603. {
  604. HWND     hwnd ;
  605. MSG      msg ;
  606. WNDCLASS   wndclass ;
  607. HACCEL hAccel ;//快捷键表


  608. wndclass.style     = CS_HREDRAW | CS_VREDRAW ;
  609. wndclass.lpfnWndProc  = WndProc ;
  610. wndclass.cbClsExtra   = 0 ;
  611. wndclass.cbWndExtra   = 0 ;
  612. wndclass.hInstance   = hInstance ;
  613. wndclass.hIcon     = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ICON)) ;
  614. wndclass.hCursor    = LoadCursor (NULL, IDC_ARROW) ;
  615. wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
  616. wndclass.lpszMenuName  = szAppName ;
  617. wndclass.lpszClassName = szAppName ;

  618. if (!RegisterClass (&wndclass))
  619. {
  620. MessageBox (NULL, TEXT ("This program requires Windows NT!"),
  621.   szAppName, MB_ICONERROR) ;
  622. return 0 ;
  623. }
  624.   
  625. hwnd = CreateWindow ( szAppName, // window class name
  626.               TEXT ("连连看 V1.08.18.01"), // window caption
  627.               WS_OVERLAPPEDWINDOW &
  628.    ~WS_MAXIMIZEBOX & ~WS_SIZEBOX,// window style
  629.    //没有最大化按钮和无法改变窗口大小
  630.               CW_USEDEFAULT, // initial x position
  631.               CW_USEDEFAULT, // initial y position
  632.               xsize, // initial x size
  633.               ysize, // initial y size
  634.               NULL,  // parent window handle
  635.               NULL,  // window menu handle
  636.               hInstance,  // program instance handle
  637.               NULL ) ;  // creation parameters
  638.   
  639. ShowWindow (hwnd, iCmdShow) ;
  640. UpdateWindow (hwnd) ;
  641.   
  642. hAccel = LoadAccelerators (hInstance, TEXT ("MY_ACCELERATOR")) ;

  643. while(GetMessage (&msg, NULL, 0, 0))
  644. {
  645. if(!TranslateAccelerator (hwnd, hAccel, &msg))
  646. {
  647.           TranslateMessage (&msg) ;
  648.           DispatchMessage (&msg) ;
  649. }
  650. }

  651. return msg.wParam ;
  652. }

  653. BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message,
  654.                WPARAM wParam, LPARAM lParam)
  655. {
  656.    switch (message)
  657.    {
  658.    case WM_INITDIALOG :
  659.       return TRUE ;
  660.      
  661.    case WM_COMMAND :
  662.       switch (LOWORD (wParam))
  663.       {
  664.       case IDOK :
  665.       case IDCANCEL :
  666.         EndDialog (hDlg, 0) ;
  667.         return TRUE ;
  668.       }
  669.       break ;
  670.    }
  671.    return FALSE ;
  672. }

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

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

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

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

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


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

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

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

  720. //SendMessage(hwnd,WM_COMMAND,IDM_APP_START,0);
  721. first_started=true;

  722. return 0 ;

  723. case WM_TIMER:
  724. if(iTime>0)
  725.   iTime--;

  726. //使字体所在区域无效化,重绘
  727. rect.left = 0;
  728. rect.right = xsize;
  729. rect.top  = 0;
  730. rect.bottom = 20;
  731. InvalidateRect (hwnd, &rect, true) ;
  732. rect.left = 0;
  733. rect.right = 0;
  734. rect.top  = 0;
  735. rect.bottom = 0;

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

  742.   SendMessage(hwnd,WM_COMMAND,IDM_APP_START,0);

  743.   linker=Linker_Matrix();
  744.   InvalidateRect (hwnd, NULL, true) ;
  745. }



  746. return 0;



  747. case WM_PAINT:
  748. hdc = BeginPaint (hwnd, &ps) ;

  749. //GetClientRect (hwnd, &rect) ;
  750. hdcMem = CreateCompatibleDC (hdc) ;
  751.   


  752. //绘制牌面
  753. for(i=1; i<=M-2; i++ )
  754.   for(j=1; j<=N-2; j++ )
  755.   {
  756.   num=linker.get_element(i,j);
  757.   if( num!=0 )
  758.   {
  759.   x=i*(cxBack-3);
  760.   y=j*(cyBack-4)-30;
  761.   SelectObject (hdcMem, hBitmap1) ;
  762.   BitBlt (hdc, x, y, cxBack, cyBack, hdcMem, 0, cyBack*(num%6+1), SRCCOPY) ;
  763.   SelectObject (hdcMem, hBitmap2) ;
  764.   BitBlt (hdc, x+1, y+6, cxPre, cyPre, hdcMem,  cxPre, cyPre*num, SRCAND) ;
  765.   BitBlt (hdc, x+1, y+6, cxPre, cyPre, hdcMem,  0, cyPre*num, SRCPAINT) ;
  766.   
  767.   }
  768.   }

  769. //当选中第一张牌时,在上面画个圈
  770. if(rect.left!=0 && rect.right!=0 && rect.top!=0 && rect.bottom!=0 && bPrompt==false)
  771. {
  772.   SelectObject (hdc, GetStockObject (GRAY_BRUSH)) ;
  773.   Ellipse(hdc,rect.left ,rect.top ,rect.left+10 ,rect.top+10 );
  774.   rect.left=0;
  775.   rect.right=0 ;
  776.   rect.top=0;
  777.   rect.bottom=0;

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

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

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

  799.   SelectObject (hdcMem, hBitmap3) ;
  800.   StretchBlt  (hdc, 0, 0, xsize, ysize, hdcMem, 0,0, cxStart, cyStart,MERGECOPY) ;
  801.   PlaySound (TEXT ("start.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
  802.   //first_started=false;
  803. }

  804. if(bPrompt)
  805. {
  806.   SelectObject (hdc, GetStockObject (BLACK_BRUSH)) ;
  807.   Ellipse(hdc,rect.left ,rect.top ,rect.left+10 ,rect.top+10 );
  808.   Ellipse(hdc,rect2.left ,rect2.top ,rect2.left+10 ,rect2.top+10 );
  809.   rect.left=0;
  810.   rect.right=0 ;
  811.   rect.top=0;
  812.   rect.bottom=0;
  813.   rect2.left=0;
  814.   rect2.right=0 ;
  815.   rect2.top=0;
  816.   rect2.bottom=0;

  817.   bPrompt=false;
  818. }

  819. DeleteDC (hdcMem) ;
  820. EndPaint (hwnd, &ps) ;

  821. return 0 ;
  822. case WM_INITMENUPOPUP:

  823. if( first_started==false )
  824. {
  825.   EnableMenuItem ((HMENU) wParam, IDM_APP_RESHUFFLE,  MF_ENABLED) ;
  826.   EnableMenuItem ((HMENU) wParam, IDM_APP_PROMPT,  MF_ENABLED) ;
  827. }

  828. if(iShuffle==0)
  829.   EnableMenuItem ((HMENU) wParam, IDM_APP_RESHUFFLE,  MF_GRAYED) ;
  830. if(iPrompt==0)
  831.   EnableMenuItem ((HMENU) wParam, IDM_APP_PROMPT,  MF_GRAYED) ;


  832. break;

  833. case WM_COMMAND :
  834. switch (LOWORD (wParam))
  835. {

  836. case IDM_APP_START://单击开始游戏菜单
  837.   if ( IDYES == MessageBox (hwnd, TEXT ("开始游戏吗?"),
  838.   szAppName, MB_YESNO | MB_ICONQUESTION) )
  839.   //弹出确认窗口,按YES开始游戏
  840.   {
  841.   if ( iCurrentLevel==IDM_APP_LOW )
  842.   {//难度为低
  843.    iTime=90;
  844.    iPrompt=3;
  845.    iShuffle=2;
  846.    linker=Linker_Matrix(6);
  847.   
  848.   }

  849.   if ( iCurrentLevel==IDM_APP_MIDDLE )
  850.   {//难度为中
  851.    iTime=90;
  852.    iPrompt=3;
  853.    iShuffle=2;
  854.    linker=Linker_Matrix(4);
  855.    
  856.   }
  857.   
  858.   if ( iCurrentLevel==IDM_APP_HIGH )
  859.   {//难度为高
  860.    iTime=60;
  861.    iPrompt=3;
  862.    iShuffle=1;
  863.    linker=Linker_Matrix(4);
  864.   
  865.   }
  866.   
  867.   SetTimer (hwnd, TimerID, 1000, NULL) ;
  868.   InvalidateRect (hwnd, NULL, TRUE) ;
  869.   first_started=false;
  870.   iCount=0;

  871.   }
  872.   else
  873.   SendMessage(hwnd,WM_CLOSE,0,0);
  874.   break;

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

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

  881. case IDM_APP_LOW:
  882. case IDM_APP_MIDDLE:
  883. case IDM_APP_HIGH:
  884.   //单击难度菜单
  885.   CheckMenuItem (hMenu, iCurrentLevel, MF_UNCHECKED) ;
  886.   iCurrentLevel = LOWORD (wParam) ;
  887.   CheckMenuItem (hMenu, iCurrentLevel, MF_CHECKED) ;
  888.   break;

  889. case IDM_APP_RESHUFFLE://单击重新洗牌按钮
  890.   if(iShuffle>0 )
  891.   {
  892.   iShuffle--;
  893.   linker.reShuffle();
  894.   }
  895.   //if(iShuffle==0)
  896.   //EnableMenuItem ((HMENU) wParam, IDM_APP_RESHUFFLE,  MF_GRAYED) ;
  897.   
  898.   //使文字所在区域无效化,重绘
  899.   /*rect.left = 0;
  900.   rect.right = xsize;
  901.   rect.top  = 0;
  902.   rect.bottom = 20;*/
  903.   InvalidateRect (hwnd, NULL , true) ;
  904.   rect.left = 0;
  905.   rect.right = 0;
  906.   rect.top  = 0;
  907.   rect.bottom = 0;
  908.   break;

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

  915.   //使文字所在区域无效化,重绘
  916.   rect.left = 0;
  917.   rect.right = xsize;
  918.   rect.top  = 0;
  919.   rect.bottom = 20;
  920.   InvalidateRect (hwnd, &rect, true) ;
  921.   rect.left = 0;
  922.   rect.right = 0;
  923.   rect.top  = 0;
  924.   rect.bottom = 0;
  925.    
  926.   //sprintf(szBuffer," %d %d %d %d",pSelected[0].x,pSelected[0].y,pSelected[1].x,pSelected[1].y);
  927.   //MessageBox (hwnd, szBuffer,szAppName, MB_OK | MB_ICONQUESTION) ;
  928.   
  929.   rect.left = pSelected[0].x*(cxBack-3);
  930.   rect.right = rect.left+(cxBack-3)+3;
  931.   rect.top  = pSelected[0].y *(cyBack-4)-30;
  932.   rect.bottom = rect.top + (cyBack-4)+4;
  933.   //Ellipse(hdc,rect.left ,rect.top ,rect.right ,rect.bottom );
  934.   InvalidateRect (hwnd, &rect, true) ;
  935.   
  936.   rect2.left = pSelected[1].x *(cxBack-3);
  937.   rect2.right = rect2.left+(cxBack-3)+3;
  938.   rect2.top  = pSelected[1].y *(cyBack-4)-30;
  939.   rect2.bottom = rect2.top + (cyBack-4)+4;
  940.   //Ellipse(hdc,rect.left ,rect.top ,rect.right ,rect.bottom );
  941.   InvalidateRect (hwnd, &rect2, true) ;

  942.   pSelected[0].x=0;
  943.   pSelected[0].y=0;
  944.   pSelected[1].x=0;
  945.   pSelected[1].y=0;

  946.   }

  947.   bPrompt=true;
  948.   //if(iPrompt==0)
  949.   //EnableMenuItem ((HMENU) wParam, IDM_APP_PROMPT,  MF_GRAYED) ;
  950.   break;
  951. }
  952. return 0 ;
  953. case WM_LBUTTONUP:
  954. //取得鼠标坐标
  955. x= LOWORD (lParam)/(cxBack-3);
  956. y= ( HIWORD (lParam)+30)/(cyBack-4);
  957. if (x>=1 && x<=M-2 && y>=1 && y<=N-2 && linker.get_element(x,y)!=0 )
  958. {
  959. /*
  960. sprintf(szBuffer,"%d",y);
  961. MessageBox (hwnd, TEXT (szBuffer),
  962.   szAppName, MB_YESNO | MB_ICONQUESTION) ;*/
  963. //如果是在第一张牌按下鼠标
  964. if(pSelected[0].x==0 && pSelected[0].y==0 )
  965. {
  966.   //hBrush = GetStockObject (GRAY_BRUSH) ;
  967.   //SelectObject (hdc, hBrush) ;
  968.   
  969.   //hdc = BeginPaint (hwnd, &ps) ;
  970.   //SelectObject (hdc, GetStockObject (BLACK_PEN)) ;

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

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


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

  996.   if(find)
  997.   {//找到

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

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

  1009.    rect.left=0;
  1010.    rect.right=0 ;
  1011.    rect.top=0;
  1012.    rect.bottom=0;

  1013.    iCount++;
  1014.    iTime+=2;

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

  1016.    //InvalidateRect (hwnd, NULL, true) ;

  1017.   }
  1018.   else
  1019.   {//没找到
  1020.   /*
  1021.    sprintf(szBuffer,"%d",find);
  1022.    MessageBox (hwnd, TEXT (szBuffer),
  1023.    szAppName, MB_YESNO | MB_ICONQUESTION) ;*/

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

  1029.    rect.left=0;
  1030.    rect.right=0 ;
  1031.    rect.top=0;
  1032.    rect.bottom=0;
  1033.    PlaySound (TEXT ("no.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
  1034.   
  1035.   }
  1036.   pSelected[0].x=0;
  1037.   pSelected[0].y=0;
  1038.   pSelected[1].x=0;
  1039.   pSelected[1].y=0;

  1040.   
  1041.   }
  1042.   else
  1043.   {//同一张牌或花色不一致

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

  1049.   pSelected[0].x=x;
  1050.   pSelected[0].y=y;
  1051.   pSelected[1].x=0;
  1052.   pSelected[1].y=0;

  1053.   rect.left = pSelected[0].x *(cxBack-3);
  1054.   rect.right = rect.left+(cxBack-3)+3;
  1055.   rect.top  = pSelected[0].y *(cyBack-4)-30;
  1056.   rect.bottom = rect.top + (cyBack-4)+4;
  1057.   InvalidateRect (hwnd, &rect, true) ;
  1058.   /*
  1059.   rect.left=0;
  1060.   rect.right=0 ;
  1061.   rect.top=0;
  1062.   rect.bottom=0;*/
  1063.   }


  1064. }
  1065. }

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


  1071.   SendMessage(hwnd,WM_COMMAND,IDM_APP_START,0);
  1072. }
  1073. return 0;


  1074. case WM_CLOSE://用户关闭程序
  1075. if ( IDYES == MessageBox (hwnd, TEXT ("确认关闭程序"),
  1076.   szAppName, MB_YESNO | MB_ICONQUESTION) )
  1077. //弹出确认窗口,按YES退出程序
  1078. {
  1079.   PlaySound (TEXT ("close.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
  1080.   KillTimer (hwnd, TimerID) ;
  1081.   DestroyWindow (hwnd) ;
  1082.   Sleep(2000);
  1083. }
  1084. return 0 ;
  1085. case WM_DESTROY:

  1086. PostQuitMessage (0) ;
  1087. return 0 ;
  1088. }

  1089. return DefWindowProc (hwnd, message, wParam, lParam) ;
  1090. }
复制代码


扫码关注微信公众号,及时获取最新资源信息!下载附件优惠VIP会员5折;永久VIP免费
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

免责声明:
1、本站提供的所有资源仅供参考学习使用,版权归原著所有,禁止下载本站资源参与商业和非法行为,请在24小时之内自行删除!
2、本站所有内容均由互联网收集整理、网友上传,并且以计算机技术研究交流为目的,仅供大家参考、学习,请勿任何商业目的与商业用途。
3、若您需要商业运营或用于其他商业活动,请您购买正版授权并合法使用。
4、论坛的所有内容都不保证其准确性,完整性,有效性,由于源码具有复制性,一经售出,概不退换。阅读本站内容因误导等因素而造成的损失本站不承担连带责任。
5、用户使用本网站必须遵守适用的法律法规,对于用户违法使用本站非法运营而引起的一切责任,由用户自行承担
6、本站所有资源来自互联网转载,版权归原著所有,用户访问和使用本站的条件是必须接受本站“免责声明”,如果不遵守,请勿访问或使用本网站
7、本站使用者因为违反本声明的规定而触犯中华人民共和国法律的,一切后果自己负责,本站不承担任何责任。
8、凡以任何方式登陆本网站或直接、间接使用本网站资料者,视为自愿接受本网站声明的约束。
9、本站以《2013 中华人民共和国计算机软件保护条例》第二章 “软件著作权” 第十七条为原则:为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。若有学员需要商用本站资源,请务必联系版权方购买正版授权!
10、本网站如无意中侵犯了某个企业或个人的知识产权,请来信【站长信箱312337667@qq.com】告之,本站将立即删除。
郑重声明:
本站所有资源仅供用户本地电脑学习源代码的内含设计思想和原理,禁止任何其他用途!
本站所有资源、教程来自互联网转载,仅供学习交流,不得商业运营资源,不确保资源完整性,图片和资源仅供参考,不提供任何技术服务。
本站资源仅供本地编辑研究学习参考,禁止未经资源商正版授权参与任何商业行为,违法行为!如需商业请购买各资源商正版授权
本站仅收集资源,提供用户自学研究使用,本站不存在私自接受协助用户架设游戏或资源,非法运营资源行为。
 
在线客服
点击这里给我发消息 点击这里给我发消息 点击这里给我发消息
售前咨询热线
312337667

微信扫一扫,私享最新原创实用干货

QQ|免责声明|小黑屋|依星资源网 ( 鲁ICP备2021043233号-3 )|网站地图

GMT+8, 2024-11-23 22:57

Powered by Net188.com X3.4

邮箱:312337667@qq.com 客服QQ:312337667(工作时间:9:00~21:00)

快速回复 返回顶部 返回列表