C语言实现俄罗斯方块游戏程序设计【附源码】

news2025/3/1 18:17:27

目录

一、前言

二、需求分析

2.1 产品需求概述

2.1.1 功能简介

2.1.2 运行环境

2.2 功能需求

2.2.1 绘制地图

2.2.2 生成随机方块

2.2.3 按键响应

2.2.4 预览方块

2.2.5 分数累加

三、概要设计

3.1 系统体系结构图

3.2 模块描述

四、详细设计

4.1 系统主要函数说明   

4.1.1 函数DeawMap

4.1.2 函数Tetris*BlockRand

4.1.3 函数JudgeDirection

4.1.4 函数Form

4.1.5 函数ShowBlock

4.1.6 函数JudgeWall

4.1.7 函数MoveCursor

4.1.8 函数SetColour

4.1.9 函数JudgeGroud

4.1.10 函数JudgeEntire

4.1.11 函数Show

4.1.12 函数Location

五、系统测试

5.1 初始界面

5.2 控制方块

5.3 控制方块旋转

六、程序设计 


一、前言

俄罗斯方块游戏,是俄罗斯人阿莱克斯·帕伊特诺夫在八十年代末制作一款游戏,以其规则简单,容易上手,游戏过程变化无穷,已经成为一个家喻户晓老少皆宜的大众游戏。该程序是完成一个简易的俄罗斯方块的任务,其通过结构体、指针、绘图等方面的知识完成几个重要的功能:界面,方块下落,旋转,判断是否还能下落,左右移动,分数,速度设置,清除满的每行,下个方块的预览等。  

二、需求分析

2.1 产品需求概述

2.1.1 功能简介

该程序是完成一个简易的俄罗斯方块的任务,规则简单,容易上手,游戏过程变化无穷,是一个家喻户晓、老少皆宜的大众游戏。本程序通过结构体、指针、绘图等方面的知识完成几个重要的功能:界面,方块下落,旋转,判断是否还能下落,左右移动,分数,速度设置,清满的每行,下个方块的预览等。

2.1.2 运行环境

(1)硬件环境:

最低配置:CPU:Pentium3 800以上或其他的兼容规格,内存:256M以上,硬盘:100GB以上空间

推荐配置:CPU:Pentium4 1.6G,内存:512M以上,硬盘:100GB以上空间

(2)软件环境:

运用VC++6.0编程环境

2.2 功能需求

本系统主要功能:绘制地图;生成随机方块;按键响应;预览方块;分数累加。

2.2.1 绘制地图

通过for循环嵌套的方式,绘制一个20*28的地图。

2.2.2 生成随机方块

随机生成下一个方块。

2.2.3 按键响应

通过按键控制程序,上键旋转方块,下键加速下落,左右键控制方块向左向右移动,Esc暂停游戏。

2.2.4 预览方块

在地图右上方显示下一个方块种类。

2.2.5 分数累加

1.在地图右上方显示目前已获得分数;

2.一次消除的行数越多,得分指数越高。

三、概要设计

根据对题目的分析,该系统主要包括,生成方块、输出方块、按键响应、落地判断、刷新界面、预览方块六个功能,每一个功能都由相应的函数及其他函数辅助实现。主函数控制整个程序的运行及生成地图,可以使程序在一次的运行之中循环执行所有的功能,除此外还具有暂停功能,根据需要暂停程序,使程序更加的完美。

3.1 系统体系结构图

图 1 俄罗斯方块_系统体系结构图

3.2 模块描述

本系统为俄罗斯方块游戏系统,每个模块均为实现游戏功能,无子系统。

模块1:绘制地图

名  称

绘制地图

标识

DeawMap

系统名称

俄罗斯方块

接口说明

输入

输出

游戏地图

功能说明

绘制游戏地图

运行环境

运行于VC++6.0编程坏境之下

调用关系

调用模块

被调用模块

模块2:生成随机方块

名  称

生成随机方块

标识

Tetris*BlockRand

系统名称

俄罗斯方块

接口说明

输入

输出

方块

功能说明

确定下一个方块的类型

运行环境

运行于VC++6.0编程坏境之下

调用关系

调用模块

颜色设定

被调用模块

模块3:按键响应

名  称

按键响应

标识

JudgeDirection

系统名称

俄罗斯方块

接口说明

输入

键盘

输出

功能说明

控制方块

运行环境

运行于VC++6.0编程坏境之下

调用关系

调用模块

被调用模块

模块4:确定坐标

名  称

确定坐标

标识

Form

系统名称

俄罗斯方块

接口说明

输入

输出

功能说明

确定方块坐标

