1. #include "primlib.h"
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include "stack.h"
  5.  
  6. #define POLES 3
  7. #define BLOCKS 5
  8. #define BLOCK_WIDTH 40
  9. #define BLOCK_HEIGHT 20
  10. #define MOVE_SPEED 4
  11.  
  12. void drawStructure(int *Poles);
  13. void drawBlock(int x1, int y1, int x2, int y2);
  14. void moveBlock(int *Blocks[], int BlockNumber, int BlockToMove, int *Poles, int FinishY);
  15. void drawRemaining(int *Blocks[], int *Poles, int BlockToSkip);
  16. void clearScreen();
  17. void clearBlock(int x1, int y1, int x2, int y2);
  18.  
  19. int main(int argc, char* argv[])
  20. {
  21. stackT Pole1;
  22. stackT Pole2;
  23. stackT Pole3;
  24. int centerX;
  25. int centerY;
  26. int maxX;
  27. int maxY;
  28. int poles[POLES];
  29. int i;
  30. int firstKey;
  31. int secondKey;
  32. int buffer;
  33. int elems;
  34. int **blocks = malloc(BLOCKS * sizeof(int *));
  35. for(i = 0; i < BLOCKS; i++)
  36. blocks[i] = malloc(2 * sizeof(int));
  37.  
  38. StackInit(&Pole1, BLOCKS);
  39. StackInit(&Pole2, BLOCKS);
  40. StackInit(&Pole3, BLOCKS);
  41.  
  42. if(initGraph())
  43. exit(3);
  44. centerX = screenWidth()/2;
  45. centerY = screenHeight()/2;
  46. maxX = screenWidth();
  47. maxY = screenHeight();
  48. drawStructure(poles);
  49. for(i = BLOCKS; i > 0; i--)
  50. {
  51. StackPush(&Pole1, i);
  52. elems = StackElems(&Pole1);
  53. drawBlock(poles[0]-BLOCK_WIDTH/2*i, maxY-1-BLOCK_HEIGHT*elems, poles[0]+BLOCK_WIDTH/2*i, maxY-21-BLOCK_HEIGHT*elems);
  54. blocks[i-1][0] = poles[0];
  55. blocks[i-1][1] = maxY-1-BLOCK_HEIGHT*elems;
  56. }
  57. do
  58. {
  59. updateScreen();
  60. printf("Choose your destiny:\n");
  61. firstKey = getkey();
  62. secondKey = getkey();
  63. switch(firstKey)
  64. {
  65. case SDLK_1:
  66. if(StackIsEmpty(&Pole1))
  67. printf("1 is empty\n");
  68. else
  69. {
  70. switch(secondKey)
  71. {
  72. case SDLK_1:
  73. printf("Invalid Operation!\n");
  74. break;
  75. case SDLK_2:
  76. if(StackTop(&Pole1)>StackTop(&Pole2) && StackTop(&Pole2)!=0)
  77. printf("You cant put bigger block on a smaller one.\n");
  78. else
  79. {
  80. elems = StackElems(&Pole2);
  81. buffer = StackPop(&Pole1);
  82. StackPush(&Pole2, buffer);
  83. moveBlock(blocks, 2, buffer, poles, maxY-21-BLOCK_HEIGHT*(elems+1));
  84. printf("Moved from 1 to 2 block number: %d.\n", buffer);
  85. }
  86. break;
  87. case SDLK_3:
  88. if(StackTop(&Pole1)>StackTop(&Pole3) && StackTop(&Pole3)!=0)
  89. printf("You cant put bigger block on a smaller one.\n");
  90. else
  91. {
  92. elems = StackElems(&Pole3);
  93. buffer = StackPop(&Pole1);
  94. StackPush(&Pole3, buffer);
  95. moveBlock(blocks, 3, buffer, poles, maxY-21-BLOCK_HEIGHT*(elems+1));
  96. printf("Moved from 1 to 3 block number: %d.\n", buffer);
  97. }
  98. break;
  99. default:
  100. printf("Invalid key\n");
  101. break;
  102. }
  103. }
  104. break;
  105. case SDLK_2:
  106. if(StackIsEmpty(&Pole2))
  107. printf("2 is empty\n");
  108. else
  109. {
  110. switch(secondKey)
  111. {
  112. case SDLK_1:
  113. if(StackTop(&Pole2)>StackTop(&Pole1) && StackTop(&Pole1)!=0)
  114. printf("You cant put bigger block on a smaller one.\n");
  115. else
  116. {
  117. elems = StackElems(&Pole1);
  118. buffer = StackPop(&Pole2);
  119. StackPush(&Pole1, buffer);
  120. moveBlock(blocks, 1, buffer, poles, maxY-21-BLOCK_HEIGHT*(elems+1));
  121. printf("Moved from 2 to 1 block number: %d.\n", buffer);
  122. }
  123. break;
  124. case SDLK_2:
  125. printf("Invalid Operation!\n");
  126. break;
  127. case SDLK_3:
  128. if(StackTop(&Pole2)>StackTop(&Pole3) && StackTop(&Pole3)!=0)
  129. printf("You cant put bigger block on a smaller one.\n");
  130. else
  131. {
  132. elems = StackElems(&Pole3);
  133. buffer = StackPop(&Pole2);
  134. StackPush(&Pole3, buffer);
  135. moveBlock(blocks, 3, buffer, poles, maxY-21-BLOCK_HEIGHT*(elems+1));
  136. printf("Moved from 2 to 3 block number: %d.\n", buffer);
  137. }
  138. break;
  139. default:
  140. printf("Invalid key\n");
  141. break;
  142. }
  143. }
  144. break;
  145. case SDLK_3:
  146. if(StackIsEmpty(&Pole3))
  147. printf("3 is empty\n");
  148. else
  149. {
  150. switch(secondKey)
  151. {
  152. case SDLK_1:
  153. if(StackTop(&Pole3)>StackTop(&Pole1) && StackTop(&Pole1)!=0)
  154. printf("You cant put bigger block on a smaller one.\n");
  155. else
  156. {
  157. elems = StackElems(&Pole1);
  158. buffer = StackPop(&Pole3);
  159. StackPush(&Pole1, buffer);
  160. moveBlock(blocks, 1, buffer, poles, maxY-21-BLOCK_HEIGHT*(elems+1));
  161. printf("Moved from 3 to 1 block number: %d.\n", buffer);
  162. }
  163. break;
  164. case SDLK_2:
  165. if(StackTop(&Pole3)>StackTop(&Pole2) && StackTop(&Pole2)!=0)
  166. printf("You cant put bigger block on a smaller one.\n");
  167. else
  168. {
  169. elems = StackElems(&Pole2);
  170. buffer = StackPop(&Pole3);
  171. StackPush(&Pole2, buffer);
  172. moveBlock(blocks, 2, buffer, poles, maxY-21-BLOCK_HEIGHT*(elems+1));
  173. printf("Moved from 3 to 2 block number: %d.\n", buffer);
  174. }
  175. break;
  176. case SDLK_3:
  177. printf("Invalid Operation!\n");
  178. break;
  179. default:
  180. printf("Invalid key\n");
  181. break;
  182. }
  183. }
  184. break;
  185. default:
  186. printf("Unknown key\n");
  187. break;
  188. }
  189. printf("To quit press \"q\" \n");
  190. }while(getkey() != SDLK_q);
  191. return 1;
  192. }
  193.  
  194.  
  195. void drawStructure(int *Poles)
  196. {
  197. int centerX;
  198. int centerY;
  199. int maxX;
  200. int maxY;
  201. int i;
  202. int position;
  203. centerX = screenWidth()/2;
  204. centerY = screenHeight()/2;
  205. maxX = screenWidth();
  206. maxY = screenHeight();
  207. position = maxX/POLES;
  208. filledRect(0, maxY-20, maxX, maxY, RED);
  209. for(i = 1; i < POLES+1; i++)
  210. {
  211. filledRect(position*i-position/2+10, maxY, position*i-position/2-10, maxY-200, YELLOW);
  212. Poles[i-1] = position*i-position/2;
  213. updateScreen();
  214. }
  215. }
  216.  
  217. void drawBlock(int x1, int y1, int x2, int y2)
  218. {
  219. filledRect( x1, y1, x2, y2, BLUE);
  220. updateScreen();
  221. }
  222.  
  223. void clearBlock(int x1, int y1, int x2, int y2)
  224. {
  225. filledRect( x1, y1, x2, y2, BLACK);
  226. updateScreen();
  227. }
  228.  
  229. void moveBlock(int *Blocks[], int PoleNumber, int BlockToMove, int *Poles, int FinishY)
  230. { int move_speed;
  231. int temp;
  232. int i;
  233. move_speed = 1;
  234. for(i = Blocks[BlockToMove-1][1]; i > 200; i=i-1)
  235. {
  236. if(move_speed == MOVE_SPEED)
  237. {
  238. drawRemaining(Blocks, Poles, BlockToMove);
  239. filledRect(Blocks[BlockToMove-1][0]-BLOCK_WIDTH/2*BlockToMove, i, Blocks[BlockToMove-1][0]+BLOCK_WIDTH/2*BlockToMove, i-20, BLUE);
  240. move_speed = 1;
  241. }
  242. else
  243. move_speed++;
  244. updateScreen();
  245. }
  246. temp = i;
  247. i = Blocks[BlockToMove-1][0];
  248. move_speed = 1;
  249. if(Poles[PoleNumber-1]<i)
  250. {
  251. while(Poles[PoleNumber-1]<i)
  252. {
  253. if(move_speed == MOVE_SPEED)
  254. {
  255. drawRemaining(Blocks, Poles, BlockToMove);
  256. filledRect(i-BLOCK_WIDTH/2*BlockToMove, temp, i+BLOCK_WIDTH/2*BlockToMove, temp-20, BLUE);
  257. move_speed = 1;
  258. }
  259. else
  260. move_speed++;
  261. i=i-1;
  262. updateScreen();
  263. }
  264. }
  265. else if(Poles[PoleNumber-1]>i)
  266. {
  267. while(Poles[PoleNumber-1]>=i)
  268. {
  269. if(move_speed == MOVE_SPEED)
  270. {
  271. drawRemaining(Blocks, Poles, BlockToMove);
  272. filledRect(i-BLOCK_WIDTH/2*BlockToMove, temp, i+BLOCK_WIDTH/2*BlockToMove, temp-20, BLUE);
  273. move_speed = 1;
  274. }
  275. else
  276. move_speed++;
  277. i=i+1;
  278. updateScreen();
  279. }
  280. }
  281. temp = i;
  282. move_speed = 1;
  283. for(i = 200; i < FinishY+22; i=i+1)
  284. {
  285. if(move_speed == MOVE_SPEED)
  286. {
  287. drawRemaining(Blocks, Poles, BlockToMove);
  288. filledRect(temp-BLOCK_WIDTH/2*BlockToMove, i, temp+BLOCK_WIDTH/2*BlockToMove, i-20, BLUE);
  289. move_speed = 1;
  290. }
  291. else
  292. move_speed++;
  293. updateScreen();
  294. }
  295. Blocks[BlockToMove-1][0] = temp;
  296. Blocks[BlockToMove-1][1] = i-1;
  297. }
  298.  
  299. void drawRemaining(int *Blocks[], int *Poles, int BlockToSkip)
  300. {
  301. int i;
  302. clearScreen();
  303. drawStructure(Poles);
  304. for(i = BLOCKS; i > 0; i--)
  305. {
  306. if(i == BlockToSkip)
  307. continue;
  308. else
  309. {
  310. drawBlock(Blocks[i-1][0]-BLOCK_WIDTH/2*i, Blocks[i-1][1], Blocks[i-1][0]+BLOCK_WIDTH/2*i, Blocks[i-1][1]-20);
  311. }
  312. }
  313. updateScreen();
  314. }
  315.  
  316. void clearScreen()
  317. {
  318. filledRect(0, 0, screenWidth()-1, screenHeight()-1, BLACK);
  319. }