ad208三国

 找回密码
 加入
搜索
热搜: 活动 交友 discuz
查看: 823|回复: 0

适合练手的C语言编写的俄罗斯方块

[复制链接]
发表于 2023-7-31 12:10:46 | 显示全部楼层 |阅读模式

pc2g,电脑好游戏


  1. #include<stdio.h>
  2. #include<time.h>
  3. #include<Windows.h>
  4. #define HEIGHT  28  //设置地图高度
  5. #define WIDTH   20  //设置地图宽度
  6. #define ZERO    1
  7. #define HEIGHT_1 18
  8. #define Loca_y    6
  9. #define Loca_x    25
  10. #define PRINTF  printf("■");
  11. #define LINE    printf("\n");
  12. #define EMPTY   printf("  ");
  13. typedef struct Tetris
  14. {
  15. int x_1, y_1;   //主x坐标,主y坐标,下面三个为附属,通过主坐标确定三个附属
  16. int x_2, y_2;
  17. int x_3, y_3;
  18. int x_4, y_4;
  19. int code;//7种方块形态代号
  20. Tetris * next;
  21. }Tetris;
  22. void DeawMap();                             //绘制地图
  23. Tetris * BlockRand(int code);                     //随机主方块生成  
  24. void JudgeDirection(Tetris ** Block); //按键响应
  25. void Form(Tetris ** Block);                      //方块坐标全部确定
  26. void ShowBlock(Tetris ** Block);            //显示完整方块
  27. int JudgeWall(Tetris ** Block);             //判断左右界限
  28. void MoveCursor(int x, int y);              //移动光标  不闪屏是因为每次不会刷新全部地图,只会刷新某一特定区域
  29. void SetColour(int c);                      //颜色设定
  30. int JudgeGroud(Tetris * Phead, Tetris ** Block);//判断落地
  31. void JudgeEntire(Tetris * Head);            //判断整行是否填满
  32. void NewEntire(Tetris * head, int y);  //若上面函数成立,若清除该行,并刷新地图
  33. void Show(int n);                                //显示信息,下一个方块得分情况,如果想加入一些信息可以在该函数内修改
  34. void Location(Tetris ** Block, int x, int y, int a, int b, int c, int d, int e, int f);   //坐标更新1
  35. void Location_y(Tetris ** Block, int x, int y, int a, int b, int c, int d, int e, int f); //坐标更新2
  36. void Location_x(int x, int y, int a, int b, int c, int d, int e, int f);                  //信息更新
  37. Tetris *Phead = NULL;   //链表头指针
  38. Tetris *Pend = NULL;    //跟随指针 (尾插法需要)
  39. Tetris * Return = NULL; //节点地址返回
  40. int form = 0; //判断形态
  41. int UP = 0;   //下降速度判断
  42. int code_y = 0;//随机形态
  43. int fengs = 0; //得分

  44. int main()
  45. {
  46. DeawMap();
  47. code_y = rand() % 7 + 1;
  48. while (1)
  49. {
  50.   Return = BlockRand(code_y);
  51.   code_y = rand() % 7 + 1;
  52.   Show(code_y);
  53.   ShowBlock(&Return);
  54. }
  55. system("pause>nul");
  56. return 0;
  57. }

  58. void DeawMap()
  59. {
  60. for (int i = 0; i < WIDTH; i++)PRINTF LINE  //上边框
  61.   for (int i = 1; i < HEIGHT - 1; i++)          //打印左右边框
  62.   {
  63.    for (int j = 0; j < WIDTH; j++)
  64.    {
  65.     if (j == 0 || j == WIDTH - 1)
  66.     {
  67.      PRINTF
  68.       if (j == WIDTH - 1)LINE
  69.     }
  70.     else EMPTY
  71.    }
  72.   }
  73. for (int i = 0; i < WIDTH; i++)PRINTF LINE  //下边框
  74. system("color 03");
  75. }

  76. void Location(Tetris ** Block, int x, int y, int a, int b, int c, int d, int e, int f)
  77. {
  78. (*Block)->x_1 = (*Block)->x_1 + x;
  79. (*Block)->y_1 = (*Block)->y_1 + y;
  80. (*Block)->x_2 = (*Block)->x_1 + a;
  81. (*Block)->y_2 = (*Block)->y_1 + b;
  82. (*Block)->x_3 = (*Block)->x_1 + c;
  83. (*Block)->y_3 = (*Block)->y_1 + d;
  84. (*Block)->x_4 = (*Block)->x_1 + e;
  85. (*Block)->y_4 = (*Block)->y_1 + f;
  86. }

  87. void Location_y(Tetris ** Block, int x, int y, int a, int b, int c, int d, int e, int f)
  88. {
  89. (*Block)->x_1 = (*Block)->x_1 + x;
  90. (*Block)->y_1 = (*Block)->y_1 + y;
  91. (*Block)->x_2 = (*Block)->x_2 + a;
  92. (*Block)->y_2 = (*Block)->y_2 + b;
  93. (*Block)->x_3 = (*Block)->x_3 + c;
  94. (*Block)->y_3 = (*Block)->y_3 + d;
  95. (*Block)->x_4 = (*Block)->x_4 + e;
  96. (*Block)->y_4 = (*Block)->y_4 + f;
  97. }

  98. Tetris * BlockRand(int code_y)
  99. {
  100. srand((int)time(0));
  101. Tetris * Block = (Tetris*)malloc(sizeof(Tetris));
  102. Block->x_1 = 8;
  103. Block->y_1 = 4;//规定初始中心方块的坐标为(8,4)
  104. Block->code = code_y;
  105. if (Phead == NULL)Phead = Block;
  106. else Pend->next = Block;
  107. Block->next = NULL;
  108. Pend = Block;
  109. return Block;
  110. }

  111. void ShowBlock(Tetris ** Block)
  112. {
  113. while (1)
  114. {

  115.   Form(&Return);
  116.   if ((*Block)->code == 1)SetColour(13);
  117.   if ((*Block)->code == 2)SetColour(15);
  118.   if ((*Block)->code == 3)SetColour(12);
  119.   if ((*Block)->code == 4)SetColour(10);
  120.   if ((*Block)->code == 5)SetColour(6);
  121.   if ((*Block)->code == 6)SetColour(4);
  122.   if ((*Block)->code == 7)SetColour(8);
  123.   MoveCursor((*Block)->x_1, (*Block)->y_1); PRINTF
  124.   MoveCursor((*Block)->x_2, (*Block)->y_2); PRINTF
  125.   MoveCursor((*Block)->x_3, (*Block)->y_3); PRINTF
  126.   MoveCursor((*Block)->x_4, (*Block)->y_4); PRINTF
  127.   if (JudgeGroud(Phead, &Return) == 0)
  128.   {
  129.    system("color 03");
  130.    break;
  131.   }
  132.   if (UP == 0)
  133.   {
  134.    for (int i = 0; i <= 400000000; i++) {}
  135.   }
  136.   if (UP == 1)
  137.   {
  138.    for (int i = 0; i <= 40000000; i++) {}
  139.    UP = 0;
  140.   }
  141.   MoveCursor((*Block)->x_1, (*Block)->y_1); EMPTY
  142.   MoveCursor((*Block)->x_2, (*Block)->y_2); EMPTY
  143.   MoveCursor((*Block)->x_3, (*Block)->y_3); EMPTY
  144.   MoveCursor((*Block)->x_4, (*Block)->y_4); EMPTY
  145.   Location_y(&Return, 0, 1, 0, 1, 0, 1, 0, 1);
  146.   JudgeDirection(&Return);
  147.   JudgeEntire(Phead);
  148. }
  149. }

  150. void JudgeDirection(Tetris ** Block)
  151. {
  152. if (GetAsyncKeyState(VK_UP) && 0x8000)
  153. {
  154.   form += 1;
  155.   if (form == 4)
  156.   {
  157.    form = 0;
  158.   }
  159.   Form(&Return);
  160. }
  161. if (GetAsyncKeyState(VK_DOWN) && 0x8000)
  162. {
  163.   //加速向下  时间加速
  164.   UP = 1;
  165. }
  166. if (GetAsyncKeyState(VK_LEFT) && 0x8000)
  167. {
  168.   //向左移动
  169.   if (JudgeWall(&Return) != -1) Location_y(&Return, -1, 0, -1, 0, -1, 0, -1, 0);
  170. }
  171. if (GetAsyncKeyState(VK_RIGHT) && 0x8000)
  172. {
  173.   //向右移动
  174.   if (JudgeWall(&Return) != -2) Location_y(&Return, 1, 0, 1, 0, 1, 0, 1, 0);
  175. }
  176. if (GetAsyncKeyState(VK_ESCAPE) && 0x0D)
  177. {
  178.   MoveCursor(27, 15);
  179.   printf("游戏暂停");
  180.   //判断Esc
  181.   while (1)
  182.   {
  183.    if (GetAsyncKeyState(VK_ESCAPE) && 0x0D)
  184.    {
  185.     MoveCursor(27, 15);
  186.     printf("       ");
  187.     break;
  188.    }
  189.   }
  190. }
  191. }

  192. void Form(Tetris ** Block)
  193. {
  194. //先确实哪一类,再细分
  195. switch ((*Block)->code)
  196. {
  197. case 1:
  198.   if (form == 0)Location(&Return, 0, 0, -1, 0, 0, -1, 1, 0);
  199.   if (form == 1)Location(&Return, 0, 0, 0, 1, 0, -1, 1, 0);
  200.   if (form == 2)Location(&Return, 0, 0, 0, 1, -1, 0, 1, 0);
  201.   if (form == 3)Location(&Return, 0, 0, 0, 1, -1, 0, 0, -1);
  202.   break;
  203. case 2:
  204.   Location(&Return, 0, 0, 1, 0, 0, 1, 1, 1);
  205.   break;
  206. case 3:
  207.   if (form == 0 || form == 2)Location(&Return, 0, 0, 0, -1, 0, 1, 0, 2);
  208.   if (form == 1 || form == 3)Location(&Return, 0, 0, -1, 0, 1, 0, 2, 0);
  209.   break;
  210. case 4:
  211.   if (form == 0)Location(&Return, 0, 0, -1, 0, 1, 0, 1, -1);
  212.   if (form == 1)Location(&Return, 0, 0, 0, -1, 1, 0, 0, -2);
  213.   if (form == 2)Location(&Return, 0, 0, 0, -1, 1, -1, 2, -1);
  214.   if (form == 3)Location(&Return, 0, 0, 0, -1, 0, -2, -1, -2);
  215.   break;
  216. case 5:
  217.   if (form == 0)Location(&Return, 0, 0, 1, 0, 2, 0, 0, -1);
  218.   if (form == 1)Location(&Return, 0, 0, 1, 0, 1, -1, 1, -2);
  219.   if (form == 2)Location(&Return, 0, 0, 1, 0, 2, 0, 2, 1);
  220.   if (form == 3)Location(&Return, 0, 0, 1, 0, 0, 1, 0, 2);
  221.   break;
  222. case 6:
  223.   if (form == 0 || form == 2)Location(&Return, 0, 0, 0, -1, 1, 0, 1, 1);
  224.   if (form == 1 || form == 3)Location(&Return, 0, 0, 0, -1, 1, -1, -1, 0);
  225.   break;
  226. case 7:
  227.   if (form == 0 || form == 2)Location(&Return, 0, 0, 0, 1, 1, 0, 1, -1);
  228.   if (form == 1 || form == 3)Location(&Return, 0, 0, 0, 1, -1, 0, 1, 1);
  229. }
  230. }

  231. void MoveCursor(int x, int y)//设置光标位置(就是输出显示的开始位置)
  232. {
  233. COORD pos = { x * 2,y };
  234. HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);//获得 标准输出的句柄   
  235. SetConsoleCursorPosition(output, pos); //设置控制台光标位置
  236. }

  237. void SetColour(int c)
  238. {
  239. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);//API函数可以改变控制台颜色
  240. }
  241. int JudgeWall(Tetris ** Block)
  242. {
  243. if ((*Block)->x_1 == ZERO || (*Block)->x_2 == ZERO || (*Block)->x_3 == ZERO || (*Block)->x_4 == ZERO)return -1;
  244. if ((*Block)->x_1 == HEIGHT_1 || (*Block)->x_2 == HEIGHT_1 || (*Block)->x_3 == HEIGHT_1 || (*Block)->x_4 == HEIGHT_1)return -2;
  245. return 0;
  246. }

  247. int JudgeGroud(Tetris * Phead, Tetris ** Block)
  248. {

  249. Tetris * P = Phead;
  250. //如果到达最低层。直接经行下一循环
  251. if ((*Block)->y_1 == 26 || (*Block)->y_2 == 26 || (*Block)->y_3 == 26 || (*Block)->y_4 == 26)return 0;
  252. while (P->next != NULL)
  253. {
  254.   if (P->y_1 == (*Block)->y_1 + 1)
  255.   {
  256.    if (P->x_1 == (*Block)->x_1)return 0;
  257.   }
  258.   if (P->y_2 == (*Block)->y_1 + 1)
  259.   {
  260.    if (P->x_2 == (*Block)->x_1)return 0;
  261.   }
  262.   if (P->y_3 == (*Block)->y_1 + 1)
  263.   {
  264.    if (P->x_3 == (*Block)->x_1)return 0;
  265.   }
  266.   if (P->y_4 == (*Block)->y_1 + 1)
  267.   {
  268.    if (P->x_4 == (*Block)->x_1)return 0;
  269.   }
  270.   if (P->y_1 == (*Block)->y_2 + 1)
  271.   {
  272.    if (P->x_1 == (*Block)->x_2)return 0;
  273.   }
  274.   if (P->y_2 == (*Block)->y_2 + 1)
  275.   {
  276.    if (P->x_2 == (*Block)->x_2)return 0;
  277.   }
  278.   if (P->y_3 == (*Block)->y_2 + 1)
  279.   {
  280.    if (P->x_3 == (*Block)->x_2)return 0;
  281.   }
  282.   if (P->y_4 == (*Block)->y_2 + 1)
  283.   {
  284.    if (P->x_4 == (*Block)->x_2)return 0;
  285.   }
  286.   if (P->y_1 == (*Block)->y_3 + 1)
  287.   {
  288.    if (P->x_1 == (*Block)->x_3)return 0;
  289.   }
  290.   if (P->y_2 == (*Block)->y_3 + 1)
  291.   {
  292.    if (P->x_2 == (*Block)->x_3)return 0;
  293.   }
  294.   if (P->y_3 == (*Block)->y_3 + 1)
  295.   {
  296.    if (P->x_3 == (*Block)->x_3)return 0;
  297.   }
  298.   if (P->y_4 == (*Block)->y_3 + 1)
  299.   {
  300.    if (P->x_4 == (*Block)->x_3)return 0;
  301.   }
  302.   if (P->y_1 == (*Block)->y_4 + 1)
  303.   {
  304.    if (P->x_1 == (*Block)->x_4)return 0;
  305.   }
  306.   if (P->y_2 == (*Block)->y_4 + 1)
  307.   {
  308.    if (P->x_2 == (*Block)->x_4)return 0;
  309.   }
  310.   if (P->y_3 == (*Block)->y_4 + 1)
  311.   {
  312.    if (P->x_3 == (*Block)->x_4)return 0;
  313.   }
  314.   if (P->y_4 == (*Block)->y_4 + 1)
  315.   {
  316.    if (P->x_4 == (*Block)->x_4)return 0;
  317.   }
  318.   P = P->next;
  319. }
  320. return 1;
  321. }

  322. void JudgeEntire(Tetris * Head)
  323. {
  324. Tetris * PHead = Head;
  325. //从1到26
  326. for (int y = 26; y >= 1; y--)
  327. {
  328.   int sum = 0;
  329.   while (PHead->next != NULL)
  330.   {
  331.    if (PHead->y_1 == y)sum++;
  332.    if (PHead->y_2 == y)sum++;
  333.    if (PHead->y_3 == y)sum++;
  334.    if (PHead->y_4 == y)sum++;
  335.    MoveCursor(20, 28);
  336.    PHead = PHead->next;
  337.   }
  338.   PHead = Head;
  339.   if (sum == 18)
  340.   {
  341.   //如果成行则,执行NewEntire()  清空该行,并将所有y下降一个单位。
  342.    NewEntire(Phead, y);
  343.    fengs += 10;
  344.    Show(code_y);
  345.   }
  346.   sum = 0;
  347. }
  348. }

  349. void NewEntire(Tetris * head,int y)
  350. {
  351. Tetris * PHead = head;
  352. while (PHead->next != NULL)
  353. {
  354.   if (PHead->y_1 == y)
  355.   {
  356.    MoveCursor(PHead->x_1, PHead->y_1); EMPTY
  357.    PHead->x_1 = 99;
  358.    PHead->y_1 = 99;
  359.   }
  360.   if (PHead->y_2 == y)
  361.   {
  362.    MoveCursor(PHead->x_2, PHead->y_2); EMPTY
  363.    PHead->x_2 = 99;
  364.    PHead->y_2 = 99;
  365.   }
  366.   if (PHead->y_3 == y)
  367.   {
  368.    MoveCursor(PHead->x_3, PHead->y_3); EMPTY
  369.    PHead->x_3 = 99;
  370.    PHead->y_3 = 99;
  371.   }
  372.   if (PHead->y_4 == y)
  373.   {
  374.    MoveCursor(PHead->x_4, PHead->y_4); EMPTY
  375.    PHead->x_4 = 99;
  376.    PHead->y_4 = 99;
  377.   }
  378.   PHead = PHead->next;
  379. }
  380. PHead = head;
  381. while (PHead->next != NULL)
  382. {
  383.   if (PHead->y_1 < y)
  384.   {
  385.    MoveCursor(PHead->x_1, PHead->y_1); EMPTY
  386.    PHead->y_1 += 1;
  387.    MoveCursor(PHead->x_1, PHead->y_1); PRINTF
  388.   }
  389.   if (PHead->y_2 < y)
  390.   {
  391.    MoveCursor(PHead->x_2, PHead->y_2); EMPTY
  392.    PHead->y_2 += 1;
  393.    MoveCursor(PHead->x_2, PHead->y_2); PRINTF
  394.   }
  395.   if (PHead->y_3 < y)
  396.   {
  397.    MoveCursor(PHead->x_3, PHead->y_3); EMPTY
  398.    PHead->y_3 += 1;
  399.    MoveCursor(PHead->x_3, PHead->y_3); PRINTF
  400.   }
  401.   if (PHead->y_4 < y)
  402.   {
  403.    MoveCursor(PHead->x_4, PHead->y_4); EMPTY
  404.    PHead->y_4 += 1;
  405.    MoveCursor(PHead->x_4, PHead->y_4); PRINTF
  406.   }
  407.   PHead = PHead->next;
  408. }
  409. }

  410. void Show(int n)
  411. {
  412. //显示下一个方块
  413. //先清空该区域
  414. for (int j = 4; j <= 8; j++)
  415. {
  416.   for (int i = 23; i <= 28; i++)
  417.   {
  418.    MoveCursor(i, j);  EMPTY
  419.   }
  420. }
  421. MoveCursor(24, 3);
  422. printf("下一个方块种类:");
  423. MoveCursor(24, 10);
  424. printf("游戏得分:%d", fengs);
  425. MoveCursor(24, 12);
  426. printf("");
  427. if (n == 1)
  428. {
  429.   SetColour(13);
  430.   Location_x(-1, 0, 0, 0, 1, 0, -1, -1);
  431. }
  432. if (n == 2)
  433. {
  434.   SetColour(15);
  435.   Location_x(0, 0, 1, 0, -1, 1, 1, 1);
  436. }
  437. if (n == 3)
  438. {
  439.   SetColour(12);
  440.   Location_x(0, 0, 1, 0, 2, 0, 3, 0);
  441. }
  442. if (n == 4)
  443. {
  444.   SetColour(10);
  445.   Location_x(0, 0, 1, 0, 2, 0, 2, -1);
  446. }
  447. if (n == 5)
  448. {
  449.   SetColour(6);
  450.   Location_x(0, -1, 0, 0, 1, 0, 2, 0);
  451. }
  452. if (n == 6)
  453. {
  454.   SetColour(4);
  455.   Location_x(-1, -1, -1, 0, 0, 0, 0, 1);
  456. }
  457. if (n == 7)
  458. {
  459.   SetColour(8);
  460.   Location_x(0, -1, 0, 0, -1, 0, -1, 1);
  461. }
  462. }

  463. void Location_x(int x, int y, int a, int b, int c, int d, int e, int f)
  464. {
  465.      MoveCursor(Loca_x+x, Loca_y+y); PRINTF
  466.   MoveCursor(Loca_x+a, Loca_y+b); PRINTF
  467.   MoveCursor(Loca_x+c, Loca_y+d); PRINTF
  468.   MoveCursor(Loca_x+e, Loca_y+f); PRINTF
  469. }
复制代码


Archiver|手机版|小黑屋|ad208三国

GMT+8, 2024-4-28 04:08

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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