运行环境

运行于VC++6.0编程坏境之下

调用关系

调用模块

坐标更新

被调用模块

模块5:显示完整方块

名  称

显示完整方块

标识

ShowBlock

系统名称

俄罗斯方块

接口说明

输入

输出

功能说明

显示生成的方块

运行环境

运行于VC++6.0编程坏境之下

调用关系

调用模块

确定坐标、颜色设定、判断落地、判断是否落地、坐标更新、设置光标位置

被调用模块

模块6:判断左右界限

名  称

判断左右界限

标识

JudgeWall

系统名称

俄罗斯方块

接口说明

输入

输出

功能说明

判断左右界限

运行环境

运行于VC++6.0编程坏境之下

调用关系

调用模块

被调用模块

模块7:设置光标位置

名  称

设置光标位置

标识

MoveCursor

系统名称

俄罗斯方块

接口说明

输入

输出

功能说明

设置光标位置

运行环境

运行于VC++6.0编程坏境之下

调用关系

调用模块

被调用模块

模块8:颜色设定

名  称

颜色设定

标识

SetColour

系统名称

俄罗斯方块

接口说明

输入

输出

功能说明

确定下一个方块颜色

运行环境

运行于VC++6.0编程坏境之下

调用关系

调用模块

被调用模块

模块9:判断落地

名  称

判断落地

标识

JudgeGroud

系统名称

俄罗斯方块

接口说明

输入

输出

功能说明

判断是接触到方块或界面底边

运行环境

运行于VC++6.0编程坏境之下

调用关系

调用模块

被调用模块

模块10:判断整行是否填满

名  称

判断整行是否填满

标识

JudgeEntire

系统名称

俄罗斯方块

接口说明

输入

输出

功能说明

判读是否有整行被填满,若填满则清除行

运行环境

运行于VC++6.0编程坏境之下

调用关系

调用模块

被调用模块

模块11:显示信息

名  称

显示信息

标识

show

系统名称

俄罗斯方块

接口说明

输入

输出

功能说明

显示得分和下一个方块

运行环境

运行于VC++6.0编程坏境之下

调用关系

调用模块

设置光标位置

被调用模块

模块12:信息更新

名  称

信息更新

标识

Location

系统名称

俄罗斯方块

接口说明

输入

输出

功能说明

更新坐标和界面

运行环境

运行于VC++6.0编程坏境之下

调用关系

调用模块

设置光标位置

被调用模块

四、详细设计

4.1 系统主要函数说明   

函数名称

函数功能

DeawMap

绘制游戏地图

Tetris*BlockRand

确定下一个方块的类型

JudgeDirection

控制方块

Form

确定方块坐标

ShowBlock

显示生成的方块

JudgeWall

判断左右界限

MoveCursor

设置光标位置

SetColour

确定下一个方块颜色

JudgeGroud

判断是接触到方块或界面底边

JudgeEntire

判读是否有整行被填满

Show

显示得分和下一个方块

Location

更新坐标和界面

4.1.1 函数DeawMap

【功能】

绘制游戏地图

【参数】

【返回值】

【算法描述】

设置i,j两个整型变量,再通过for循环控制打印次数、内容及位置,绘制地图。

4.1.2 函数Tetris*BlockRand

【功能】

确定下一个方块的类型

【参数】

【返回值】

【算法描述】

用指针确定方块的类型及初始位置。

4.1.3 函数JudgeDirection

【功能】

控制方块

【参数】

【返回值】

【算法描述】

用if条件语句判断按键,实现不同按键对应的功能。

4.1.4 函数Form

【功能】

确定方块坐标

【参数】

【返回值】

【算法描述】

用Switch语句判断方块类型,在用if语句判断形态,并调用Location函数更新坐标。

4.1.5 函数ShowBlock

【功能】

显示生成的方块

【参数】

【返回值】

【算法描述】

调用JudgeDirection函数控制方块,用指针更新坐标、颜色信息,并调用MoveCursor函数更新光标位置,以及用if语句调用JudgeGroud函数判断是否到底面,最后调用JudgeEntire函数判断是否有整行被填满。

4.1.6 函数JudgeWall

【功能】

判断左右界限

【参数】

【返回值】

【算法描述】

用if条件语句判断当前方块坐标是否等于地图左右边界。

4.1.7 函数MoveCursor

【功能】

设置光标位置

【参数】

【返回值】

【算法描述】

用HANDLE output、GetStdHandle()获取标准输出的句柄,再用SetConsole CursorPosition()设置控制台光标位置。

4.1.8 函数SetColour

【功能】

确定方块颜色

【参数】

