Advertisement
podsolnyxxx

+угловой цвет и фикс проигрыша. нет таймера 13

Apr 7th, 2024
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.91 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <ctime>
  4. #include <cstdlib>
  5. #include <sstream>
  6. #include "glut.h"
  7. const int SIZE = 6;
  8. const int TILE_SIZE = 100;
  9. int board[SIZE][SIZE] = { 0 };
  10. int originalBoard[SIZE][SIZE] = { 0 }; // Переменная для хранения копии доски
  11. int score = 0; // Переменная для хранения очков
  12.  
  13. void init() {
  14. glClearColor(0.9, 0.9, 0.9, 1.0);
  15. glMatrixMode(GL_PROJECTION);
  16. glLoadIdentity();
  17. gluOrtho2D(0, SIZE * TILE_SIZE, 0, SIZE * TILE_SIZE);
  18.  
  19. glLineWidth(2.0);
  20. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  21. }
  22.  
  23. void drawTile(int x, int y, int value) {
  24. glPushMatrix();
  25. glTranslatef(x, y, 0);
  26.  
  27. bool isCornerTile = (x == 0 && y == 0) || (x == 0 && y == (SIZE - 1) * TILE_SIZE) ||
  28. (x == (SIZE - 1) * TILE_SIZE && y == 0) || (x == (SIZE - 1) * TILE_SIZE && y == (SIZE - 1) * TILE_SIZE);
  29.  
  30. if (isCornerTile) {
  31. // Для угловых клеток используем черный цвет
  32. glColor3f(0.0f, 0.0f, 0.0f);
  33. }
  34. else if (x == 0 || y == 0 || x == (SIZE - 1) * TILE_SIZE || y == (SIZE - 1) * TILE_SIZE) {
  35. // Для внешних клеток, кроме угловых, используем темно-синий цвет
  36. glColor3f(0.1f, 0.1f, 0.5f);
  37. }
  38. else {
  39. switch (value) {
  40. case 2: glColor3f(0.9f, 0.9f, 0.9f); break;
  41. case 4: glColor3f(1.0f, 1.0f, 0.5f); break;
  42. case 8: glColor3f(1.0f, 0.5f, 0.0f); break;
  43. case 16: glColor3f(1.0f, 0.0f, 0.0f); break;
  44. case 32: glColor3f(0.8f, 0.6f, 1.0f); break;
  45. case 64: glColor3f(0.0f, 0.0f, 1.0f); break;
  46. case 128: glColor3f(0.0f, 1.0f, 1.0f); break;
  47. case 256: glColor3f(0.6f, 1.0f, 0.6f); break;
  48. case 512: glColor3f(0.0f, 1.0f, 0.0f); break;
  49. case 1024: glColor3f(0.0f, 0.5f, 0.0f); break;
  50. case 2048: glColor3f(1.0f, 0.0f, 1.0f); break;
  51. default: glColor3f(1.0f, 1.0f, 1.0f);
  52. }
  53. }
  54.  
  55. glBegin(GL_QUADS);
  56. glVertex2i(0, 0);
  57. glVertex2i(TILE_SIZE, 0);
  58. glVertex2i(TILE_SIZE, TILE_SIZE);
  59. glVertex2i(0, TILE_SIZE);
  60. glEnd();
  61.  
  62. if (value != 0) {
  63. glColor3f(0.0f, 0.0f, 0.0f);
  64. std::string text = std::to_string(value);
  65. glRasterPos2i(TILE_SIZE / 2 - 8 * text.length(), TILE_SIZE / 2 + 8);
  66. for (char c : text) {
  67. glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, c);
  68. }
  69. }
  70.  
  71. glColor3f(0.0f, 0.0f, 0.0f);
  72. glBegin(GL_LINE_LOOP);
  73. glVertex2i(0, 0);
  74. glVertex2i(TILE_SIZE, 0);
  75. glVertex2i(TILE_SIZE, TILE_SIZE);
  76. glVertex2i(0, TILE_SIZE);
  77. glEnd();
  78.  
  79. glPopMatrix();
  80. }
  81.  
  82.  
  83. void generateTile() {
  84. std::vector<std::pair<int, int>> emptyCells;
  85. for (int i = 1; i < SIZE - 1; ++i) {
  86. for (int j = 1; j < SIZE - 1; ++j) {
  87. if (board[i][j] == 0) {
  88. emptyCells.push_back(std::make_pair(i, j));
  89. }
  90. }
  91. }
  92. if (emptyCells.empty()) {
  93. return;
  94. }
  95.  
  96. int value = (rand() % 10 == 0) ? 4 : 2;
  97.  
  98. int position = rand() % emptyCells.size();
  99. int x = emptyCells[position].first;
  100. int y = emptyCells[position].second;
  101. board[x][y] = value;
  102. }
  103.  
  104. bool checkWin() {
  105. for (int i = 0; i < SIZE; ++i) {
  106. for (int j = 0; j < SIZE; ++j) {
  107. if (board[i][j] == 2048) {
  108. return true;
  109. }
  110. }
  111. }
  112. return false;
  113. }
  114.  
  115. bool checkLose() {
  116. for (int i = 1; i < SIZE - 1; ++i) {
  117. for (int j = 1; j < SIZE - 1; ++j) {
  118. if (board[i][j] == 0) {
  119. return false; // Если есть пустая клетка внутри внешнего слоя, игра не закончена
  120. }
  121. if (board[i][j] == board[i][j - 1] || board[i][j] == board[i][j + 1] ||
  122. board[i][j] == board[i - 1][j] || board[i][j] == board[i + 1][j]) {
  123. return false; // Если соседние клетки имеют такое же значение, игра не закончена
  124. }
  125. }
  126. }
  127. return true; // Если все клетки внутри внешнего слоя заполнены и нет возможности объединить клетки, игра закончена
  128. }
  129.  
  130. void moveLeft() {
  131. for (int i = 1; i < SIZE - 1; ++i) {
  132. for (int j = 1; j < SIZE - 1; ++j) {
  133. if (board[i][j] == 0) {
  134. for (int k = j + 1; k < SIZE - 1; ++k) {
  135. if (board[i][k] != 0) {
  136. board[i][j] = board[i][k];
  137. board[i][k] = 0;
  138. break;
  139. }
  140. }
  141. }
  142. }
  143. }
  144. }
  145.  
  146. void mergeLeft() {
  147. for (int i = 1; i < SIZE - 1; ++i) {
  148. for (int j = 1; j < SIZE - 1; ++j) {
  149. if (board[i][j] == board[i][j + 1] && board[i][j] != 0) {
  150. board[i][j] *= 2;
  151. board[i][j + 1] = 0;
  152. score += board[i][j];
  153. }
  154. }
  155. }
  156. }
  157.  
  158. void moveRight() {
  159. for (int i = 1; i < SIZE - 1; ++i) {
  160. for (int j = SIZE - 2; j > 0; --j) {
  161. if (board[i][j] == 0) {
  162. for (int k = j - 1; k > 0; --k) {
  163. if (board[i][k] != 0) {
  164. board[i][j] = board[i][k];
  165. board[i][k] = 0;
  166. break;
  167. }
  168. }
  169. }
  170. }
  171. }
  172. }
  173.  
  174. void mergeRight() {
  175. for (int i = 1; i < SIZE - 1; ++i) {
  176. for (int j = SIZE - 2; j > 0; --j) {
  177. if (board[i][j] == board[i][j - 1] && board[i][j] != 0) {
  178. board[i][j] *= 2;
  179. board[i][j - 1] = 0;
  180. score += board[i][j];
  181. }
  182. }
  183. }
  184. }
  185.  
  186. void moveUp() {
  187. for (int j = 1; j < SIZE - 1; ++j) {
  188. for (int i = 1; i < SIZE - 1; ++i) {
  189. if (board[i][j] == 0) {
  190. for (int k = i + 1; k < SIZE - 1; ++k) {
  191. if (board[k][j] != 0) {
  192. board[i][j] = board[k][j];
  193. board[k][j] = 0;
  194. break;
  195. }
  196. }
  197. }
  198. }
  199. }
  200. }
  201.  
  202. void mergeUp() {
  203. for (int j = 1; j < SIZE - 1; ++j) {
  204. for (int i = 1; i < SIZE - 1; ++i) {
  205. if (board[i][j] == board[i + 1][j] && board[i][j] != 0) {
  206. board[i][j] *= 2;
  207. board[i + 1][j] = 0;
  208. score += board[i][j];
  209. }
  210. }
  211. }
  212. }
  213.  
  214. void moveDown() {
  215. for (int j = 1; j < SIZE - 1; ++j) {
  216. for (int i = SIZE - 2; i > 0; --i) {
  217. if (board[i][j] == 0) {
  218. for (int k = i - 1; k > 0; --k) {
  219. if (board[k][j] != 0) {
  220. board[i][j] = board[k][j];
  221. board[k][j] = 0;
  222. break;
  223. }
  224. }
  225. }
  226. }
  227. }
  228. }
  229.  
  230. void mergeDown() {
  231. for (int j = 1; j < SIZE - 1; ++j) {
  232. for (int i = SIZE - 2; i > 0; --i) {
  233. if (board[i][j] == board[i - 1][j] && board[i][j] != 0) {
  234. board[i][j] *= 2;
  235. board[i - 1][j] = 0;
  236. score += board[i][j];
  237. }
  238. }
  239. }
  240. }
  241.  
  242. void handleKeypress(unsigned char key, int x, int y) {
  243. if (key == 27) {
  244. exit(0);
  245. }
  246. }
  247.  
  248. void updateOriginalBoard() {
  249. std::memcpy(originalBoard, board, SIZE * SIZE * sizeof(int));
  250. }
  251.  
  252. void handleSpecialKeypress(int key, int x, int y) {
  253. int originalBoard[SIZE][SIZE];
  254. std::memcpy(originalBoard, board, SIZE * SIZE * sizeof(int));
  255.  
  256. switch (key) {
  257. case GLUT_KEY_LEFT:
  258. moveLeft();
  259. mergeLeft();
  260. moveLeft();
  261. break;
  262. case GLUT_KEY_RIGHT:
  263. moveRight();
  264. mergeRight();
  265. moveRight();
  266. break;
  267. case GLUT_KEY_UP:
  268. moveUp();
  269. mergeUp();
  270. moveUp();
  271. break;
  272. case GLUT_KEY_DOWN:
  273. moveDown();
  274. mergeDown();
  275. moveDown();
  276. break;
  277. }
  278.  
  279. bool moved = false;
  280. for (int i = 0; i < SIZE; ++i) {
  281. for (int j = 0; j < SIZE; ++j) {
  282. if (originalBoard[i][j] != board[i][j]) {
  283. moved = true;
  284. break;
  285. }
  286. }
  287. if (moved)
  288. break;
  289. }
  290.  
  291. if (moved) {
  292. generateTile();
  293. glutPostRedisplay();
  294. if (checkWin()) {
  295. std::cout << "You win! Your score: " << score << std::endl;
  296. exit(0);
  297. }
  298. if (checkLose()) {
  299. std::cout << "Game over! Your score: " << score << std::endl;
  300. exit(0);
  301. }
  302. }
  303. }
  304.  
  305. void drawBoard() {
  306. for (int i = 0; i < SIZE; ++i) {
  307. for (int j = 0; j < SIZE; ++j) {
  308. int x = j * TILE_SIZE;
  309. int y = (SIZE - 1 - i) * TILE_SIZE;
  310. drawTile(x, y, board[i][j]);
  311. }
  312. }
  313. }
  314.  
  315. void timer(int value) {
  316. glutTimerFunc(1000, timer, 0);
  317. glutPostRedisplay();
  318. }
  319.  
  320. void display() {
  321. glClear(GL_COLOR_BUFFER_BIT);
  322. drawBoard();
  323. glutSwapBuffers();
  324. }
  325.  
  326. void handleMouseClick(int button, int state, int x, int y) {
  327. if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
  328. updateOriginalBoard(); // Сохраняем оригинальную доску перед перемещением клеток
  329.  
  330. int row = SIZE - 1 - (y / TILE_SIZE);
  331. int col = x / TILE_SIZE;
  332.  
  333. if ((row == 0 && col == 0) || // левый верхний угол
  334. (row == 0 && col == SIZE - 1) || // правый верхний угол
  335. (row == SIZE - 1 && col == 0) || // левый нижний угол
  336. (row == SIZE - 1 && col == SIZE - 1)) // правый нижний угол
  337. {
  338. // Если нажата угловая клетка внешнего слоя, ничего не делаем
  339. glutPostRedisplay();
  340. return;
  341. }
  342.  
  343. if (row == 0 || row == SIZE - 1 || col == 0 || col == SIZE - 1) {
  344. // Нажатие на остальные клетки внешнего слоя
  345. if (row == 0) {
  346. // Нажатие на верхние клетки внешнего слоя, двигаем клетки вверх
  347. moveDown();
  348. mergeDown();
  349. moveDown();
  350. }
  351. else if (row == SIZE - 1) {
  352. // Нажатие на нижние клетки внешнего слоя, двигаем клетки вниз
  353. moveUp();
  354. mergeUp();
  355. moveUp();
  356. }
  357. else if (col == 0) {
  358. // Нажатие на левые клетки внешнего слоя, двигаем клетки влево
  359. moveLeft();
  360. mergeLeft();
  361. moveLeft();
  362. }
  363. else {
  364. // Нажатие на правые клетки внешнего слоя, двигаем клетки вправо
  365. moveRight();
  366. mergeRight();
  367. moveRight();
  368. }
  369.  
  370. bool moved = false;
  371. for (int i = 0; i < SIZE; ++i) {
  372. for (int j = 0; j < SIZE; ++j) {
  373. if (board[i][j] != originalBoard[i][j]) {
  374. moved = true;
  375. break;
  376. }
  377. }
  378. if (moved)
  379. break;
  380. }
  381.  
  382. if (moved) {
  383. generateTile();
  384. glutPostRedisplay();
  385. if (checkWin()) {
  386. std::cout << "You win! Your score: " << score << std::endl;
  387. exit(0);
  388. }
  389. if (checkLose()) {
  390. std::cout << "Game over! Your score: " << score << std::endl;
  391. exit(0);
  392. }
  393. }
  394. else {
  395. // Если клетки не изменили своего положения, новые клетки не появятся
  396. glutPostRedisplay();
  397. }
  398. }
  399. }
  400. }
  401.  
  402.  
  403. int main(int argc, char** argv) {
  404. srand(time(nullptr));
  405. glutInit(&argc, argv);
  406. glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
  407. glutInitWindowSize(SIZE * TILE_SIZE, SIZE * TILE_SIZE);
  408. glutCreateWindow("2048 Game");
  409. glutDisplayFunc(display);
  410. glutKeyboardFunc(handleKeypress);
  411. glutSpecialFunc(handleSpecialKeypress);
  412. glutMouseFunc(handleMouseClick); // Добавленная строка для обработки щелчков мыши
  413. init();
  414. generateTile();
  415. generateTile();
  416. glutTimerFunc(1000, timer, 0);
  417. glutMainLoop();
  418. return 0;
  419. }
  420.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement