Subversion Repositories Kolibri OS

Rev

Rev 4481 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. //
  2.  
  3. #include "kosSyst.h"
  4. #include "KosFile.h"
  5. #include "gfxdef.h"
  6. #include "gameWnd.h"
  7. #include "mcarray.h"
  8. #include "lang.h"
  9.  
  10. //
  11. #define EMPTY_PLACE                             0
  12.  
  13. #define LEVEL_PROGRESS_LEFT             (132+1)
  14. #define LEVEL_PROGRESS_TOP              (388+21)
  15. #define LEVEL_PROGRESS_HEIGHT   4
  16. #define LEVEL_PROGRESS_WIDTH    329
  17. #define LEVEL_PROGRESS_COLOUR   0xDF2933
  18.  
  19. #define BONUS_SOMEBLOCK_TOP             (120+21)
  20. #define BONUS_SOMEBLOCK_LEFT    (46+1)
  21. #define BONUS_FREEBLOCK_TOP             (163+21)
  22. #define BONUS_FREEBLOCK_LEFT    (9+1)
  23. #define BONUS_DIAGBLOCK_TOP             (213+21)
  24. #define BONUS_DIAGBLOCK_LEFT    (48+1)
  25. #define BONUS_PROGRESS_HEIGHT   37
  26. #define BONUS_PROGRESS_WIDTH    4
  27.  
  28. #define LEVEL_SCORE_BASE                50
  29.  
  30. //
  31. CKosBitmap gameFace;
  32. CKosBitmap gameBlocks;
  33. CKosBitmap gameNumbers;
  34. CKosBitmap gameBlocksZ[4];
  35. //
  36. CFishka *fishki[blocksNum];
  37.  
  38. //
  39. char *gameWndTitle;
  40. #if LANG == RUS
  41. char gameWndTitle1[] = "” à ®­ ¦¤ñâ ⥡ï :)\0";
  42. char gameWndTitle2[] = "ã ¢®â...\0";
  43. char gameOverText[] = "„ «ìè¥ ¤®à®£¨ ­¥â!";
  44. #else
  45. char gameWndTitle1[] = "Pharaoh waits for you :)\0";
  46. char gameWndTitle2[] = "Well...\0";
  47. char gameOverText[] = "No further way!";
  48. #endif
  49. //
  50. Word gcx, gcy;
  51. //
  52. #define mapSize                 8
  53. //
  54. //
  55. #define blocksLeft              (134+2)
  56. #define blocksTop               (43+22)
  57. //
  58. #define blockTypesNum   10
  59. //
  60. Byte gameMap[mapSize * mapSize];
  61. // óðîâåíü
  62. int gameLevel;
  63. //
  64. int maxGameLevel;
  65. int startGameLevel;
  66. // ñ÷¸ò
  67. Dword playerScore;
  68. // ñ÷¸ò÷èê äîáàâëåííûõ áëîêîâ
  69. int insertedBlocksCount;
  70. // êîëè÷åñòâî áëîêîâ äëÿ ïåðåõîäà íà ñëåäóþùèé óðîâåíü
  71. int levelBlocksLimit;
  72. // íîìåð âûäåëåííîãî áëîêà
  73. int selectedBlock;
  74. // ïðèáàâëåíèå øàãà äëÿ èíäèêàòîðà ïðîõîæäåíèÿ óðîâíÿ * 1024
  75. int levelProgressStep;
  76. // çàí÷åíèå èíäèêàòîðà ïðîõîæäåíèÿ óðîâíÿ
  77. int levelProgressCount;
  78. // áëîêè äëÿ óäàëåíèÿ
  79. struct sRemoveBlock
  80. {
  81.         short int ndx;
  82.         short int value;
  83.         sRemoveBlock()
  84.         {
  85.                 this->ndx = 0;
  86.                 this->value = 0;
  87.         };
  88.         sRemoveBlock( int pNdx, int pValue )
  89.         {
  90.                 this->ndx = pNdx;
  91.                 this->value = pValue;
  92.         };
  93. };
  94. bool operator == ( const sRemoveBlock &b1, const sRemoveBlock &b2 )
  95. {
  96.         return b1.ndx == b2.ndx;
  97. };
  98. MCArray<sRemoveBlock> toRemoveList;
  99. // ïàäàþùèå áëîêè
  100. MCArray<int> toFallList;
  101. //
  102. bool mouseButtonDisabled;
  103. //
  104. bool freezeBonuses = false;
  105. //
  106. int bonusSomeBlockProgressStep;
  107. int bonusSomeBlockProgressCount;
  108. //
  109. int bonusFreeBlockProgressStep;
  110. int bonusFreeBlockProgressCount;
  111. //
  112. int bonusDiagBlockProgressStep;
  113. int bonusDiagBlockProgressCount;
  114.  
  115.  
  116.  
  117. #define SELECTED_BLOCK_NONE                     -1
  118.  
  119. // áîíóñ âêëþ÷åí
  120. int bonusSomeBlock;
  121. // ñ÷¸ò÷èê áëîêîâ äëÿ áîíóñà
  122. int bonusSomeBlockCount;
  123. // êîëè÷åñòâî áëîêîâ, êîòîðîå íàäî óáðàòü, ÷òîáû ïîëó÷èòü áîíóñ
  124. int bonusSomeBlockEdge;
  125. #define BONUS_SOMEBLOCK_SELECTED        -2
  126. //
  127. bool bonusFreeBlock;
  128. int bonusFreeBlockCount;
  129. int bonusFreeBlockEdge;
  130. #define BONUS_FREEBLOCK_SELECTED        -3
  131. //
  132. int bonusDiagBlock;
  133. int bonusDiagBlockCount;
  134. int bonusDiagBlockEdge;
  135. #define BONUS_DIAGBLOCK_SELECTED        -4
  136. //
  137. void drawScore();
  138. // îòîáðàçèòü áëîêè áîíóñîâ
  139. void drawBonuses();
  140. //
  141. void drawLevelNum();
  142. //
  143. void fadeOutBlocks();
  144. //
  145. void fallDownBlocks();
  146.  
  147.  
  148. void ClearGameMeters()
  149. {
  150.         // èíäèêàòîð ïðîõîæäåíèå óðîâíÿ
  151.         kos_DrawBar(
  152.                 LEVEL_PROGRESS_LEFT,
  153.                 LEVEL_PROGRESS_TOP,
  154.                 LEVEL_PROGRESS_WIDTH,
  155.                 LEVEL_PROGRESS_HEIGHT,
  156.                 0
  157.                 );
  158.         // èíäèêàòîðû áîíóñîâ
  159.         // some
  160.         kos_DrawBar(
  161.                 33+1,
  162.                 118+21,
  163.                 BONUS_PROGRESS_WIDTH,
  164.                 BONUS_PROGRESS_HEIGHT,
  165.                 0
  166.                 );
  167.         // free
  168.         kos_DrawBar(
  169.                 58+1,
  170.                 166+21,
  171.                 BONUS_PROGRESS_WIDTH,
  172.                 BONUS_PROGRESS_HEIGHT,
  173.                 0
  174.                 );
  175.         // diag
  176.         kos_DrawBar(
  177.                 37+1,
  178.                 213+21,
  179.                 BONUS_PROGRESS_WIDTH,
  180.                 BONUS_PROGRESS_HEIGHT,
  181.                 0
  182.                 );
  183. }
  184.  
  185.  
  186. //
  187. void drawGameMeters()
  188. {
  189.         //
  190.         ClearGameMeters();
  191.         // èíäèêàòîð ïðîõîæäåíèå óðîâíÿ
  192.         kos_DrawBar(
  193.                 LEVEL_PROGRESS_LEFT,
  194.                 LEVEL_PROGRESS_TOP,
  195.                 levelProgressCount,
  196.                 LEVEL_PROGRESS_HEIGHT,
  197.                 LEVEL_PROGRESS_COLOUR
  198.                 );
  199.         //
  200.         if ( bonusSomeBlockProgressCount > 0 )
  201.         // some
  202.         kos_DrawBar(
  203.                 33+1,
  204.                 118+21+BONUS_PROGRESS_HEIGHT-bonusSomeBlockProgressCount,
  205.                 BONUS_PROGRESS_WIDTH,
  206.                 bonusSomeBlockProgressCount,
  207.                 LEVEL_PROGRESS_COLOUR
  208.                 );
  209.         //
  210.         if ( bonusFreeBlockProgressCount > 0 )
  211.         // free
  212.         kos_DrawBar(
  213.                 58+1,
  214.                 166+21+BONUS_PROGRESS_HEIGHT-bonusFreeBlockProgressCount,
  215.                 BONUS_PROGRESS_WIDTH,
  216.                 bonusFreeBlockProgressCount,
  217.                 LEVEL_PROGRESS_COLOUR
  218.                 );
  219.         //
  220.         if ( bonusDiagBlockProgressCount > 0 )
  221.         // diag
  222.         kos_DrawBar(
  223.                 37+1,
  224.                 213+21+BONUS_PROGRESS_HEIGHT-bonusDiagBlockProgressCount,
  225.                 BONUS_PROGRESS_WIDTH,
  226.                 bonusDiagBlockProgressCount,
  227.                 LEVEL_PROGRESS_COLOUR
  228.                 );
  229. }
  230.  
  231.  
  232. ////////////////////////////////////////////////////////////////////////////////
  233. void SetLevelVariables()
  234. {
  235.         selectedBlock = -1;
  236.         levelBlocksLimit = ( gameLevel > 5 ) ? LEVEL_SCORE_BASE * ( gameLevel + 1 ) : LEVEL_SCORE_BASE * ( 11 - gameLevel );
  237.         insertedBlocksCount = 0;
  238.         //
  239.         levelProgressCount = 0;
  240.         levelProgressStep = ( LEVEL_PROGRESS_WIDTH * 1024 ) / levelBlocksLimit;
  241.         //
  242.         bonusSomeBlockEdge = levelBlocksLimit / 4;
  243.         bonusFreeBlockEdge = levelBlocksLimit / 3;
  244.         bonusDiagBlockEdge = levelBlocksLimit / 2;
  245.         //
  246.         bonusSomeBlockProgressStep = ( BONUS_PROGRESS_HEIGHT * 1024 ) / bonusSomeBlockEdge;
  247.         bonusSomeBlockProgressCount = ( ( ( bonusSomeBlockCount > bonusSomeBlockEdge ) ? bonusSomeBlockEdge : bonusSomeBlockCount ) * bonusSomeBlockProgressStep ) / 1024;
  248.         //
  249.         bonusFreeBlockProgressStep = ( BONUS_PROGRESS_HEIGHT * 1024 ) / bonusFreeBlockEdge;
  250.         bonusFreeBlockProgressCount = ( ( ( bonusFreeBlockCount > bonusFreeBlockEdge ) ? bonusFreeBlockEdge : bonusFreeBlockCount ) * bonusFreeBlockProgressStep ) / 1024;
  251.         //
  252.         bonusDiagBlockProgressStep = ( BONUS_PROGRESS_HEIGHT * 1024 ) / bonusDiagBlockEdge;
  253.         bonusDiagBlockProgressCount = ( ( ( bonusDiagBlockCount > bonusDiagBlockEdge ) ? bonusDiagBlockEdge : bonusDiagBlockCount ) * bonusDiagBlockProgressStep ) / 1024;
  254. }
  255.  
  256.  
  257. //
  258. int GetScoreByBlocks( int blocksCount )
  259. {
  260.         int limit, update, i, j, acc;
  261.  
  262.         //
  263.         if ( blocksCount < 3 ) return 0;
  264.         //
  265.         limit = 20 * blocksNum * gameLevel;
  266.         //
  267.         update = gameLevel;
  268.         acc = 1;
  269.         //
  270.         j = blocksCount - 3;
  271.         //
  272.         for ( i = 0; i < j; i++ )
  273.         {
  274.                 //
  275.                 acc *= gameLevel + 1;
  276.                 //
  277.                 if ( ( update + acc ) > limit ) return limit;
  278.         }
  279.         //
  280.         return update + acc;
  281. }
  282.  
  283.  
  284.  
  285. //
  286. int insertNewBlocks()
  287. {
  288.         int i, j, k, ndx, result, btn;
  289.  
  290.         //
  291.         toFallList.Clear();
  292.         //
  293.         result = 0;
  294.         //
  295.         btn = gameLevel > 5 ? blockTypesNum : 5 + gameLevel;
  296.         //
  297.         ndx = ( mapSize * mapSize ) - mapSize;
  298.         //
  299.         for ( i = 0; i < mapSize; i++ )
  300.         {
  301.                 for ( j = 0; j < mapSize; j++ )
  302.                 {
  303.                         //
  304.                         k = ndx + i - ( j * mapSize );
  305.                         //
  306.                         if ( gameMap[k] == EMPTY_PLACE )
  307.                         {
  308.                                 //
  309.                                 for ( ; j < (mapSize-1); j++ )
  310.                                 {
  311.                                         //
  312.                                         gameMap[k] = gameMap[k-mapSize];
  313.                                         toFallList.AddExclusive( k );
  314.                                         k -= mapSize;
  315.                                 }
  316.                                 //
  317.                                 gameMap[i] = ( rtlRand() % btn ) + 1;
  318.                                 toFallList.AddExclusive( i );
  319.                                 //
  320.                                 result++;
  321.                                 //
  322.                                 break;
  323.                         }
  324.                 }
  325.         }
  326.         //
  327.         insertedBlocksCount += result;
  328.         //
  329.         return result;
  330. }
  331.  
  332.  
  333. // ïîèñê öåïî÷åê áëîêîâ äëÿ óäàëåíèÿ, óäàëåíèå áëîêîâ
  334. // âîçâðàùàåò ïðèðàùåíèå ñ÷¸òà èãðîêà
  335. int findBlockLines()
  336. {
  337.         int x, y, ndx;
  338.         int removeCount = 0;
  339.  
  340.         // î÷èñòèì ñïèñîê äëÿ çàïèñè ðåçóëüòàòîâ
  341.         toRemoveList.Clear();
  342.         //
  343.         for ( y = 0; y < mapSize; y++ )
  344.         {
  345.                 //
  346.                 for ( x = 0; x < mapSize; x++ )
  347.                 {
  348.                         //
  349.                         ndx = x + ( y * mapSize );
  350.                         //
  351.                         if ( gameMap[ndx] == EMPTY_PLACE ) continue;
  352.                         // ïðîâåðÿåì ãîðèçîíòàëüíóþ öåïî÷êó
  353.                         if ( x < (mapSize - 2) )
  354.                         {
  355.                                 //
  356.                                 if (
  357.                                         ( gameMap[ndx] == gameMap[ndx+1]  &&  gameMap[ndx] == gameMap[ndx+2] )
  358.                                         || ( BONUS_FREE_BLOCK == gameMap[ndx]  &&  gameMap[ndx+1] == gameMap[ndx+2] )
  359.                                         || ( gameMap[ndx] == gameMap[ndx+1]  &&  BONUS_FREE_BLOCK == gameMap[ndx+2] )
  360.                                         || ( gameMap[ndx] == gameMap[ndx+2]  &&  BONUS_FREE_BLOCK == gameMap[ndx+1] )
  361.                                         )
  362.                                 {
  363.                                         // íàøëè öåïî÷êó, çàïîìíèì
  364.                                         toRemoveList.AddExclusive( sRemoveBlock( ndx, gameMap[ndx] ) );
  365.                                         toRemoveList.AddExclusive( sRemoveBlock( ndx+1, gameMap[ndx+1] ) );
  366.                                         toRemoveList.AddExclusive( sRemoveBlock( ndx+2, gameMap[ndx+2] ) );
  367.                                 }
  368.                         }
  369.                         // ïðîâåðÿåì âåðòèêàëüíóþ öåïî÷êó
  370.                         if ( y < (mapSize - 2) )
  371.                         {
  372.                                 //
  373.                                 if (
  374.                                         ( gameMap[ndx] == gameMap[ndx+mapSize]  &&  gameMap[ndx] == gameMap[ndx+mapSize+mapSize] )
  375.                                         || ( BONUS_FREE_BLOCK == gameMap[ndx]  &&  gameMap[ndx+mapSize] == gameMap[ndx+mapSize+mapSize] )
  376.                                         || ( gameMap[ndx] == gameMap[ndx+mapSize]  &&  BONUS_FREE_BLOCK == gameMap[ndx+mapSize+mapSize] )
  377.                                         || ( gameMap[ndx] == gameMap[ndx+mapSize+mapSize]  &&  BONUS_FREE_BLOCK == gameMap[ndx+mapSize] )
  378.                                         )
  379.                                 {
  380.                                         // íàøëè öåïî÷êó, çàïîìíèì
  381.                                         toRemoveList.AddExclusive( sRemoveBlock( ndx, gameMap[ndx] ) );
  382.                                         toRemoveList.AddExclusive( sRemoveBlock( ndx+mapSize, gameMap[ndx+mapSize] ) );
  383.                                         toRemoveList.AddExclusive( sRemoveBlock( ndx+mapSize+mapSize, gameMap[ndx+mapSize+mapSize] ) );
  384.                                 }
  385.                         }
  386.                 }
  387.         }
  388.         //
  389.         return toRemoveList.GetCount();
  390. }
  391.  
  392.  
  393. // ïðîâåðêà íà íåâîçìîæíîñòü ñîáðàòü êàêóþ-íèáóäü ëèíèþ
  394. bool checkGameOut()
  395. {
  396.         int x, y, ndx;
  397.  
  398.         //
  399.         ndx = 0;
  400.         //
  401.         for ( y = 0; y < mapSize; y++ )
  402.         {
  403.                 //
  404.                 for ( x = 0; x < mapSize; x++ )
  405.                 {
  406.                         // ïðîâåðÿåì ãîðèçîíòàëüíûå öåïî÷êè èç äâóõ ñèìâîëîâ
  407.                         if ( x < (mapSize - 1) )
  408.                         {
  409.                                 //
  410.                                 if ( gameMap[ndx] == gameMap[ndx+1] )
  411.                                 {
  412.                                         // íàøëè öåïî÷êó èç äâóõ áëîêîâ
  413.                                         // ïðîâåðêà áîíóñîâ
  414.                                         if ( bonusSomeBlock == gameMap[ndx] ) return false;
  415.                                         if ( bonusFreeBlock ) return false;
  416.                                         // ïðîâåðêà îáû÷íûõ ïåðåñòàíîâîê
  417.                                         if ( y > 0 )
  418.                                         {
  419.                                                 //
  420.                                                 if ( x > 0 )
  421.                                                 {
  422.                                                         //
  423.                                                         if ( gameMap[ndx-mapSize-1] == gameMap[ndx] ) return false;
  424.                                                 }
  425.                                                 //
  426.                                                 if ( x < (mapSize - 2) )
  427.                                                 {
  428.                                                         //
  429.                                                         if ( gameMap[ndx-mapSize+2] == gameMap[ndx] ) return false;
  430.                                                 }
  431.                                         }
  432.                                         //
  433.                                         if ( x > 1 )
  434.                                         {
  435.                                                 //
  436.                                                 if ( gameMap[ndx-2] == gameMap[ndx] ) return false;
  437.                                         }
  438.                                         //
  439.                                         if ( x < (mapSize - 3) )
  440.                                         {
  441.                                                 //
  442.                                                 if ( gameMap[ndx+3] == gameMap[ndx] ) return false;
  443.                                         }
  444.                                         //
  445.                                         if ( y < (mapSize - 1) )
  446.                                         {
  447.                                                 //
  448.                                                 if ( x > 0 )
  449.                                                 {
  450.                                                         //
  451.                                                         if ( gameMap[ndx+mapSize-1] == gameMap[ndx] ) return false;
  452.                                                 }
  453.                                                 //
  454.                                                 if ( x < (mapSize - 2) )
  455.                                                 {
  456.                                                         //
  457.                                                         if ( gameMap[ndx+mapSize+2] == gameMap[ndx] ) return false;
  458.                                                 }
  459.                                         }
  460.                                         // ïðîâåðêà äèàãîíàëüíûõ ïåðåñòàíîâîê
  461.                                         if ( bonusDiagBlock > 0 )
  462.                                         {
  463.                                                 //
  464.                                                 if ( y > 0 )
  465.                                                 {
  466.                                                         //
  467.                                                         if ( x > 1 )
  468.                                                         {
  469.                                                                 //
  470.                                                                 if ( gameMap[ndx-mapSize-2] == gameMap[ndx] ) return false;
  471.                                                         }
  472.                                                         //
  473.                                                         if ( gameMap[ndx-mapSize] == gameMap[ndx] ) return false;
  474.                                                         //
  475.                                                         if ( x < (mapSize - 2) )
  476.                                                         {
  477.                                                                 //
  478.                                                                 if ( gameMap[ndx-mapSize+1] == gameMap[ndx] ) return false;
  479.                                                         }
  480.                                                         //
  481.                                                         if ( x < (mapSize - 3) )
  482.                                                         {
  483.                                                                 //
  484.                                                                 if ( gameMap[ndx-mapSize+3] == gameMap[ndx] ) return false;
  485.                                                         }
  486.                                                 }
  487.                                                 //
  488.                                                 if ( y < (mapSize - 1) )
  489.                                                 {
  490.                                                         //
  491.                                                         if ( x > 1 )
  492.                                                         {
  493.                                                                 //
  494.                                                                 if ( gameMap[ndx+mapSize-2] == gameMap[ndx] ) return false;
  495.                                                         }
  496.                                                         //
  497.                                                         if ( gameMap[ndx+mapSize] == gameMap[ndx] ) return false;
  498.                                                         //
  499.                                                         if ( x < (mapSize - 2) )
  500.                                                         {
  501.                                                                 //
  502.                                                                 if ( gameMap[ndx+mapSize+1] == gameMap[ndx] ) return false;
  503.                                                         }
  504.                                                         //
  505.                                                         if ( x < (mapSize - 3) )
  506.                                                         {
  507.                                                                 //
  508.                                                                 if ( gameMap[ndx+mapSize+3] == gameMap[ndx] ) return false;
  509.                                                         }
  510.                                                 }
  511.                                         } // çàêîí÷åíà ïðîâåðêà äèàãîíàëüíûõ ïåðåñòàíîâîê
  512.                                 }
  513.                         }
  514.                         // ïðîâåðÿåì ãîðèçîíòàëüíûå öåïî÷êè èç äâóõ áëîêîâ ñ ïðîìåæóòêîì
  515.                         if ( x < (mapSize - 2) )
  516.                         {
  517.                                 //
  518.                                 if ( gameMap[ndx] == gameMap[ndx+2] )
  519.                                 {
  520.                                         // íàøëè äâà áëîêà ñ ïðîìåæóòêîì
  521.                                         // ïðîâåðêà áîíóñîâ
  522.                                         if ( bonusSomeBlock == gameMap[ndx] ) return false;
  523.                                         if ( bonusFreeBlock ) return false;
  524.                                         //
  525.                                         if ( y > 0 )
  526.                                         {
  527.                                                 //
  528.                                                 if ( gameMap[ndx-mapSize+1] == gameMap[ndx] ) return false;
  529.                                         }
  530.                                         //
  531.                                         if ( y < (mapSize-1) )
  532.                                         {
  533.                                                 //
  534.                                                 if ( gameMap[ndx+mapSize+1] == gameMap[ndx] ) return false;
  535.                                         }
  536.                                         // ïðîâåðêà äèàãîíàëüíûõ ïåðåñòàíîâîê
  537.                                         if ( bonusDiagBlock > 0 )
  538.                                         {
  539.                                                 //
  540.                                                 if ( y > 0 )
  541.                                                 {
  542.                                                         //
  543.                                                         if ( gameMap[ndx-mapSize] == gameMap[ndx] ) return false;
  544.                                                         //
  545.                                                         if ( gameMap[ndx-mapSize+2] == gameMap[ndx] ) return false;
  546.                                                 }
  547.                                                 //
  548.                                                 if ( y < (mapSize-1) )
  549.                                                 {
  550.                                                         //
  551.                                                         if ( gameMap[ndx+mapSize] == gameMap[ndx] ) return false;
  552.                                                         //
  553.                                                         if ( gameMap[ndx+mapSize+2] == gameMap[ndx] ) return false;
  554.                                                 }
  555.                                         }
  556.                                 }
  557.                         }
  558.                         // ïðîâåðÿåì âåðòèêàëüíûå öåïî÷êè èç äâóõ ñèìâîëîâ
  559.                         if ( y < (mapSize - 1) )
  560.                         {
  561.                                 //
  562.                                 if ( gameMap[ndx] == gameMap[ndx+mapSize] )
  563.                                 {
  564.                                         // íàøëè öåïî÷êó èç äâóõ áëîêîâ
  565.                                         // ïðîâåðêà áîíóñîâ
  566.                                         if ( bonusSomeBlock == gameMap[ndx] ) return false;
  567.                                         if ( bonusFreeBlock ) return false;
  568.                                         //
  569.                                         if ( x > 0 )
  570.                                         {
  571.                                                 //
  572.                                                 if ( y > 0 )
  573.                                                 {
  574.                                                         //
  575.                                                         if ( gameMap[ndx-1-mapSize] == gameMap[ndx] ) return false;
  576.                                                 }
  577.                                                 //
  578.                                                 if ( y < (mapSize - 2) )
  579.                                                 {
  580.                                                         //
  581.                                                         if ( gameMap[ndx-1+(2*mapSize)] == gameMap[ndx] ) return false;
  582.                                                 }
  583.                                         }
  584.                                         //
  585.                                         if ( y > 1 )
  586.                                         {
  587.                                                 //
  588.                                                 if ( gameMap[ndx-(2*mapSize)] == gameMap[ndx] ) return false;
  589.                                         }
  590.                                         //
  591.                                         if ( y < (mapSize - 3) )
  592.                                         {
  593.                                                 //
  594.                                                 if ( gameMap[ndx+(3*mapSize)] == gameMap[ndx] ) return false;
  595.                                         }
  596.                                         //
  597.                                         if ( x < (mapSize - 1) )
  598.                                         {
  599.                                                 //
  600.                                                 if ( y > 0 )
  601.                                                 {
  602.                                                         //
  603.                                                         if ( gameMap[ndx+1-mapSize] == gameMap[ndx] ) return false;
  604.                                                 }
  605.                                                 //
  606.                                                 if ( y < (mapSize - 2) )
  607.                                                 {
  608.                                                         //
  609.                                                         if ( gameMap[ndx+1+(2*mapSize)] == gameMap[ndx] ) return false;
  610.                                                 }
  611.                                         }
  612.                                         // ïðîâåðêà äèàãîíàëüíûõ ïåðåñòàíîâîê
  613.                                         if ( bonusDiagBlock > 0 )
  614.                                         {
  615.                                                 //
  616.                                                 if ( x > 0 )
  617.                                                 {
  618.                                                         //
  619.                                                         if ( y > 1 )
  620.                                                         {
  621.                                                                 //
  622.                                                                 if ( gameMap[ndx-1-(2*mapSize)] == gameMap[ndx] ) return false;
  623.                                                         }
  624.                                                         //
  625.                                                         if ( gameMap[ndx-1] == gameMap[ndx] ) return false;
  626.                                                         //
  627.                                                         if ( y < (mapSize - 2) )
  628.                                                         {
  629.                                                                 //
  630.                                                                 if ( gameMap[ndx-1+mapSize] == gameMap[ndx] ) return false;
  631.                                                         }
  632.                                                         //
  633.                                                         if ( y < (mapSize - 3) )
  634.                                                         {
  635.                                                                 //
  636.                                                                 if ( gameMap[ndx-1+(3*mapSize)] == gameMap[ndx] ) return false;
  637.                                                         }
  638.                                                 }
  639.                                                 //
  640.                                                 if ( x < (mapSize - 1) )
  641.                                                 {
  642.                                                         //
  643.                                                         if ( y > 1 )
  644.                                                         {
  645.                                                                 //
  646.                                                                 if ( gameMap[ndx+1-(2*mapSize)] == gameMap[ndx] ) return false;
  647.                                                         }
  648.                                                         //
  649.                                                         if ( gameMap[ndx+1] == gameMap[ndx] ) return false;
  650.                                                         //
  651.                                                         if ( y < (mapSize - 2) )
  652.                                                         {
  653.                                                                 //
  654.                                                                 if ( gameMap[ndx+1+mapSize] == gameMap[ndx] ) return false;
  655.                                                         }
  656.                                                         //
  657.                                                         if ( y < (mapSize - 3) )
  658.                                                         {
  659.                                                                 //
  660.                                                                 if ( gameMap[ndx+1+(3*mapSize)] == gameMap[ndx] ) return false;
  661.                                                         }
  662.                                                 }
  663.                                         } // çàêîí÷åíà ïðîâåðêà äèàãîíàëüíûõ ïåðåñòàíîâîê
  664.                                 }
  665.                         }
  666.                         // ïðîâåðÿåì âåðòèêàëüíûå öåïî÷êè èç äâóõ áëîêîâ ñ ïðîìåæóòêîì
  667.                         if ( y < (mapSize - 2) )
  668.                         {
  669.                                 //
  670.                                 if ( gameMap[ndx] == gameMap[ndx+(2*mapSize)] )
  671.                                 {
  672.                                         // íàøëè äâà áëîêà ñ ïðîìåæóòêîì
  673.                                         // ïðîâåðêà áîíóñîâ
  674.                                         if ( bonusSomeBlock == gameMap[ndx] ) return false;
  675.                                         if ( bonusFreeBlock ) return false;
  676.                                         //
  677.                                         if ( x > 0 )
  678.                                         {
  679.                                                 //
  680.                                                 if ( gameMap[ndx-1+mapSize] == gameMap[ndx] ) return false;
  681.                                         }
  682.                                         //
  683.                                         if ( x < (mapSize-1) )
  684.                                         {
  685.                                                 //
  686.                                                 if ( gameMap[ndx+1+mapSize] == gameMap[ndx] ) return false;
  687.                                         }
  688.                                         // ïðîâåðêà äèàãîíàëüíûõ ïåðåñòàíîâîê
  689.                                         if ( bonusDiagBlock > 0 )
  690.                                         {
  691.                                                 //
  692.                                                 if ( x > 0 )
  693.                                                 {
  694.                                                         //
  695.                                                         if ( gameMap[ndx-1] == gameMap[ndx] ) return false;
  696.                                                         //
  697.                                                         if ( gameMap[ndx-1+(2*mapSize)] == gameMap[ndx] ) return false;
  698.                                                 }
  699.                                                 //
  700.                                                 if ( x < (mapSize-1) )
  701.                                                 {
  702.                                                         //
  703.                                                         if ( gameMap[ndx+1] == gameMap[ndx] ) return false;
  704.                                                         //
  705.                                                         if ( gameMap[ndx+1+(2*mapSize)] == gameMap[ndx] ) return false;
  706.                                                 }
  707.                                         }
  708.                                 }
  709.                         }
  710.                         //
  711.                         ndx++;
  712.                 }
  713.         }
  714.         //
  715.         gameWndTitle = gameWndTitle2;
  716.         //
  717.         return true;
  718. }
  719.  
  720.  
  721. //
  722. bool exterminateLines()
  723. {
  724.         int deletedBlocks, btn, i, j;
  725.         bool needRedrawBonus = false;
  726.  
  727.         //
  728.         btn = gameLevel > 5 ? blockTypesNum : 5 + gameLevel;
  729.         //
  730.         playerScore += GetScoreByBlocks( deletedBlocks = findBlockLines() );
  731.         //
  732.         if ( ! freezeBonuses )
  733.         {
  734.                 //
  735.                 if ( gameLevel >= 2 && bonusSomeBlock <= 0 ) bonusSomeBlockCount += deletedBlocks;
  736.                 if ( gameLevel >= 3 && !bonusFreeBlock ) bonusFreeBlockCount += deletedBlocks;
  737.                 if ( gameLevel >= 4 && bonusDiagBlock <= 0 ) bonusDiagBlockCount += deletedBlocks;
  738.                 // ïåðâûé áîíóñ
  739.                 if (
  740.                         ( bonusSomeBlockCount >= bonusSomeBlockEdge || ( gameLevel >= 2 && deletedBlocks >= 4 ) )
  741.                         && bonusSomeBlock <= 0
  742.                         )
  743.                 {
  744.                         bonusSomeBlock = ( rtlRand() % btn ) + 1;
  745.                         needRedrawBonus = true;
  746.                         if ( bonusSomeBlockCount >= bonusSomeBlockEdge ) bonusSomeBlockCount = 0;
  747.                 }
  748.                 if ( bonusSomeBlockCount >= bonusSomeBlockEdge ) bonusSomeBlockCount = 0;
  749.                 // âòîðîé áîíóñ
  750.                 if ( bonusFreeBlockCount >= bonusFreeBlockEdge || ( gameLevel >=3 && deletedBlocks >= 5 ) )
  751.                 {
  752.                         bonusFreeBlock = true;
  753.                         needRedrawBonus = true;
  754.                         if ( bonusFreeBlockCount >= bonusFreeBlockEdge ) bonusFreeBlockCount = 0;
  755.                 }
  756.                 if ( bonusFreeBlockCount >= bonusFreeBlockEdge ) bonusFreeBlockCount = 0;
  757.                 // òðåòèé áîíóñ
  758.                 if ( bonusDiagBlockCount >= bonusDiagBlockEdge || ( gameLevel >= 4 && deletedBlocks >= 6 ) )
  759.                 {
  760.                         bonusDiagBlock = 3;
  761.                         needRedrawBonus = true;
  762.                         if ( bonusDiagBlockCount >= bonusDiagBlockEdge ) bonusDiagBlockCount = 0;
  763.                 }
  764.                 if ( bonusDiagBlockCount >= bonusDiagBlockEdge ) bonusDiagBlockCount = 0;
  765.                 //
  766.                 bonusSomeBlockProgressCount = ( ( ( bonusSomeBlockCount > bonusSomeBlockEdge ) ? bonusSomeBlockEdge : bonusSomeBlockCount ) * bonusSomeBlockProgressStep ) / 1024;
  767.                 //
  768.                 bonusFreeBlockProgressCount = ( ( ( bonusFreeBlockCount > bonusFreeBlockEdge ) ? bonusFreeBlockEdge : bonusFreeBlockCount ) * bonusFreeBlockProgressStep ) / 1024;
  769.                 //
  770.                 bonusDiagBlockProgressCount = ( ( ( bonusDiagBlockCount > bonusDiagBlockEdge ) ? bonusDiagBlockEdge : bonusDiagBlockCount ) * bonusDiagBlockProgressStep ) / 1024;
  771.                 //
  772.                 if ( needRedrawBonus ) drawBonuses();
  773.         }
  774.         //
  775.         j = toRemoveList.GetCount();
  776.         //
  777.         for ( i = 0; i < j; i++ )
  778.         {
  779.                 gameMap[toRemoveList[i].ndx] = EMPTY_PLACE;
  780.         }
  781.         //
  782.         return toRemoveList.GetCount() > 0;
  783. }
  784.  
  785.  
  786. // çàïîëíåíèå èãðîâîãî ïîëÿ ñëó÷àéíîé êîìáèíàöèåé áëîêîâ
  787. void initGameMap()
  788. {
  789.         int i, localScore, localInserted, btn;
  790.  
  791.         //
  792.         btn = gameLevel > 5 ? blockTypesNum : 5 + gameLevel;
  793.         //
  794.         for ( i = 0; i < (mapSize * mapSize); i++ )
  795.         {
  796.                 gameMap[i] = ( rtlRand() % btn ) + 1;
  797.         }
  798.         //
  799.         localScore = playerScore;
  800.         localInserted = insertedBlocksCount;
  801.         //
  802.         freezeBonuses = true;
  803.         //
  804.         while ( exterminateLines() )
  805.         {
  806.                 while ( insertNewBlocks() > 0 );
  807.         }
  808.         //
  809.         freezeBonuses = false;
  810.         //
  811.         playerScore = localScore;
  812.         insertedBlocksCount = localInserted;
  813. }
  814.  
  815.  
  816. // îòîáðàçèòü áëîêè áîíóñîâ
  817. void drawBonuses()
  818. {
  819.         //
  820.         kos_PutImage(
  821.                 selectedBlock != BONUS_SOMEBLOCK_SELECTED ?
  822.                         fishki[bonusSomeBlock]->GetBits() :
  823.                         fishki[bonusSomeBlock]->GetHighlightedBits(),
  824.                 blockSize, blockSize,
  825.                 BONUS_SOMEBLOCK_LEFT, BONUS_SOMEBLOCK_TOP
  826.                 );
  827.         //
  828.         kos_PutImage(
  829.                 bonusFreeBlock ?
  830.                 (
  831.                         selectedBlock != BONUS_FREEBLOCK_SELECTED ?
  832.                         fishki[BONUS_FREE_BLOCK]->GetBits() :
  833.                         fishki[BONUS_FREE_BLOCK]->GetHighlightedBits()
  834.                 ) :
  835.                 fishki[0]->GetBits(),
  836.                 blockSize, blockSize,
  837.                 BONUS_FREEBLOCK_LEFT, BONUS_FREEBLOCK_TOP
  838.                 );
  839.         //
  840.         kos_PutImage(
  841.                 bonusDiagBlock > 0 ?
  842.                         fishki[bonusDiagBlock+BONUS_DIAG_BLOCK-1]->GetBits() :
  843.                         fishki[0]->GetBits(),
  844.                 blockSize, blockSize,
  845.                 BONUS_DIAGBLOCK_LEFT, BONUS_DIAGBLOCK_TOP
  846.                 );
  847. }
  848.  
  849.  
  850. // îòîáðàçèòü èãðîâîå ïîëå
  851. void drawGameMap()
  852. {
  853.         int i, j, ndx;
  854.  
  855.         //
  856.         for ( i = 0; i < mapSize; i++ )
  857.         {
  858.                 //
  859.                 for ( j = 0; j < mapSize; j++ )
  860.                 {
  861.                         //
  862.                         ndx = (i*mapSize) + j;
  863.                         //
  864.                         kos_PutImage(
  865.                                 ndx != selectedBlock ?
  866.                                         fishki[gameMap[ndx]]->GetBits() :
  867.                                         fishki[gameMap[ndx]]->GetHighlightedBits(),
  868.                                 blockSize, blockSize,
  869.                                 (j * blockSize) + blocksLeft,
  870.                                 (i * blockSize) + blocksTop
  871.                                 );
  872.                 }
  873.         }
  874. }
  875.  
  876.  
  877. // êîîðäèíàòû êóðñîðà "ìûøè"
  878. int mX, mY;
  879.  
  880. // ïðîâåðêà íà íàæàòèå ëåâîé êíîïêè "ìûøè"
  881. bool mouseLButtonDown()
  882. {
  883.         static bool isDown = false;
  884.         Dword buttons;
  885.  
  886.         //
  887.         kos_GetMouseState( buttons, mX, mY );
  888.         //
  889.         if ( mouseButtonDisabled ) return false;
  890.         //
  891.         if ( ( buttons & 1 ) )
  892.         {
  893.                 if ( isDown )
  894.                         return false;
  895.                 else
  896.                 {
  897.                         isDown = true;
  898.                         return true;
  899.                 }
  900.         }
  901.         else
  902.         {
  903.                 if ( isDown )
  904.                 {
  905.                         isDown = false;
  906.                 }
  907.                 return false;
  908.         }
  909. }
  910.  
  911. //
  912. void flipTwoBlocks( int ndx1, int ndx2 )
  913. {
  914.         Word blX, blY, selX, selY;
  915.         Byte fishCode;
  916.  
  917.         //
  918.         blX = ( ndx1 % mapSize ) * blockSize + blocksLeft;
  919.         blY = ( ndx1 / mapSize ) * blockSize + blocksTop;
  920.         selX = ( ndx2 % mapSize ) * blockSize + blocksLeft;
  921.         selY = ( ndx2 / mapSize ) * blockSize + blocksTop;
  922.         // ïåðåñòàâèì áëîêè ìåñòàìè
  923.         fishCode = gameMap[ndx1];
  924.         gameMap[ndx1] = gameMap[ndx2];
  925.         gameMap[ndx2] = fishCode;
  926.         // èçîáðàæåíèå áëîêà
  927.         kos_PutImage(
  928.                 fishki[gameMap[ndx1]]->GetBits(),
  929.                 blockSize, blockSize,
  930.                 blX,
  931.                 blY
  932.                 );
  933.         // èçîáðàæåíèå áëîêà
  934.         kos_PutImage(
  935.                 fishki[gameMap[ndx2]]->GetBits(),
  936.                 blockSize, blockSize,
  937.                 selX,
  938.                 selY
  939.                 );
  940. }
  941.  
  942.  
  943. // èãðîâîé ïðîöåññ
  944. int GameLoop()
  945. {
  946.         int result, ndx, blX, blY, selX, selY, ddX, ddY, nSel;
  947.         Byte keyCode, mCode;
  948.         bool needDecBonus;
  949.         Dword buttonID;
  950.  
  951.         //
  952.         gameWndTitle = gameWndTitle1;
  953.         gameFace.GetSize( gcx, gcy );
  954.         gameLevel = startGameLevel;
  955.         playerScore = 0;
  956.         bonusSomeBlock = 0;
  957.         bonusFreeBlock = false;
  958.         bonusDiagBlock = 0;
  959.         bonusSomeBlockCount = 0;
  960.         bonusFreeBlockCount = 0;
  961.         bonusDiagBlockCount = 0;
  962.         bonusSomeBlockProgressCount = 0;
  963.         bonusFreeBlockProgressCount = 0;
  964.         bonusDiagBlockProgressCount = 0;
  965.         SetLevelVariables();
  966.         mouseButtonDisabled = false;
  967.         initGameMap();
  968.         //
  969.         kos_ChangeWindow( -1, -1, gcx + 1, gcy + 21 );
  970.         //
  971.         for ( result = GM_NONE; result == GM_NONE; )
  972.         {
  973.                 switch( kos_WaitForEvent() )
  974.                 {
  975.                 // íàäî ïîëíîñòüþ ïåðåðèñîâàòü îêíî
  976.                 case 1:
  977.                         DrawGameWindow();
  978.                         break;
  979.  
  980.                 // êëàâèàòóðà
  981.                 case 2:
  982.                         if ( kos_GetKey( keyCode ) )
  983.                         {
  984.                                 //
  985.                                 switch ( keyCode )
  986.                                 {
  987.                                 case 0x1B:
  988.                                         result = GM_ABORT;
  989.                                         break;
  990.  
  991.                                 default:
  992.                                         break;
  993.                                 }
  994.                         }
  995.                         break;
  996.  
  997.                 // êíîïêè
  998.                 case 3:
  999.                         if ( kos_GetButtonID( buttonID ) )
  1000.                         {
  1001.                                 switch ( buttonID )
  1002.                                 {
  1003.                                 case 1:
  1004.                                         kos_ExitApp();
  1005.  
  1006.                                 case 0xA:
  1007.                                         result = GM_ABORT;
  1008.                                         break;
  1009.  
  1010.                                 default:
  1011.                                         break;
  1012.                                 }
  1013.                         }
  1014.  
  1015.                 // ñîáûòèå îò ìûøè
  1016.                 case 6:
  1017.                         // íàæàòèå ëåâîé êíîïêè?
  1018.                         if ( mouseLButtonDown() )
  1019.                         {
  1020.                                 // ñ÷èòàåì êîîðäèíàòû îòíîñèòåëíî èãðîâîãî ïîëÿ
  1021.                                 blX = mX - blocksLeft;
  1022.                                 blY = mY - blocksTop;
  1023.                                 // ïîïàëî â èãðîâîå ïîëå?
  1024.                                 if ( blX >= 0 && blX < (mapSize * blockSize)
  1025.                                         && blY >= 0 && blY < (mapSize * blockSize) )
  1026.                                 {
  1027.                                         // ïîëó÷àåì êîîðäèíàòû â áëîêàõ
  1028.                                         blX /= blockSize;
  1029.                                         blY /= blockSize;
  1030.                                         // ïîëó÷àåì íîìåð áëîêà íà êàðòå
  1031.                                         ndx = blX + ( blY * mapSize );
  1032.                                         // åù¸ îäíà ïðîâåðêà, ÷òîáû íå âûëåçòè çà ïðåäåëû êàðòû
  1033.                                         if ( ndx >= 0 && ndx < (mapSize * mapSize) )
  1034.                                         {
  1035.                                                 // íà÷èíàåì ïåðåðèñîâêó
  1036.                                                 kos_WindowRedrawStatus( WRS_BEGIN );
  1037.                                                 // åñëè íå áûëî âûáðàííîãî áëîêà
  1038.                                                 if ( selectedBlock == SELECTED_BLOCK_NONE )
  1039.                                                 {
  1040.                                                         // çàïîìíèì âûäåëåííûé áëîê
  1041.                                                         selectedBlock = ndx;
  1042.                                                         // îòìåòèì áëîê íà èãðîâîì ïîëå
  1043.                                                         kos_PutImage(
  1044.                                                                 fishki[gameMap[selectedBlock]]->GetHighlightedBits(),
  1045.                                                                 blockSize, blockSize,
  1046.                                                                 ( selectedBlock % mapSize ) * blockSize + blocksLeft,
  1047.                                                                 ( selectedBlock / mapSize ) * blockSize + blocksTop
  1048.                                                                 );
  1049.                                                 }
  1050.                                                 else // ïîìå÷åííûé áëîê óæå åñòü
  1051.                                                 {
  1052.                                                         if ( selectedBlock >= 0 )
  1053.                                                         {
  1054.                                                                 // êîîðäèíàòû ïîìå÷åííîãî áëîêà
  1055.                                                                 selX = selectedBlock % mapSize;
  1056.                                                                 selY = selectedBlock / mapSize;
  1057.                                                                 // áûë âûáðàí äðóãîé áëîê?
  1058.                                                                 if ( ndx != selectedBlock )
  1059.                                                                 {
  1060.                                                                         // ñ÷èòàåì ðàçíîñòü êîîðäèíàò äâóõ áëîêîâ
  1061.                                                                         ddX = selX - blX;
  1062.                                                                         ddY = selY - blY;
  1063.                                                                         needDecBonus = ( bonusDiagBlock > 0 && abs(ddX) == 1 && abs(ddY) == 1 );
  1064.                                                                         // åñëè ýòî ñîñåäíèé áëîê
  1065.                                                                         if (
  1066.                                                                                 ( abs(ddX) == 1 && ddY == 0 )
  1067.                                                                                 || ( abs(ddY) == 1 && ddX == 0 )
  1068.                                                                                 || needDecBonus
  1069.                                                                                 )
  1070.                                                                         {
  1071.                                                                                 // ïåðåñòàâèì áëîêè ìåñòàìè
  1072.                                                                                 flipTwoBlocks( ndx, selectedBlock );
  1073.                                                                                 //
  1074.                                                                                 kos_Pause( 16 );
  1075.                                                                                 //
  1076.                                                                                 if ( findBlockLines() > 0 )
  1077.                                                                                 {
  1078.                                                                                         //
  1079.                                                                                         if ( needDecBonus )
  1080.                                                                                         {
  1081.                                                                                                 //
  1082.                                                                                                 --bonusDiagBlock;
  1083.                                                                                                 //
  1084.                                                                                                 drawBonuses();
  1085.                                                                                         }
  1086.                                                                                         // ñíèìàåì ïîìåòêó ñ áëîêà
  1087.                                                                                         selectedBlock = SELECTED_BLOCK_NONE;
  1088.                                                                                         //
  1089.                                                                                         while ( exterminateLines() )
  1090.                                                                                         {
  1091.                                                                                                 //
  1092.                                                                                                 fadeOutBlocks();
  1093.                                                                                                 //
  1094.                                                                                                 //drawGameMap();
  1095.                                                                                                 //drawScore();
  1096.                                                                                                 //
  1097.                                                                                                 //kos_Pause( 25 );
  1098.                                                                                                 //
  1099.                                                                                                 while ( insertNewBlocks() > 0 )
  1100.                                                                                                 {
  1101.                                                                                                         //
  1102.                                                                                                         fallDownBlocks();
  1103.                                                                                                         //
  1104.                                                                                                         //drawGameMap();
  1105.                                                                                                         //kos_Pause( 30 );
  1106.                                                                                                 }
  1107.                                                                                         }
  1108.                                                                                         //
  1109.                                                                                         drawScore();
  1110.                                                                                         //
  1111.                                                                                         levelProgressCount = ( ( ( insertedBlocksCount > levelBlocksLimit ) ? levelBlocksLimit : insertedBlocksCount ) * levelProgressStep ) / 1024;
  1112.                                                                                         //
  1113.                                                                                         drawGameMeters();
  1114.                                                                                         //
  1115.                                                                                         if ( insertedBlocksCount > levelBlocksLimit )
  1116.                                                                                         {
  1117.                                                                                                 kos_Pause( 50 );
  1118.                                                                                                 gameLevel++;
  1119.                                                                                                 SetLevelVariables();
  1120.                                                                                                 //
  1121.                                                                                                 //initGameMap();
  1122.                                                                                                 //
  1123.                                                                                                 //DrawGameWindow();
  1124.                                                                                                 //
  1125.                                                                                                 drawGameMeters();
  1126.                                                                                                 drawLevelNum();
  1127.                                                                                         }
  1128.                                                                                         else
  1129.                                                                                                 //
  1130.                                                                                                 if ( mouseButtonDisabled = checkGameOut() )
  1131.                                                                                                 {
  1132.                                                                                                         //
  1133.                                                                                                         DrawGameWindow();
  1134.                                                                                                 }
  1135.                                                                                 }
  1136.                                                                                 else
  1137.                                                                                 {
  1138.                                                                                         // íå ïîëó÷àåòñÿ ëèíèè, áëîêè ñòàâèì íà ìåñòî
  1139.                                                                                         flipTwoBlocks( ndx, selectedBlock );
  1140.                                                                                         // ñíèìàåì ïîìåòêó ñ áëîêà
  1141.                                                                                         selectedBlock = SELECTED_BLOCK_NONE;
  1142.                                                                                 }
  1143.                                                                         }
  1144.                                                                         else // âûáðàí íåñîñåäíèé áëîê
  1145.                                                                         {
  1146.                                                                                 // ïåðåñòèì ìàðêåð
  1147.                                                                                 kos_PutImage(
  1148.                                                                                         fishki[gameMap[selectedBlock]]->GetBits(),
  1149.                                                                                         blockSize, blockSize,
  1150.                                                                                         selX * blockSize + blocksLeft,
  1151.                                                                                         selY * blockSize + blocksTop
  1152.                                                                                         );
  1153.                                                                                 // ïîìåòèì âûáðàííûé áëîê
  1154.                                                                                 selectedBlock = ndx;
  1155.                                                                                 // íà èãðîâîì ïîëå
  1156.                                                                                 kos_PutImage(
  1157.                                                                                         fishki[gameMap[selectedBlock]]->GetHighlightedBits(),
  1158.                                                                                         blockSize, blockSize,
  1159.                                                                                         blX * blockSize + blocksLeft,
  1160.                                                                                         blY * blockSize + blocksTop
  1161.                                                                                         );
  1162.                                                                         }
  1163.                                                                 }
  1164.                                                                 else // âûáðàí òîò æå áëîê
  1165.                                                                 {
  1166.                                                                         // ñíèìàåì ïîìåòêó
  1167.                                                                         kos_PutImage(
  1168.                                                                                 fishki[gameMap[selectedBlock]]->GetBits(),
  1169.                                                                                 blockSize, blockSize,
  1170.                                                                                 selX * blockSize + blocksLeft,
  1171.                                                                                 selY * blockSize + blocksTop
  1172.                                                                                 );
  1173.                                                                         //
  1174.                                                                         selectedBlock = SELECTED_BLOCK_NONE;
  1175.                                                                 }
  1176.                                                         }
  1177.                                                         else
  1178.                                                         // òêíóëè â áëîê ïðè âûáðàííîì áîíóñå
  1179.                                                         {
  1180.                                                                 //
  1181.                                                                 mCode = gameMap[ndx];
  1182.                                                                 //
  1183.                                                                 switch ( selectedBlock )
  1184.                                                                 {
  1185.                                                                 case BONUS_SOMEBLOCK_SELECTED:
  1186.                                                                         gameMap[ndx] = bonusSomeBlock;
  1187.                                                                         break;
  1188.  
  1189.                                                                 case BONUS_FREEBLOCK_SELECTED:
  1190.                                                                         gameMap[ndx] = BONUS_FREE_BLOCK;
  1191.                                                                         break;
  1192.  
  1193.                                                                 default:
  1194.                                                                         break;
  1195.                                                                 }
  1196.                                                                 //
  1197.                                                                 if ( findBlockLines() > 0 )
  1198.                                                                 {
  1199.                                                                         // óáèðàåì èñïîëüçîâàííûé áîíóñ
  1200.                                                                         switch ( selectedBlock )
  1201.                                                                         {
  1202.                                                                         case BONUS_SOMEBLOCK_SELECTED:
  1203.                                                                                 bonusSomeBlock = 0;
  1204.                                                                                 break;
  1205.  
  1206.                                                                         case BONUS_FREEBLOCK_SELECTED:
  1207.                                                                                 bonusFreeBlock = false;
  1208.                                                                                 break;
  1209.  
  1210.                                                                         default:
  1211.                                                                                 break;
  1212.                                                                         }
  1213.                                                                         // íà ýêðàíå òîæå
  1214.                                                                         drawBonuses();
  1215.                                                                         drawGameMap();
  1216.                                                                         kos_Pause( 16 );
  1217.                                                                         // óáèðàåì áëîêè
  1218.                                                                         // ñíèìàåì ïîìåòêó ñ áëîêà
  1219.                                                                         selectedBlock = SELECTED_BLOCK_NONE;
  1220.                                                                         //
  1221.                                                                         while ( exterminateLines() )
  1222.                                                                         {
  1223.                                                                                 //
  1224.                                                                                 fadeOutBlocks();
  1225.                                                                                 //
  1226.                                                                                 //drawGameMap();
  1227.                                                                                 //drawScore();
  1228.                                                                                 //
  1229.                                                                                 //kos_Pause( 25 );
  1230.                                                                                 //
  1231.                                                                                 while ( insertNewBlocks() > 0 )
  1232.                                                                                 {
  1233.                                                                                         //
  1234.                                                                                         fallDownBlocks();
  1235.                                                                                         //
  1236.                                                                                         //drawGameMap();
  1237.                                                                                         //kos_Pause( 30 );
  1238.                                                                                 }
  1239.                                                                         }
  1240.                                                                         //
  1241.                                                                         drawScore();
  1242.                                                                         //
  1243.                                                                         levelProgressCount = ( ( ( insertedBlocksCount > levelBlocksLimit ) ? levelBlocksLimit : insertedBlocksCount ) * levelProgressStep ) / 1024;
  1244.                                                                         //
  1245.                                                                         drawGameMeters();
  1246.                                                                         //
  1247.                                                                         if ( insertedBlocksCount > levelBlocksLimit )
  1248.                                                                         {
  1249.                                                                                 kos_Pause( 50 );
  1250.                                                                                 gameLevel++;
  1251.                                                                                 SetLevelVariables();
  1252.                                                                                 //
  1253.                                                                                 //initGameMap();
  1254.                                                                                 //
  1255.                                                                                 //DrawGameWindow();
  1256.                                                                                 //
  1257.                                                                                 drawGameMeters();
  1258.                                                                                 drawLevelNum();
  1259.                                                                         }
  1260.                                                                         else
  1261.                                                                                 //
  1262.                                                                                 mouseButtonDisabled = checkGameOut();
  1263.                                                                 }
  1264.                                                                 else
  1265.                                                                 // áîíóñ çäåñü íåïðèìåíèì
  1266.                                                                 {
  1267.                                                                         // âåðí¸ì âçàä
  1268.                                                                         gameMap[ndx] = mCode;
  1269.                                                                         // ïîìåòèì áëîê
  1270.                                                                         selectedBlock = ndx;
  1271.                                                                         // íà èãðîâîì ïîëå
  1272.                                                                         kos_PutImage(
  1273.                                                                                 fishki[gameMap[selectedBlock]]->GetHighlightedBits(),
  1274.                                                                                 blockSize, blockSize,
  1275.                                                                                 blX * blockSize + blocksLeft,
  1276.                                                                                 blY * blockSize + blocksTop
  1277.                                                                                 );
  1278.                                                                         // óáåð¸ì ïîìåòêó ñ áîíóñà
  1279.                                                                         drawBonuses();
  1280.                                                                 }
  1281.                                                         }
  1282.                                                 }
  1283.                                                 // îïðåäåëèì êíîïêó
  1284.                                                 kos_DefineButton(
  1285.                                                         444+1, 2+21,
  1286.                                                         54, 20,
  1287.                                                         0x6000000A,
  1288.                                                         0
  1289.                                                         );
  1290.                                                 // çàâåðøàåì ïåðåðèñîâêó
  1291.                                                 kos_WindowRedrawStatus( WRS_END );
  1292.                                         }
  1293.                                 }
  1294.                                 else
  1295.                                 // ïðîâåðèì ïîïàäàíèå â áîíóñû
  1296.                                 {
  1297.                                         nSel = 0;
  1298.                                         //
  1299.                                         if ( mX >= BONUS_SOMEBLOCK_LEFT && (mX - BONUS_SOMEBLOCK_LEFT) <= blockSize
  1300.                                                 && mY >= BONUS_SOMEBLOCK_TOP && (mY - BONUS_SOMEBLOCK_TOP ) <= blockSize )
  1301.                                         {
  1302.                                                 //
  1303.                                                 nSel = BONUS_SOMEBLOCK_SELECTED;
  1304.                                         }
  1305.                                         //
  1306.                                         if ( mX >= BONUS_FREEBLOCK_LEFT && (mX - BONUS_FREEBLOCK_LEFT) <= blockSize
  1307.                                                 && mY >= BONUS_FREEBLOCK_TOP && (mY - BONUS_FREEBLOCK_TOP ) <= blockSize )
  1308.                                         {
  1309.                                                 //
  1310.                                                 nSel = BONUS_FREEBLOCK_SELECTED;
  1311.                                         }
  1312.                                         //
  1313.                                         if ( mX >= BONUS_DIAGBLOCK_LEFT && (mX - BONUS_DIAGBLOCK_LEFT) <= blockSize
  1314.                                                 && mY >= BONUS_DIAGBLOCK_TOP && (mY - BONUS_DIAGBLOCK_TOP ) <= blockSize )
  1315.                                         {
  1316.                                                 //
  1317.                                                 nSel = BONUS_DIAGBLOCK_SELECTED;
  1318.                                         }
  1319.                                         //
  1320.                                         if ( nSel != 0 )
  1321.                                         {
  1322.                                                 //
  1323.                                                 if ( selectedBlock > 0 )
  1324.                                                 {
  1325.                                                         // ñíèìàåì ïîìåòêó
  1326.                                                         kos_PutImage(
  1327.                                                                 fishki[gameMap[selectedBlock]]->GetBits(),
  1328.                                                                 blockSize, blockSize,
  1329.                                                                 (selectedBlock % mapSize) * blockSize + blocksLeft,
  1330.                                                                 (selectedBlock / mapSize) * blockSize + blocksTop
  1331.                                                                 );
  1332.                                                 }
  1333.                                                 //
  1334.                                                 if ( selectedBlock != nSel )
  1335.                                                         selectedBlock = nSel;
  1336.                                                 else
  1337.                                                         selectedBlock = SELECTED_BLOCK_NONE;
  1338.                                                 //
  1339.                                                 drawBonuses();
  1340.                                         }
  1341.                                 }
  1342.  
  1343.                         }
  1344.                         //
  1345.                         break;
  1346.  
  1347.                 default:
  1348.                         break;
  1349.                 }
  1350.         }
  1351.         // îòìåíèì êíîïêó
  1352.         kos_DefineButton(
  1353.                 0, 0,
  1354.                 0, 0,
  1355.                 0x8000000A,
  1356.                 0
  1357.                 );
  1358.         //
  1359.         if ( gameLevel > maxGameLevel ) maxGameLevel = gameLevel;
  1360.         //
  1361.         return result;
  1362. }
  1363.  
  1364. //
  1365. void drawLevelNum()
  1366. {
  1367.         Word startX;
  1368.  
  1369.         //
  1370.         if ( gameLevel > 9 )
  1371.         {
  1372.                 //
  1373.                 startX = LEVEL_LEFT;
  1374.                 //
  1375.                 kos_PutImage(
  1376.                         gameNumbers.GetBits() + ( ( gameLevel / 10 ) * NUM_WIDTH * NUM_HEIGHT ),
  1377.                         NUM_WIDTH, NUM_HEIGHT,
  1378.                         startX, LEVEL_TOP
  1379.                         );
  1380.                 //
  1381.                 startX += NUM_WIDTH;
  1382.         }
  1383.         else
  1384.         {
  1385.                 //
  1386.                 startX = LEVEL_LEFT + ( (LEVEL_WIDTH - NUM_WIDTH) / 2 );
  1387.         }
  1388.         //
  1389.         kos_PutImage(
  1390.                 gameNumbers.GetBits() + ( ( gameLevel % 10 ) * NUM_WIDTH * NUM_HEIGHT ),
  1391.                 NUM_WIDTH, NUM_HEIGHT,
  1392.                 startX, LEVEL_TOP
  1393.                 );
  1394. }
  1395.  
  1396. //
  1397. void drawScore()
  1398. {
  1399.         Word startX;
  1400.         int i, j;
  1401.         char strNum[8];
  1402.  
  1403.         // ÷èñëî â òåêñòîâîì âèäå
  1404.         sprintf( strNum, "%U", playerScore );
  1405.         //
  1406.         j = strlen( strNum );
  1407.         //
  1408.         startX = SCORE_LEFT + ( ( SCORE_WIDTH - ( NUM_WIDTH * j ) ) / 2 );
  1409.         //
  1410.         for ( i = 0; i < j; i++ )
  1411.         {
  1412.                 //
  1413.                 kos_PutImage(
  1414.                         gameNumbers.GetBits() + ( ( strNum[i] - '0' ) * NUM_WIDTH * NUM_HEIGHT ),
  1415.                         NUM_WIDTH, NUM_HEIGHT,
  1416.                         startX, SCORE_TOP
  1417.                         );
  1418.                 //
  1419.                 startX += NUM_WIDTH;
  1420.         }
  1421. }
  1422.  
  1423.  
  1424. //
  1425. void DrawGameWindow()
  1426. {
  1427.         //
  1428.         kos_WindowRedrawStatus( WRS_BEGIN );
  1429.         // îêíî
  1430.         kos_DefineAndDrawWindow(
  1431.                 WNDLEFT, WNDTOP,
  1432.                 gcx + 1, gcy + 21,
  1433.                 0x54, 0x0,                              // Skinned fixed size window, dont fill working area, window has caption
  1434.                 0, WNDHEADCOLOUR,
  1435.                 gameWndTitle
  1436.                 );
  1437.         // çàãîëîâîê îêíà
  1438.           kos_ChangeWindowCaption(gameWndTitle);
  1439.         gameFace.Draw( 1, 21 );
  1440.         drawGameMap();
  1441.         drawGameMeters();
  1442.         drawBonuses();
  1443.         // íîìåð óðîâíÿ
  1444.         drawLevelNum();
  1445.         drawScore();
  1446.         //
  1447.         if ( mouseButtonDisabled )
  1448.         {
  1449.                 //
  1450.                 kos_DrawBar(
  1451.                         ( gcx + 1 - 160 ) / 2, ( gcy + 21 - 32 ) / 2,
  1452.                         160, 32,
  1453.                         0x2383B3
  1454.                         );
  1455.                 //
  1456.                 kos_WriteTextToWindow(
  1457.                         ( gcx + 1 - sizeof( gameOverText ) * 6 ) / 2, ( gcy + 21 - 9 ) / 2,
  1458.                         0x0, 0xF7F7F7,
  1459.                         gameOverText,
  1460.                         sizeof( gameOverText )
  1461.                         );
  1462.         }
  1463.         // îïðåäåëèì êíîïêó
  1464.         kos_DefineButton(
  1465.                 444+1, 2+21,
  1466.                 54, 20,
  1467.                 0x6000000A,
  1468.                 0
  1469.                 );
  1470.         //
  1471.         kos_WindowRedrawStatus( WRS_END );
  1472. }
  1473.  
  1474.  
  1475. //
  1476. void fadeOutBlocks()
  1477. {
  1478.         int i, j, k, ndx, x, y;
  1479.  
  1480.         //
  1481.         j = toRemoveList.GetCount();
  1482.         //
  1483.         for ( k = 0; k < 4; k++ )
  1484.         {
  1485.                 //
  1486.                 __asm{
  1487.                                 push    eax
  1488.                                 push    ebx
  1489.                                 mov             eax, 18
  1490.                                 mov             ebx, 14
  1491.                                 int             0x40
  1492.                                 pop             eax
  1493.                                 pop             ebx
  1494.                 }
  1495.                 //
  1496.                 for ( i = 0; i < j; i++ )
  1497.                 {
  1498.                         //
  1499.                         ndx = toRemoveList[i].ndx;
  1500.                         y = ndx / mapSize;
  1501.                         x = ndx % mapSize;
  1502.                         //
  1503.                         kos_PutImage(
  1504.                                 gameBlocksZ[k].GetBits() + ( (toRemoveList[i].value - 1) * blockSize * blockSize ),
  1505.                                 blockSize, blockSize,
  1506.                                 (x * blockSize) + blocksLeft,
  1507.                                 (y * blockSize) + blocksTop
  1508.                                 );
  1509.                 }
  1510.                 //
  1511.                 kos_Pause( 3 );
  1512.         }
  1513.         //clear
  1514.         for ( i = 0; i < j; i++ )
  1515.         {
  1516.                 //
  1517.                 ndx = toRemoveList[i].ndx;
  1518.                 y = ndx / mapSize;
  1519.                 x = ndx % mapSize;
  1520.                 //
  1521.                 kos_DrawBar(
  1522.                         (x * blockSize) + blocksLeft,
  1523.                         (y * blockSize) + blocksTop,
  1524.                         blockSize, blockSize, 0
  1525.                         );
  1526.         }
  1527.         //
  1528.         kos_Pause( 16 );
  1529. }
  1530.  
  1531.  
  1532. //
  1533. void fallDownBlocks()
  1534. {
  1535.         int i, j, k, ndx, x, y, height, offset;
  1536.  
  1537.         //
  1538.         j = toFallList.GetCount();
  1539.         //
  1540.         for ( k = 1; k <= blockSize; k += 2 )
  1541.         {
  1542.                 //
  1543.                 __asm{
  1544.                                 push    eax
  1545.                                 push    ebx
  1546.                                 mov             eax, 18
  1547.                                 mov             ebx, 14
  1548.                                 int             0x40
  1549.                                 pop             eax
  1550.                                 pop             ebx
  1551.                 }
  1552.                 //
  1553.                 for ( i = 0; i < j; i++ )
  1554.                 {
  1555.                         //
  1556.                         ndx = toFallList[i];
  1557.                         //
  1558.                         y = ( ( ( ndx / mapSize ) - 1 ) * blockSize ) + k;
  1559.                         if ( y < 0 )
  1560.                         {
  1561.                                 y = 0;
  1562.                                 height = k;
  1563.                                 offset = blockSize - k;
  1564.                         }
  1565.                         else
  1566.                         {
  1567.                                 offset = 0;
  1568.                                 height = blockSize;
  1569.                         }
  1570.                         //
  1571.                         x = ( ndx % mapSize ) * blockSize;
  1572.                         //
  1573.                         kos_PutImage(
  1574.                                 fishki[gameMap[ndx]]->GetBits() + ( offset * blockSize ),
  1575.                                 blockSize, height,
  1576.                                 x + blocksLeft,
  1577.                                 y + blocksTop
  1578.                                 );
  1579.                 }
  1580.                 //
  1581.                 kos_Pause( 1 );
  1582.         }
  1583. }
  1584.