【返回值】

【算法描述】

用SetConsoleTextAttribute()控制方块颜色。

4.1.9 函数JudgeGroud

【功能】

判断是接触到方块或界面底边

【参数】

【返回值】

【算法描述】

用指针获取当前方块坐标,再用数个if语句判断是否到达底层,若到达底层则直接进行下一循环。

4.1.10 函数JudgeEntire

【功能】

判读是否有整行被填满

【参数】

【返回值】

【算法描述】

用if语句判断是否有整行被填满,若有整行被填满,则清除行,并调用Show更新得分。

4.1.11 函数Show

【功能】

在地图右上方显示得分和预览下一个方块

【参数】

【返回值】

【算法描述】

先用for循环二重嵌套调用MoveCursor清空显示区域,再用if语句判断新方块类型,将其打印在显示区域。

4.1.12 函数Location

【功能】

若填满则清除行

【参数】

【返回值】

【算法描述】

用指针更新坐标。

五、系统测试

5.1 初始界面

输出方块到顶部,显示下一个方块及得分

图 2 输出方块到顶部

5.2 控制方块

图 3 控制方块_初始位置

控制方块向左

图 4 控制方块_向左

控制方块向右

图 5 控制方块_向右

5.3 控制方块旋转

图 6 方块初始形态

图 7 方块旋转后形态

六、程序设计 

#include<stdio.h>
#include<time.h>
#include<Windows.h>

#define HEIGHT  28  //设置地图高度
#define WIDTH   20  //设置地图宽度
#define ZERO    1
#define HEIGHT_1 18
#define Loca_y    6
#define Loca_x    25
#define PRINTF  printf("■");
#define LINE    printf("\n");
#define EMPTY   printf("  ");

typedef struct Tetris
{
 int x_1, y_1;   //主x坐标,主y坐标,下面三个为附属,通过主坐标确定三个附属
 int x_2, y_2;
 int x_3, y_3;
 int x_4, y_4;
 int code;//7种方块形态代号
 Tetris * next;
}Tetris;

void DeawMap();                     	                 //绘制地图 
Tetris * BlockRand(int code);    	 	                 //随机主方块生成  
void JudgeDirection(Tetris ** Block);                    //按键响应 
void Form(Tetris ** Block);      	                     //方块坐标全部确定
void ShowBlock(Tetris ** Block);                      	 //显示完整方块 
int JudgeWall(Tetris ** Block);                      	 //判断左右界限
void MoveCursor(int x, int y);                       	 //移动光标  不闪屏是因为每次不会刷新全部地图,只会刷新某一特定区域
void SetColour(int c);                               	 //颜色设定
int JudgeGroud(Tetris * Phead, Tetris ** Block);         //判断落地
void JudgeEntire(Tetris * Head);    	                 //判断整行是否填满
void NewEntire(Tetris * head, int y);                    //若上面函数成立,若清除该行,并刷新地图
void Show(int n);        			                     //显示信息,下一个方块得分情况
void Location(Tetris ** Block, int x, int y, int a, int b, int c, int d, int e, int f);   //坐标更新1
void Location_y(Tetris ** Block, int x, int y, int a, int b, int c, int d, int e, int f); //坐标更新2
void Location_x(int x, int y, int a, int b, int c, int d, int e, int f);                  //信息更新
Tetris *Phead = NULL;   //链表头指针
Tetris *Pend = NULL;    //跟随指针 (尾插法需要)
Tetris * Return = NULL; //节点地址返回
int form = 0; //判断形态
int UP = 0;   //下降速度判断
int code_y = 0;//随机形态
int fengs = 220; //得分

int main()
{
 DeawMap();
 code_y = rand() % 7 + 1;
 while (1)
 {
  Return = BlockRand(code_y);
  code_y = rand() % 7 + 1;
  Show(code_y);
  ShowBlock(&Return);
 }
 system("pause>nul");
 return 0;
}

void DeawMap()  //绘制地图
{
 for (int i = 0; i < WIDTH; i++)PRINTF LINE  //上边框
  for (int i = 1; i < HEIGHT - 1; i++)          //打印左右边框
  {
   for (int j = 0; j < WIDTH; j++)
   {
    if (j == 0 || j == WIDTH - 1)
    {
     PRINTF
      if (j == WIDTH - 1)LINE
    }
    else EMPTY
   }
  }
 for (int i = 0; i < WIDTH; i++)PRINTF LINE  //下边框
 system("color 03");
}

