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

目录

一、前言

二、需求分析

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){PRINTFif (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); PRINTFMoveCursor((*Block)->x_2, (*Block)->y_2); PRINTFMoveCursor((*Block)->x_3, (*Block)->y_3); PRINTFMoveCursor((*Block)->x_4, (*Block)->y_4); PRINTFif (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); EMPTYMoveCursor((*Block)->x_2, (*Block)->y_2); EMPTYMoveCursor((*Block)->x_3, (*Block)->y_3); EMPTYMoveCursor((*Block)->x_4, (*Block)->y_4); EMPTYLocation_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("游戏暂停");//判断Escwhile (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到26for (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); EMPTYPHead->x_1 = 99;PHead->y_1 = 99;}if (PHead->y_2 == y){MoveCursor(PHead->x_2, PHead->y_2); EMPTYPHead->x_2 = 99;PHead->y_2 = 99;}if (PHead->y_3 == y){MoveCursor(PHead->x_3, PHead->y_3); EMPTYPHead->x_3 = 99;PHead->y_3 = 99;}if (PHead->y_4 == y){MoveCursor(PHead->x_4, PHead->y_4); EMPTYPHead->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); EMPTYPHead->y_1 += 1;MoveCursor(PHead->x_1, PHead->y_1); PRINTF}if (PHead->y_2 < y){MoveCursor(PHead->x_2, PHead->y_2); EMPTYPHead->y_2 += 1;MoveCursor(PHead->x_2, PHead->y_2); PRINTF}if (PHead->y_3 < y){MoveCursor(PHead->x_3, PHead->y_3); EMPTYPHead->y_3 += 1;MoveCursor(PHead->x_3, PHead->y_3); PRINTF}if (PHead->y_4 < y){MoveCursor(PHead->x_4, PHead->y_4); EMPTYPHead->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); PRINTFMoveCursor(Loca_x+a, Loca_y+b); PRINTFMoveCursor(Loca_x+c, Loca_y+d); PRINTFMoveCursor(Loca_x+e, Loca_y+f); PRINTF
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql进阶-重构表

目录 1. 原因 2. 如何重构表呢&#xff1f; 2.1 命令1&#xff1a; 2.2 命令2&#xff1a; 2.3 命令3&#xff1a; 1. 原因 正常的业务开发&#xff0c;为什么需要重构表呢&#xff1f; 原因1&#xff1a;某张表存在大量的新增和删除操作&#xff0c;导致表经历过大量的…

4.MapReduce 序列化

目录 概述序列化序列化反序例化java自带的两种Serializable非Serializable hadoop序例化实践 分片/InputFormat & InputSplit日志 结束 概述 序列化是分布式计算中很重要的一环境&#xff0c;好的序列化方式&#xff0c;可以大大减少分布式计算中&#xff0c;网络传输的数…

《向量数据库指南》让「引用」为 RAG 机器人回答增加可信度

在之前的文章中&#xff0c;我们已经介绍了如何用 Milvus 向量数据库以及 LlamaIndex 搭建基础的聊天机器人《Chat Towards Data Science &#xff5c;如何用个人数据知识库构建 RAG 聊天机器人&#xff1f;》《书接上回&#xff0c;如何用 LlamaIndex 搭建聊天机器人&#xff…

FlinkCDC的分析和应用代码

前言&#xff1a;原本想讲如何基于Flink实现定制化计算引擎的开发&#xff0c;并以FlinkCDC为例介绍&#xff1b;发现这两个在表达上不知以谁为主&#xff0c;所以先分析FlinkCDC的应用场景和技术实现原理&#xff0c;下一篇再去分析Flink能在哪些方面&#xff0c;做定制化计算…

个人网站制作 Part 4 添加响应式设计 | Web开发项目

文章目录 &#x1f469;‍&#x1f4bb; 基础Web开发练手项目系列&#xff1a;个人网站制作&#x1f680; 添加响应式设计&#x1f528;移动优先的响应式样式&#x1f527;步骤 1: 添加媒体查询 &#x1f528;图片和布局调整&#x1f527;步骤 2: 使用响应式图片&#x1f527;步…

vue3-计算属性

计算属性 模板中的表达式虽然方便&#xff0c;但也只能用来做简单的操作。如果在模板中写太多逻辑&#xff0c;会让模板变得臃肿&#xff0c;难以维护。 根据作者今年是否看过书展示不同信息 <script lang"ts" setup> import { ref, reactive } from "…

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

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

Spring Boot 整合支付宝实现在线支付方案(沙箱环境)

文章目录 1.理解沙箱环境2.沙箱环境接入准备2.1 访问开发者控制台2.2 获取重要信息2.3 处理秘钥 3.接入支付宝支付的流程4.实现支付4.1 添加 SDK 依赖4.2 创建配置类4.3 支付宝订单管理接口实现流程4.4 支付宝支付接口实现流程 5.支付宝支付功能演示7.总结 TIP&#xff1a;对于…

网络协议与攻击模拟_04ICMP协议与ICMP重定向

ICMP协议是网络层协议&#xff0c; 利用ICMP协议可以实现网络中监听服务和拒绝服务&#xff0c;如 ICMP重定向的攻击。 一、ICMP基本概念 1、ICMP协议 ICMP是Internet控制报文协议&#xff0c;用于在IP主机、路由器之间传递控制消息&#xff0c;控制消息指网络通不通、主机是…

Git LFS 大文件存储

Git 碰到大文件的困境 Git 是业界流行的分布式版本控制工具&#xff0c;本地仓库与远端仓库同样保存了全量的文件和变更历史&#xff0c;这样让代码协作变得简单和高效。但也正因为如此&#xff0c;Git针对大型文件&#xff08;例如图片、视频或其他二进制文件&#xff09;的版…

序章 熟悉战场篇—了解vue的基本操作

了解vue 的基本目录&#xff1a; dist 是打包后存放的目录(后续可以改)node_modules 是依赖包public 是静态index页面src 是存放文件的目录assets 是存放静态资源的目录components 是存放组件的目录views 是存放页面文件的目录&#xff08;没有views 自己新建一个&#xff09;A…

Jetpack Compose -> 声明式UI Modifier

前言 本章主要介绍下 Compose 的声明式 UI 以及初级写法&#xff1b; 什么是声明式UI 传统UI 传统 UI 方式来声明UI <androidx.appcompat.widget.LinearLayoutCompat android:layout_width"match_parent" android:layout_height"match_parent&quo…

YOLOv5改进 | 二次创新篇 | 结合iRMB和EMA形成全新的iEMA机制(全网独家创新)

一、本文介绍 本文给大家带来的改进机制是二次创新的机制,二次创新是我们发表论文中关键的一环,为什么这么说,从去年的三月份开始对于图像领域的论文发表其实是变难的了,在那之前大家可能搭搭积木的情况下就可以简单的发表一篇论文,但是从去年开始单纯的搭积木其实发表论…

C# 图解教程 第5版 —— 第24章 预处理指令

文章目录 24.1 什么是预处理指令24.2 基本规则24.3 符号指令&#xff08;#define、#undef &#xff09;24.4 条件编译&#xff08;#if、#else、#elif、#endif&#xff09;24.5 条件编译结构24.6 诊断指令&#xff08;#warning、#error&#xff09;24.7 行号指令&#xff08;#li…

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

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

Sqoop的增量数据加载策略与示例

当使用Apache Sqoop进行数据加载时&#xff0c;增量数据加载策略是一个关键的话题。增量加载可以仅导入发生变化的数据&#xff0c;而不必每次都导入整个数据集&#xff0c;这可以显著提高任务的效率。本文将深入探讨Sqoop的增量数据加载策略&#xff0c;提供详细的示例代码&am…

大语言模型面试问题

自己在看面经中遇到的一些面试题&#xff0c;结合自己和理解进行了一下整理。 transformer中求和与归一化中“求和”是什么意思&#xff1f; 求和的意思就是残差层求和&#xff0c;原本的等式为y H(x)转化为y x H(x)&#xff0c;这样做的目的是防止网络层数的加深而造成的梯…

管理软件供应链中网络安全工具蔓延的三种方法

软件开发组织不断发展&#xff0c;团队成长&#xff0c;项目数量增加。技术堆栈发生变化&#xff0c;技术和管理决策变得更加分散。 在这一演变过程中&#xff0c;该组织的 AppSec 工具组合也在不断增长。在动态组织中&#xff0c;这可能会导致“工具蔓延”。庞大的 AppSec 工…

Java--RSA非对称加密的实现(使用java.security.KeyPair)

文章目录 前言实现步骤测试结果 前言 非对称加密是指使用不同的两个密钥进行加密和解密的一种加密算法&#xff0c;调用方用使用服务方提供的公钥进行加密&#xff0c;服务方使用自己的私钥进行解密。RSA算法是目前使用最广泛的公钥密码算法。Java提供了KeyPairGenerator类要生…

2024年AMC8模拟考试实测流程、注意事项和常见问题

和往年的AMC8比赛一样&#xff0c;在正式比赛的前一周左右会开放两天的模拟考试时间&#xff0c;AMC8的主办方建议所有的参赛选手重视且参加模拟考试&#xff0c;以测试设备、熟悉流程&#xff0c;避免将来正式考试不小心违规&#xff0c;或者设备不给力。 2024年的AMC8模拟考…