void Location(Tetris ** Block, int x, int y, int a, int b, int c, int d, int e, int f)//坐标更新1
{
 (*Block)->x_1 = (*Block)->x_1 + x;
 (*Block)->y_1 = (*Block)->y_1 + y;
 (*Block)->x_2 = (*Block)->x_1 + a;
 (*Block)->y_2 = (*Block)->y_1 + b;
 (*Block)->x_3 = (*Block)->x_1 + c;
 (*Block)->y_3 = (*Block)->y_1 + d;
 (*Block)->x_4 = (*Block)->x_1 + e;
 (*Block)->y_4 = (*Block)->y_1 + f;
}

void Location_y(Tetris ** Block, int x, int y, int a, int b, int c, int d, int e, int f)//坐标更新2
{
 (*Block)->x_1 = (*Block)->x_1 + x;
 (*Block)->y_1 = (*Block)->y_1 + y;
 (*Block)->x_2 = (*Block)->x_2 + a;
 (*Block)->y_2 = (*Block)->y_2 + b;
 (*Block)->x_3 = (*Block)->x_3 + c;
 (*Block)->y_3 = (*Block)->y_3 + d;
 (*Block)->x_4 = (*Block)->x_4 + e;
 (*Block)->y_4 = (*Block)->y_4 + f;
}

Tetris * BlockRand(int code_y)  //随机主方块生成
{
 srand((int)time(0));
 Tetris * Block = (Tetris*)malloc(sizeof(Tetris));
 Block->x_1 = 8;
 Block->y_1 = 4;//规定初始中心方块的坐标为(8,4)
 Block->code = code_y;
 if (Phead == NULL)Phead = Block;
 else Pend->next = Block;
 Block->next = NULL;
 Pend = Block;
 return Block;
}

void ShowBlock(Tetris ** Block)  //显示完整方块 
{
 while (1)
 {

  Form(&Return); 
  if ((*Block)->code == 1)SetColour(13);
  if ((*Block)->code == 2)SetColour(15);
  if ((*Block)->code == 3)SetColour(12);
  if ((*Block)->code == 4)SetColour(10);
  if ((*Block)->code == 5)SetColour(6);
  if ((*Block)->code == 6)SetColour(4);
  if ((*Block)->code == 7)SetColour(8);
  MoveCursor((*Block)->x_1, (*Block)->y_1); PRINTF
  MoveCursor((*Block)->x_2, (*Block)->y_2); PRINTF
  MoveCursor((*Block)->x_3, (*Block)->y_3); PRINTF
  MoveCursor((*Block)->x_4, (*Block)->y_4); PRINTF
  if (JudgeGroud(Phead, &Return) == 0)
  {
   system("color 03");
   break;
  }
  if (UP == 0)
  {
   for (int i = 0; i <= 400000000; i++) {}
  }
  if (UP == 1)
  {
   for (int i = 0; i <= 40000000; i++) {}
   UP = 0;
  }
  MoveCursor((*Block)->x_1, (*Block)->y_1); EMPTY
  MoveCursor((*Block)->x_2, (*Block)->y_2); EMPTY
  MoveCursor((*Block)->x_3, (*Block)->y_3); EMPTY
  MoveCursor((*Block)->x_4, (*Block)->y_4); EMPTY
  Location_y(&Return, 0, 1, 0, 1, 0, 1, 0, 1);
  JudgeDirection(&Return);
  JudgeEntire(Phead);
 }
}

void JudgeDirection(Tetris ** Block)    //按键响应
{
 if (GetAsyncKeyState(VK_UP) && 0x8000)
 {
  form += 1;
  if (form == 4)
  {
   form = 0;
  }
  Form(&Return);
 }
 if (GetAsyncKeyState(VK_DOWN) && 0x8000)
 {
  //加速向下  时间加速
  UP = 1;
 }
 if (GetAsyncKeyState(VK_LEFT) && 0x8000)
 {
  //向左移动
  if (JudgeWall(&Return) != -1) Location_y(&Return, -1, 0, -1, 0, -1, 0, -1, 0);
 }
 if (GetAsyncKeyState(VK_RIGHT) && 0x8000)
 {
  //向右移动
  if (JudgeWall(&Return) != -2) Location_y(&Return, 1, 0, 1, 0, 1, 0, 1, 0);
 }
 if (GetAsyncKeyState(VK_ESCAPE) && 0x0D)
 {
  MoveCursor(27, 15);
  printf("游戏暂停");
  //判断Esc
  while (1)
  {
   if (GetAsyncKeyState(VK_ESCAPE) && 0x0D)
   {
    MoveCursor(27, 15);
    printf("       ");
    break;
   }
  }
 }
}

void Form(Tetris ** Block)  //方块坐标全部确定
{
 //先确实哪一类,再细分
 switch ((*Block)->code)
 {
 case 1:
  if (form == 0)Location(&Return, 0, 0, -1, 0, 0, -1, 1, 0);
  if (form == 1)Location(&Return, 0, 0, 0, 1, 0, -1, 1, 0);
  if (form == 2)Location(&Return, 0, 0, 0, 1, -1, 0, 1, 0);
  if (form == 3)Location(&Return, 0, 0, 0, 1, -1, 0, 0, -1);
  break;
 case 2:
  Location(&Return, 0, 0, 1, 0, 0, 1, 1, 1);
  break;
 case 3:
  if (form == 0 || form == 2)Location(&Return, 0, 0, 0, -1, 0, 1, 0, 2);
  if (form == 1 || form == 3)Location(&Return, 0, 0, -1, 0, 1, 0, 2, 0);
  break;
 case 4:
  if (form == 0)Location(&Return, 0, 0, -1, 0, 1, 0, 1, -1);
  if (form == 1)Location(&Return, 0, 0, 0, -1, 1, 0, 0, -2);
  if (form == 2)Location(&Return, 0, 0, 0, -1, 1, -1, 2, -1);
  if (form == 3)Location(&Return, 0, 0, 0, -1, 0, -2, -1, -2);
  break;
 case 5:
  if (form == 0)Location(&Return, 0, 0, 1, 0, 2, 0, 0, -1);
  if (form == 1)Location(&Return, 0, 0, 1, 0, 1, -1, 1, -2);
  if (form == 2)Location(&Return, 0, 0, 1, 0, 2, 0, 2, 1);
  if (form == 3)Location(&Return, 0, 0, 1, 0, 0, 1, 0, 2);
  break;
 case 6:
  if (form == 0 || form == 2)Location(&Return, 0, 0, 0, -1, 1, 0, 1, 1);
  if (form == 1 || form == 3)Location(&Return, 0, 0, 0, -1, 1, -1, -1, 0);
  break;
 case 7:
  if (form == 0 || form == 2)Location(&Return, 0, 0, 0, 1, 1, 0, 1, -1);
  if (form == 1 || form == 3)Location(&Return, 0, 0, 0, 1, -1, 0, 1, 1);
 }
}

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

void SetColour(int c)     //颜色设定
{
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);//API函数可以改变控制台颜色
}

int JudgeWall(Tetris ** Block)     //判断左右界限
{
 if ((*Block)->x_1 == ZERO || (*Block)->x_2 == ZERO || (*Block)->x_3 == ZERO || (*Block)->x_4 == ZERO)return -1;
 if ((*Block)->x_1 == HEIGHT_1 || (*Block)->x_2 == HEIGHT_1 || (*Block)->x_3 == HEIGHT_1 || (*Block)->x_4 == HEIGHT_1)return -2;
 return 0;
}

int JudgeGroud(Tetris * Phead, Tetris ** Block)  //判断落地
{
 
 Tetris * P = Phead;
 //如果到达最低层。直接经行下一循环
 if ((*Block)->y_1 == 26 || (*Block)->y_2 == 26 || (*Block)->y_3 == 26 || (*Block)->y_4 == 26)return 0;
 while (P->next != NULL)
 {
  if (P->y_1 == (*Block)->y_1 + 1)
  {
   if (P->x_1 == (*Block)->x_1)return 0;
  }
  if (P->y_2 == (*Block)->y_1 + 1)
  {
   if (P->x_2 == (*Block)->x_1)return 0;
  }
  if (P->y_3 == (*Block)->y_1 + 1)
  {
   if (P->x_3 == (*Block)->x_1)return 0;
  }
  if (P->y_4 == (*Block)->y_1 + 1)
  {
   if (P->x_4 == (*Block)->x_1)return 0;
  }
  if (P->y_1 == (*Block)->y_2 + 1)
  {
   if (P->x_1 == (*Block)->x_2)return 0;
  }
  if (P->y_2 == (*Block)->y_2 + 1)
  {
   if (P->x_2 == (*Block)->x_2)return 0;
  }
  if (P->y_3 == (*Block)->y_2 + 1)
  {
   if (P->x_3 == (*Block)->x_2)return 0;
  }
  if (P->y_4 == (*Block)->y_2 + 1)
  {
   if (P->x_4 == (*Block)->x_2)return 0;
  }
  if (P->y_1 == (*Block)->y_3 + 1)
  {
   if (P->x_1 == (*Block)->x_3)return 0;
  }
  if (P->y_2 == (*Block)->y_3 + 1)
  {
   if (P->x_2 == (*Block)->x_3)return 0;
  }
  if (P->y_3 == (*Block)->y_3 + 1)
  {
   if (P->x_3 == (*Block)->x_3)return 0;
  }
  if (P->y_4 == (*Block)->y_3 + 1)
  {
   if (P->x_4 == (*Block)->x_3)return 0;
  }
  if (P->y_1 == (*Block)->y_4 + 1)
  {
   if (P->x_1 == (*Block)->x_4)return 0;
  }
  if (P->y_2 == (*Block)->y_4 + 1)
  {
   if (P->x_2 == (*Block)->x_4)return 0;
  }
  if (P->y_3 == (*Block)->y_4 + 1)
  {
   if (P->x_3 == (*Block)->x_4)return 0;
  }
  if (P->y_4 == (*Block)->y_4 + 1)
  {
   if (P->x_4 == (*Block)->x_4)return 0;
  }
  P = P->next;
 }
 return 1;
}

void JudgeEntire(Tetris * Head)      //判断整行是否填满
{
 Tetris * PHead = Head;
 //从1到26
 for (int y = 26; y >= 1; y--)
 {
  int sum = 0;
  while (PHead->next != NULL)
  {
   if (PHead->y_1 == y)sum++;
   if (PHead->y_2 == y)sum++;
   if (PHead->y_3 == y)sum++;
   if (PHead->y_4 == y)sum++;
   MoveCursor(20, 28);
   PHead = PHead->next;
  }
  PHead = Head;
  if (sum == 18)
  {
  //如果成行则,执行NewEntire()  清空该行,并将所有y下降一个单位。
   NewEntire(Phead, y);
   fengs += 10;
   Show(code_y);
  }
  sum = 0;
 }
}

void NewEntire(Tetris * head,int y)  //若上面函数成立,若清除该行,并刷新地图
{
 Tetris * PHead = head;
 while (PHead->next != NULL)
 {
  if (PHead->y_1 == y)
  {
   MoveCursor(PHead->x_1, PHead->y_1); EMPTY
   PHead->x_1 = 99;
   PHead->y_1 = 99;
  }
  if (PHead->y_2 == y)
  {
   MoveCursor(PHead->x_2, PHead->y_2); EMPTY
   PHead->x_2 = 99;
   PHead->y_2 = 99;
  }
  if (PHead->y_3 == y)
  {
   MoveCursor(PHead->x_3, PHead->y_3); EMPTY
   PHead->x_3 = 99;
   PHead->y_3 = 99;
  }
  if (PHead->y_4 == y)
  {
   MoveCursor(PHead->x_4, PHead->y_4); EMPTY
   PHead->x_4 = 99;
   PHead->y_4 = 99;
  }
  PHead = PHead->next;
 }
 PHead = head;
 while (PHead->next != NULL)
 {
  if (PHead->y_1 < y)
  {
   MoveCursor(PHead->x_1, PHead->y_1); EMPTY
   PHead->y_1 += 1;
   MoveCursor(PHead->x_1, PHead->y_1); PRINTF
  }
  if (PHead->y_2 < y)
  {
   MoveCursor(PHead->x_2, PHead->y_2); EMPTY
   PHead->y_2 += 1;
   MoveCursor(PHead->x_2, PHead->y_2); PRINTF
  }
  if (PHead->y_3 < y)
  {
   MoveCursor(PHead->x_3, PHead->y_3); EMPTY
   PHead->y_3 += 1;
   MoveCursor(PHead->x_3, PHead->y_3); PRINTF
  }
  if (PHead->y_4 < y)
  {
   MoveCursor(PHead->x_4, PHead->y_4); EMPTY
   PHead->y_4 += 1;
   MoveCursor(PHead->x_4, PHead->y_4); PRINTF
  }
  PHead = PHead->next;
 }
}

void Show(int n)     //显示信息,下一个方块得分情况,如果想加入一些信息可以在该函数内修改
{
 //显示下一个方块
 //先清空该区域
for (int j = 4; j <= 8; j++)
 {
  for (int i = 23; i <= 28; i++)
  {
   MoveCursor(i, j);  EMPTY
  }
 }
 MoveCursor(24, 3); 
 printf("下一个方块种类:");
 MoveCursor(24, 10);
 printf("游戏得分:%d", fengs);
 MoveCursor(24, 12);
 if (n == 1)
 {
  SetColour(13);
  Location_x(-1, 0, 0, 0, 1, 0, -1, -1);
 }
 if (n == 2)
 {
  SetColour(15);
  Location_x(0, 0, 1, 0, -1, 1, 1, 1);
 }
 if (n == 3)
 {
  SetColour(12);
  Location_x(0, 0, 1, 0, 2, 0, 3, 0);
 }
 if (n == 4)
 {
  SetColour(10);
  Location_x(0, 0, 1, 0, 2, 0, 2, -1);
 }
 if (n == 5)
 {
  SetColour(6);
  Location_x(0, -1, 0, 0, 1, 0, 2, 0);
 }
 if (n == 6)
 {
  SetColour(4);
  Location_x(-1, -1, -1, 0, 0, 0, 0, 1);
 }
 if (n == 7)
 {
  SetColour(8);
  Location_x(0, -1, 0, 0, -1, 0, -1, 1);
 }
}

void Location_x(int x, int y, int a, int b, int c, int d, int e, int f)    //信息更新
{
	MoveCursor(Loca_x+x, Loca_y+y); PRINTF
	MoveCursor(Loca_x+a, Loca_y+b); PRINTF
	MoveCursor(Loca_x+c, Loca_y+d); PRINTF
	MoveCursor(Loca_x+e, Loca_y+f); PRINTF
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1382300.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【WPF.NET开发】流文档

本文内容 什么是流文档&#xff1f;流文档类型创建流内容与流相关的类内容架构自定义文本 流文档旨在优化查看和可读性。 流文档根据运行时变量&#xff08;例如&#xff0c;窗口大小、设备分辨率和可选的用户首选项&#xff09;来动态调整和重新排列内容&#xff0c;而不是设…

python入门,数据容器:set集合

set最大的特点就是不支持重复元素&#xff0c;可以进行元素的去重处理&#xff0c;但不有序&#xff0c;不保证元素顺序正确 所以就不能使用下标索引的访问 1.集合的定义 集合的定义使用的是大括号{ } 对ok这个字符串进行了去重 2.add添加新元素 3.remove移除元素 4.pop随机…

redis(14):缓存雪崩、击穿、穿透及其处理方式

1 Redis 缓存过程 通常后端会采用Mysql等磁盘数据库,可以持久化但是访问慢,高并发时性能差,需要设置Nosql内存型数据库缓存:Redis等; Redis 数据库运行在内存中,因此他的查询速度比 MySql 快的多。所以我们会把一些用户经常查询的数据放在 Redis 中,当 Redis 有的时候…

简单高效 LaTeX 科学排版 第004集 命令与环境

这是《简单高效LaTeX》的第四个视频&#xff0c;主要演示讨论基本命令与排版环境&#xff0c;还有保留字符。 视频地址&#xff1a;https://www.ixigua.com/7298100920137548288?id7298102807985390120&logTagf853f23a668f8a2ee405

将 OpenCV Java 与 Eclipse 结合使用

配置 Eclipse 首先&#xff0c;从下载页面获取 OpenCV 的新版本&#xff0c;并将其解压缩到一个简单的位置&#xff0c;例如 .我使用的是 2.4.6 版&#xff0c;但其他版本的步骤或多或少相同。C:\OpenCV-2.4.6\ 现在&#xff0c;我们将 OpenCV 定义为 Eclipse 中的用户库&…

美颜技术详解:美颜SDK与直播平台集成

如今&#xff0c;美颜技术成为了吸引用户的一项重要功能。本篇文章&#xff0c;小编将深入讲解美颜技术&#xff0c;重点关注美颜SDK的原理以及如何将其无缝集成到直播平台中&#xff0c;为用户提供更加优质的视觉体验。 一、美颜技术概述 美颜技术的应用范围广泛&#xff0c…

DrissionPage获取浏览器Network数据包

DrissionPage是什么&#xff1f; GitHub - g1879/DrissionPage: 基于python的网页自动化工具。既能控制浏览器&#xff0c;也能收发数据包。可兼顾浏览器自动化的便利性和requests的高效率。功能强大&#xff0c;内置无数人性化设计和便捷功能。语法简洁而优雅&#xff0c;代码…

【C++入门到精通】智能指针 [ C++入门 ]

阅读导航 引言一、什么是智能指针二、为什么需要智能指针三、内存泄漏1. 什么是内存泄漏&#xff0c;内存泄漏的危害2. 内存泄漏的示例&#xff0c;以及解决方法3. 内存泄漏分类&#xff08;1&#xff09;堆内存泄漏(Heap leak)&#xff08;2&#xff09;系统资源泄漏 4. 如何检…

Nginx配置动静分离实例(Nginx处理静态资源)

Nginx动静分离概述 Nginx 动静分离是指动态请求跟静态请求分开&#xff0c;可以理解为使用Nginx处理静态页面&#xff08;包含静态资源文件&#xff09;&#xff0c;Tomcat处理动态页面&#xff1b; 提醒一下&#xff1a;下面实例讲解是在Mac系统演示的&#xff1b; 两个方式…

恢复 iPhone 和 iPad 数据的 10 个好工具 - [苹果数据恢复]

它发生了.. 有时您需要从您的手机或平板设备恢复重要数据。 许多人已经开始将重要文件存储在手机上&#xff0c;因为他们几乎可以在任何情况下随时随地轻松访问数据。 不言而喻; 您可以轻松访问您的电子邮件、共享图片、编辑和共享文档、支付账单等等&#xff0c;只需在您的手…

【k8s】Kubernetes 声明式 API、命令式

1. 资源管理方式&#xff1a; 1>. 命令式对象管理∶直接使用命令去操作kubernetes资源 kubectl run nginx-pod --imagenginx:1.17.1 --port802>. 命令式对象配置∶通过命令配置和配置文件去操作kubernetes资源 kubectl create/patch -f nginx-pod.yaml3>. 声明式对…

win10重新安装Windows应用商店

安装Windows 终端 用 PowerShell 重装 Microsoft Store使用 MSIX 包重装 Microsoft Store下载安装包及依赖下载Windows 应用商店的安装包安装包是依赖组件包 微软应用商店无法连接网络解决办法 参考&#xff1a; wind10自带的终端程序和powerShell 真是太垃圾了&#xff0c; 突…

简单高效LaTeX 科学排版 第005集 导言区和文档输出

导言区是LaTeX文档的前导重要部分&#xff0c;这个视频讨论了建立导言区的方法&#xff0c;并且讨论了LaTeX文档的输出。 视频链接&#xff1a;https://www.ixigua.com/7298100920137548288?id7303715340075139622&logTag6eb24f453fe9fe617a61

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《与新能源互补和独立参加多级市场的抽蓄电站容量分配策略》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 这个标题涉及到抽蓄电站在能源系统中的角色&#xff0c;特别是在多级市场中的参与&#xff0c;并强调了新能源的互补性以及抽蓄电站的独立性。下面我将…

领域驱动设计应用之WebAPI

领域驱动设计应用之WebAPI 此篇文章主要讲述领域驱动设计在WebApi中的应用&#xff0c;以及设计方式&#xff0c;这种设计的原理以及有点。 文章目录 领域驱动设计应用之WebAPI前言一、相对于传统设计模式的有点二、WebAPI对接中的使用案例业务拆分父类设计HttpResponse(返回)…

计算机三级(网络技术)一综合题(IP地址计算)

例题一 &#xff08;正常算&#xff09; 计算并填写下表 地址类别 A类地址段是1.0.0.0~127.255.255.255 1~127 B类地址段是128.0.0.0~191.255.255.255 128~191 C类地址段是192.0.0.0~223.255.255.255 192~223 所以41填A 网络地址为主机位全0 根据子网掩码&…

计算机网络安全教程(第三版)课后简答题答案大全[6-12章]

目录 第 6 章 网络后门与网络隐身 第 7 章 恶意代码分析与防治 第 8 章 操作系统安全基础 第 9 章 密码学与信息加密 第 10 章 防火墙与入侵检测 第 11 章 IP安全与Web安全 第 12 章 网络安全方案设计 链接&#xff1a;计算机网络安全教程(第三版)课后简答题答案大全[1-5…

Spark---RDD序列化

文章目录 1 什么是序列化2.RDD中的闭包检查3.Kryo 序列化框架 1 什么是序列化 序列化是指 将对象的状态信息转换为可以存储或传输的形式的过程。 在序列化期间&#xff0c;对象将其当前状态写入到临时或持久性存储区。以后&#xff0c;可以通过从存储区中读取或反序列化对象的…

web前端算法简介之链表

链表 链表 VS 数组链表类型链表基本操作 创建链表&#xff1a;插入操作&#xff1a;删除操作&#xff1a;查找操作&#xff1a;显示/打印链表&#xff1a;反转链表&#xff1a;合并两个有序链表&#xff1a;链表基本操作示例 JavaScript中&#xff0c;instanceof环形链表 判断…

重学Java 4 进制转换和位运算

天赋不好好使用的话&#xff0c;可是会被收回的哦 ——24.1.13 一、进制转换 1.常用的进制 2.十进制和二进制之间的转换 1.十进制转二进制 辗转相除法——循环除以2&#xff0c;取余数&#xff0c;除到商为0为止&#xff0c;除完后&#xff0c;由下往上&#xff0c;得出换算后…