C语言:原神角色UP池祈愿模拟器

【创作灵感】

看到原神BWiki里有抽卡模拟器,便自己根据游戏内的描述用C语言编写了一个简单的模拟器,供参考使用。

作者注:

  • 普通C语言编程是没有图形化界面的,只看见原神两个字就点进来的请不要随便喷。
  • 因为三星、四星物品实在过多,对于这两种星级,程序只分4星角色、4星物品、3星这三类,不具体到名称,不然会导致程序代码大大增长且无实际意义。
  • 免费下载链接:C语言:原神角色UP池祈愿模拟器

目录

一、背景与描述

二、模块及介绍

1.祈愿基础概率的模拟

2.祈愿保底的模拟

3.历史记录的书写

4.历史记录页面实现翻页

5.修改已经抽取的数量

三、运行与展示

1.运行主界面

2.单抽

3.十连抽

4.查看历史纪录

5.修改垫抽数量

6.1 完整运行(单抽)

6.2 完整运行(十连抽)

四、代码与注释


一、背景与描述

原神BWiki里的抽卡模拟器:原神BWiki模拟器传送门

以4.2版本下半期UP祈愿-1为例:

对于这期UP池,我们有以下五星列表:

同时我们还要注意到以下这句话:

二、模块及介绍

1.祈愿基础概率的模拟

从上面图中我们可以得到小数点位数最多的就是概率为0.0255的4星武器和4星角色,也就是255/10000,为便于理解与阅读,这里我们不进行约分。

我们可以利用1-10000的一万个数字作为随机数生成的范围,让1-60为5星角色,61-315为4星角色(或物品),316-570为4星物品(或角色),剩下的就是3星物品与角色。这样处理就行了。

简单点描述就是:

srand(unsigned int)time(NULL));
int NumberCode = rand()%10000 + 1;
if (NumberCode >=1 && NumberCode <= 60) printf("这是5星角色");
    else if (NumberCode >=61 && NumberCode <= 315) printf("这是4星角色");
        else if (NumberCode >=316 && NumberCode <= 570) printf("这是4星物品");
            else printf("这是3星角色/物品");

2.祈愿保底的模拟

我们知道游戏中大保底为180次,即必中UP角色;小保底为90次,必定出五星角色,其中50%概率为UP角色。同时我们也知道每抽取10次必定出一个四星物品或角色,而且一旦出了抽到UP的情况,那么之前的抽取次数就会清空作废。

那么也就相当于N计数,每抽取一次就N++。当N为10的整数倍的时候就有保底。这个就没必要单独列出代码了。

3.历史记录的书写

这里的历史记录采用了类似于栈的结构,但也只是类似。这里就是把之前抽取的往后移,每个都往后移动一个位置,让出一个位置来写入新的记录。用代码简单表示就是:

char History[200][100];//200个储存空间
int N = 20;//已经存了20条
for (int i = N; i > 0; i--)
    strcpy(History[i], History[i - 1]);
strcpy(History[0], "这里是新的抽卡记录(一条)");

4.历史记录页面实现翻页

为了模仿游戏中的一页五条历史记录,翻页的写法是不可避免的。

首先,根据上面的写法,我们知道History[0]是最近的历史记录,History[N - 1]则为最久的历史记录。所以我们第一页无疑需要从上到下输出History[0]到History[4],以此类推每一页的输出就是:

int page;//由用户决定大小
for (int i = 0;i < 5; i++)
    printf("%s\n",History[(page - 1)*5 + i]);

5.修改已经抽取的数量

这个功能是方便大家根据自己的已垫次数进行模拟。其实只用把SmokedNumber更改就行了。

三、运行与展示

1.运行主界面

2.单抽

3.十连抽

4.查看历史纪录

5.修改垫抽数量

6.1 完整运行(单抽)

受限于gif图时间限制,下图为2.5倍速

6.2 完整运行(十连抽)

受限于gif图时间限制,下图为2.5倍速

四、代码与注释

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <Windows.h>
#include "unistd.h"

///注意,该项目规定输出区域为第三行以后(不包括第三行),前两行用于常驻简介与目前大保底的抽数

#define TimeInterval 25		//预定的动画时间间隔
#define ChangeColor_Purple printf("\033[35m")//将颜色换成紫色
#define ChangeColor_Green_ printf("\033[32m")//将颜色换成绿色
#define ChangeColor_Red___ printf("\033[31m")//将颜色换成红色
#define ChangeColor_Yellow printf("\033[33m")//将颜色换成黄色
#define ChangeColor_Whilt_ printf("\033[0m") //将颜色换成白色
#define ChangeColor_Blue__ printf("\033[36m")//将颜色换成蓝色
#define MoveTheLocation printf("\033[%d;%dH",4,0)//移动光标保证输出位置一样
#define MoveToChangeTheNumber printf("\033[%d;%dH",2,NumberOutput_X)//移动光标保证输出位置一样
#define HideCursor printf("\033[?25l")//隐藏光标
#define ShowCursor printf("\033[?25h")//隐藏光标

int Number_Big = 0;//分别记录目前大保底抽了多少抽,90就是小保底,180是大保底
int N_History = 0;//记录总共可查询的历史记录数量(不一定等于Number_Big)
char UPer_5_Stars[25] = "Furina";	//五星Up角色的名称,此处为芙宁娜
char FiveStars[7][25] = {"Tighnari", "Dehya", "Keqing", "Mona", "Qiqi", "Diluc", "Jean"};
	//分别对应提纳里、迪希雅、刻晴、莫娜、七七、迪卢克、琴
int NumberOutput_X;
char History[500][100];//最多可查询500条历史记录

struct InformationForTenPrayer {//用于储存十连抽的数据,便于排序显示
	int StarNumber;
	char Name[25];
};

void CleanTheScreen(void);
void InputTheOperate();
void Welcome();
void Prayer(char Oper);
void Output(int n, int Cod[10]);
void EditTheSmokedNumber();
void EditShowedSmokedNumber();
void SearchTheHistory();
void History_CleanThePanel();

int main(void)
{
	NumberOutput_X = 1 + strlen(UPer_5_Stars) + 16 + 16 + 14;
	Welcome();//输出欢迎页面与顶部栏

	char CharToContinue;

	do {
		InputTheOperate();

		ChangeColor_Purple; printf("\n>");
		ChangeColor_Green_; printf("Operation completed.Press [Enter] to continue...");//提示用户操作完毕
		ChangeColor_Whilt_;

		CharToContinue = getchar();
		do { CharToContinue = getchar(); } while (CharToContinue != '\n');//持续读取直到输入回车
	} while (1);

	return 0;
}

void InputTheOperate()
{//用于简单介绍如何操作并要求用户输入操作
	///总共A、B、C、D三种操作,分别对应单抽、十连抽、查看历史记录、修改已垫抽数量
	CleanTheScreen();
	ChangeColor_Whilt_; Sleep(25); printf("\n");
	printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
	printf("┃  Please input the Operate you want:                   ┃\n");
	printf("┃   A.Prayer                   B.Prayer * 10            ┃\n");
	printf("┃   C.History                  D.Edit Smoked Number     ┃\n");
	printf("┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫\n");
	printf("┃    Personal blog homepage:\033[36msherrychou.blog.csdn.net    \033[0m┃\n");
	printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
	ChangeColor_Purple; printf(">");
	ChangeColor_Green_; printf("Please input A,B,C or D:");
	ChangeColor_Whilt_;

	char Operate = ' ';//储存用户需要进行的操作
	do { 
		scanf("%c", &Operate); 
		if (!(Operate == 'A' || Operate == 'B' || Operate == 'C' || Operate == 'D'))
		{
			HideCursor; printf("\033[%d;%dH", 12, 26);
			ChangeColor_Whilt_; printf("           ");
			ShowCursor; printf("\033[%d;%dH", 12, 26);
		}
	} while (!(Operate == 'A' || Operate == 'B' || Operate == 'C' || Operate == 'D'));
		//持续读取直到输入A或B或C或D

	switch (Operate)
	{
	case 'A'://单抽
	case 'B'://十连抽
		Prayer(Operate);//并列
		break;

	case 'C'://查看历史记录
		SearchTheHistory();
		break;

	case 'D'://修改垫抽次数
		EditTheSmokedNumber();
		break;
	}
	return;
}

void Prayer(char Oper)
{//进行祈愿并输出的函数
	srand((unsigned int)time(NULL));

	switch (Oper)
	{
	case 'A'://进行单抽
	{
		Number_Big++;
		N_History++;
		int CodeNumber = rand() % 10000 + 1;
		/*对获得物品进行分段
		*1-60为5星角色(0.6%)
		*61-315为4星角色(2.55%)
		*316-570为4星物品(2.55%)
		*剩下的全是3星
		*/
		int Temp_1[1];
		if (Number_Big % 10 != 0)//没有保底的情况
		{
			if (CodeNumber >= 1 && CodeNumber <= 60)
			{
				Temp_1[0] = rand() % 2;//50%概率为up角色
				if (Temp_1[0] == 0) Number_Big = 0;//如果抽中了UP那么大保底累计抽数归零
			}
			else if (CodeNumber >= 61 && CodeNumber <= 315)
				Temp_1[0] = 2;//四星角色
			else if (CodeNumber >= 316 && CodeNumber <= 570)
				Temp_1[0] = 3;//四星物品
			else Temp_1[0] = 4;//三星
		}
		else {
			switch (Number_Big)
			{
			case 90://小保底
			{
				Temp_1[0] = rand() % 2;//50%概率为up角色
				if (Temp_1[0] == 0) Number_Big = 0;//如果抽中了UP那么大保底累计抽数归零
				break;
			}

			case 180://大保底
				Temp_1[0] = Number_Big = 0;
				break;

			default://剩下的就是四星保底
				Temp_1[0] = rand() % 2 + 2;//50%概率为四星角色,得到2或3
				break;
			}
		}
		EditShowedSmokedNumber();
		Output(1, Temp_1);
		break;
	}
		

	case 'B'://进行十连抽
	{
		N_History += 10;
		int Temp_1[10];
		for (int i = 0; i < 10; i++)
		{
			Number_Big ++;
			int CodeNumber = rand() % 10000 + 1;
			if (Number_Big % 10 != 0)//没有保底的情况
			{
				if (CodeNumber >= 1 && CodeNumber <= 60)
				{
					Temp_1[i] = rand() % 2;//50%概率为up角色
					if (Temp_1[i] == 0) Number_Big = 0;//如果抽中了UP那么大保底累计抽数归零
				}
				else if (CodeNumber >= 61 && CodeNumber <= 315)
					Temp_1[i] = 2;//四星角色
				else if (CodeNumber >= 316 && CodeNumber <= 570)
					Temp_1[i] = 3;//四星物品
				else Temp_1[i] = 4;//三星
			}
			else {
				switch (Number_Big)
				{
				case 90://小保底
				{
					Temp_1[i] = rand() % 2;//50%概率为up角色
					if (Temp_1[i] == 0) Number_Big = 0;//如果抽中了UP那么大保底累计抽数归零
					break;
				}

				case 180://大保底
					Temp_1[i] = Number_Big = 0;
					break;

				default://剩下的就是四星保底
					Temp_1[i] = rand() % 2 + 2;//50%概率为四星角色,得到2或3
					break;
				}
			}
		}
		EditShowedSmokedNumber();

		Output(10, Temp_1);
		break;
	}
	}
	return;
}

void Output(int n, int Cod[10])
{//输出动画与结果的函数
	///n为祈愿次数,cod[]储存的是抽中的编号,0为五星UP角色,1为五星常驻角色,2为四星角色,3为四星物品,4为三星
	CleanTheScreen();
	HideCursor;
	printf("\n");
	switch (n)
	{
	case 1://单抽
		switch (Cod[0])
		{
		case 0:
			ChangeColor_Yellow;
			for (int i = 1; i <= 5; i++)
			{
				printf("*");
				Sleep(200);
			}
			printf("\t:%s\n", UPer_5_Stars);

			//接下来写历史记录
			for (int i = N_History - 1; i > 0; i--)
				strcpy(History[i], History[i - 1]);//把历史记录往后推
			sprintf(History[0], "\033[33m*****\t%s", UPer_5_Stars);
			ChangeColor_Whilt_;
			break;

		case 1:
			ChangeColor_Yellow;
			for (int i = 1; i <= 5; i++)
			{
				printf("*");
				Sleep(200);
			}
			srand((unsigned int)time(NULL));
			int FiveStarsNotUPer_Code = rand() % 7;
			printf("\t:%s\n", FiveStars[FiveStarsNotUPer_Code]);

			//接下来写历史记录
			for (int i = N_History - 1; i > 0; i--)
				strcpy(History[i], History[i - 1]);//把历史记录往后推
			sprintf(History[0], "\033[33m*****\t%s", FiveStars[FiveStarsNotUPer_Code]);
			ChangeColor_Whilt_;
			break;

		case 2:
		{
			ChangeColor_Purple;
			for (int i = 1; i <= 4; i++)
			{
				printf("*");
				Sleep(200);
			}
			char Out[25] = "4 stars role";
			printf("\t:%s\n", Out);

			//接下来写历史记录
			for (int i = N_History - 1; i > 0; i--)
				strcpy(History[i], History[i - 1]);//把历史记录往后推
			sprintf(History[0], "\033[35m****\t%s", Out);
			ChangeColor_Whilt_;
			break;
		}

		case 3:
		{
			ChangeColor_Purple;
			for (int i = 1; i <= 4; i++)
			{
				printf("*");
				Sleep(200);
			}
			char Out[25] = "4 stars object";
			printf("\t:%s\n", Out);

			//接下来写历史记录
			for (int i = N_History - 1; i > 0; i--)
				strcpy(History[i], History[i - 1]);//把历史记录往后推
			sprintf(History[0], "\033[35m****\t%s", Out);
			ChangeColor_Whilt_;
			break;
		}

		case 4:
		{
			ChangeColor_Blue__;
			for (int i = 1; i <= 3; i++)
			{
				printf("*");
				Sleep(200);
			}
			char Out[25] = "3 stars object/role";
			printf("\t:%s\n", Out);

			//接下来写历史记录
			for (int i = N_History - 1; i > 0; i--)
				strcpy(History[i], History[i - 1]);//把历史记录往后推
			sprintf(History[0], "\033[36m***\t%s", Out);
			break;
		}
		}
		break;

	case 10://十连抽
	{
		struct InformationForTenPrayer Inf[10];
		struct InformationForTenPrayer *pIFTP = NULL;
		int n_History = N_History - 10;
		//先写历史记录,避免顺序打乱不好写
		for (int j = 0; j < 10; j++)
		{
			pIFTP = &Inf[j];
			n_History++;
			switch (Cod[j])
			{
			case 0:
				for (int i = n_History - 1; i > 0; i--)
					strcpy(History[i], History[i - 1]);//把历史记录往后推
				sprintf(History[0], "\033[33m*****\t%s", UPer_5_Stars);
				strcpy(pIFTP->Name, UPer_5_Stars);
				pIFTP->StarNumber = 5;
				break;

			case 1:
				srand((unsigned int)time(NULL));
				int FiveStarsNotUPer_Code = rand() % 7;
				for (int i = n_History - 1; i > 0; i--)
					strcpy(History[i], History[i - 1]);//把历史记录往后推
				sprintf(History[0], "\033[33m*****\t%s", FiveStars[FiveStarsNotUPer_Code]);
				strcpy(pIFTP->Name, FiveStars[FiveStarsNotUPer_Code]);
				pIFTP->StarNumber = 5;
				break;

			case 2:
				strcpy(pIFTP->Name, "4 stars role");
				for (int i = n_History - 1; i > 0; i--)
					strcpy(History[i], History[i - 1]);//把历史记录往后推
				sprintf(History[0], "\033[35m****\t%s", pIFTP->Name);
				pIFTP -> StarNumber= 4;
				break;

			case 3:
				strcpy(pIFTP->Name, "4 stars object");
				for (int i = n_History - 1; i > 0; i--)
					strcpy(History[i], History[i - 1]);//把历史记录往后推
				sprintf(History[0], "\033[35m****\t%s", pIFTP->Name);
				pIFTP->StarNumber = 4;
				break;

			case 4:
				strcpy(pIFTP->Name, "3 stars object/role");
				for (int i = n_History - 1; i > 0; i--)
					strcpy(History[i], History[i - 1]);//把历史记录往后推
				sprintf(History[0], "\033[36m***\t%s", pIFTP->Name);
				pIFTP->StarNumber = 3;
				break;
			}
		}//到这里按顺序写完了历史记录

		//接下来根据抽到的星数进行降序排序,符合原神实际十连抽的最终页面
		struct InformationForTenPrayer Temp_Swap;//交换的中间值
		for (int i=0;i<9;i++)
			for (int j=0;j<9-i;j++)
				if (Inf[j].StarNumber < Inf[j + 1].StarNumber)
				{
					Temp_Swap = Inf[j];
					Inf[j] = Inf[j + 1];
					Inf[j + 1] = Temp_Swap;
				}//冒泡排序
				
		printf("\n");
		for (int i = 0; i < 10; i++)//输出了
		{
			pIFTP = &Inf[i];
			switch (pIFTP->StarNumber)
			{
				case 5:ChangeColor_Yellow; break;
				case 4:ChangeColor_Purple; break;
				case 3:ChangeColor_Blue__; break;
			}
			for (int j = 1; j <= pIFTP->StarNumber; j++)
			{
				printf("*");
				Sleep(200);
			}
			Sleep(50);
			printf("\t:%s\n", pIFTP->Name);
			Sleep(100);
			ChangeColor_Whilt_;
		}
		break;
	}
	}
	ShowCursor;

	return;
}

void EditTheSmokedNumber()
{//修改已垫抽次数的函数
SmokedNumberInputWrong://如果输入的不是用户需要修改的,或者不符合要求,则跳回到这里

	CleanTheScreen();
	ChangeColor_Purple; printf(">");
	ChangeColor_Green_; printf("Please input the Smoked Number:");
	ChangeColor_Whilt_;
	while (scanf("%d", &Number_Big) == EOF) { }//如果读取失败(比如输入的不是数字)就一直循环

	if (Number_Big >= 0 && Number_Big < 180)
	{
		ChangeColor_Purple; printf(">");
		ChangeColor_Green_; printf("Do you want to change the Smoked Number to %d ?(Y/N)", Number_Big);
		ChangeColor_Whilt_;
		char CharToNext = getchar();
		do { CharToNext = getchar(); } while (!(CharToNext == 'Y' || CharToNext == 'N'));//持续读取直到读取到Y或N
		if (CharToNext == 'N') goto SmokedNumberInputWrong;
		else {
			EditShowedSmokedNumber();
			CleanTheScreen();
		}
	}
	else {//数据范围不符合要求
		ChangeColor_Purple; printf(">");
		ChangeColor_Red___; printf("The number is not allowed.\n");
		ChangeColor_Purple; printf(">");
		ChangeColor_Red___; printf("You should input between 0 to 179.Please try again.\n");

		ChangeColor_Purple; printf("\n>");
		ChangeColor_Green_; printf("Press [Enter] to continue...");

		char charToContinue = getchar();
		do { charToContinue = getchar(); } while (charToContinue != '\n');//持续读取直到输入回车
		goto SmokedNumberInputWrong;
	}
	return;
}

void EditShowedSmokedNumber()
{//修改显示的已抽取数量的函数
	MoveToChangeTheNumber;printf("   ");
	MoveToChangeTheNumber;
	ChangeColor_Yellow; printf("%d", Number_Big);
	ChangeColor_Whilt_;
	MoveTheLocation;
	return;
}

void CleanTheScreen(void)
{//清空屏幕输出区域的函数
	HideCursor;
	MoveTheLocation;
	for (int i = 1; i <= 15; i++)
	{
		for (int j = 1; j <= 100; j++)
			printf(" ");
		printf("\n");
	}
	ShowCursor;
	MoveTheLocation;
}

void Welcome()
{//用于输出欢迎页面的函数,只调用一次
	HideCursor;//隐藏光标
	ChangeColor_Purple; printf("The Genshin Impact Lottery Limulator programmed by QJB.\n");
	ChangeColor_Whilt_; printf("Today's UPer is:");
	ChangeColor_Yellow; printf("%s                ", UPer_5_Stars);
	ChangeColor_Whilt_; printf("Smoked Number:");
	ChangeColor_Yellow; printf("%d\n", Number_Big);
	ChangeColor_Red___; printf("---------------------------------------------------------\n");
	ChangeColor_Whilt_;//以上构成顶部栏

	printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
	printf("┃  Welcome to use The Genshin Impact Lottery Limulator  ┃\n");
	printf("┃   The application is programmed by QJB(Sherry Chou)   ┃\n");
	printf("┃   Compiled according to the rules of Genshin Impact   ┃\n");
	printf("┃   Please respect personal gain,don't repost at will   ┃\n");
	printf("┃    Personal blog homepage:\033[36msherrychou.blog.csdn.net    \033[0m┃\n");
	printf("┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫\n");
	printf("┃                                                       ┃\n");
	printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
	//插入的标签已经输入完毕
	
	//做个进度条增强观感
	Sleep(500);
	ChangeColor_Yellow; printf("\033[%d;%dH", 11, 2);//移动光标到进度条开始位置
	for (int i = 1; i <= 55; i++)
	{
		printf("█");
		Sleep(25);
	}
	ShowCursor;//显示光标
	return;
}

void SearchTheHistory()
{//实现查看历史记录功能的函数
	///历史记录页面格式:输出区域的 第一行为历史记录页面标题,第二行进行空行,分离内容
	///第三行到第七行为五条历史记录(每页五条),第八行为当前页数与总页数,以及左右换页符
	///第九行是提示用户输入需要进行的操作
	CleanTheScreen();
	int StartLine = 6, page = 1, pageMax=(N_History - 1) / 5 + 1;

	HideCursor;
	ChangeColor_Whilt_; printf("The history record passage:");
	printf("\033[%d;%dH", 11, 0);//定位
	printf("           <<        %d        >>\n",page);
	ChangeColor_Purple; printf(">");
	ChangeColor_Green_; printf("[A]Flip to the previous page\n");//提示用户操作
	ChangeColor_Purple; printf(">");
	ChangeColor_Green_; printf("[B]Flip to the next page\n");//提示用户操作
	ChangeColor_Purple; printf(">");
	ChangeColor_Green_; printf("[C]Exit\n");//提示用户操作
	ChangeColor_Purple; printf(">");
	ChangeColor_Green_; printf("Your operation:");//提示用户操作
	ChangeColor_Whilt_;

	for (; StartLine <= 10; StartLine++)
	{
		printf("\033[%d;%dH", StartLine, 0);
		if (5*(page - 1) + (StartLine - 6)>=0)
		{
			printf("\t%s", History[5 * (page - 1) + (StartLine - 6)]);
		}
	}
	printf("\033[%d;%dH", 15, 17); ShowCursor;//移动并显示光标

	char TheOperate;
	do {
		TheOperate = getchar();
		ChangeColor_Whilt_;
		do { 
			TheOperate = getchar();
			if (!(TheOperate == 'A' || TheOperate == 'B' || TheOperate == 'C'))
			{
				printf("\033[%d;%dH", 15, 17);
				printf("                   ");
				printf("\033[%d;%dH", 15, 17);
			}
		} while (!(TheOperate == 'A' || TheOperate == 'B' || TheOperate == 'C'));
		HideCursor;//以上完成了对用户需要的操作的读取

		switch (TheOperate)
		{
		case 'A'://翻到上一页
			HideCursor;
			if (page > 1)
			{
				page--;
				StartLine = 6;
				History_CleanThePanel();

				for (; StartLine <= 10; StartLine++)
				{
					printf("\033[%d;%dH", StartLine, 0);
					if (5 * (page - 1) + (StartLine - 6) >= 0)
					{
						printf("\t%s", History[5 * (page - 1) + (StartLine - 6)]);
					}
				}

				printf("\033[%d;%dH", 11, 22);//定位
				ChangeColor_Whilt_; printf("%d", page);
			}
			printf("\033[%d;%dH", 15, 17);
			printf("                   ");
			printf("\033[%d;%dH", 15, 17);
			ShowCursor;//移动并显示光标
			break;

		case 'B'://翻到下一页
			HideCursor;
			if (page <pageMax)
			{
				page++;
				StartLine = 6;
				History_CleanThePanel();

				for (; StartLine <= 10; StartLine++)
				{
					printf("\033[%d;%dH", StartLine, 0);
					if (5 * (page - 1) + (StartLine - 6) >= 0)
					{
						printf("\t%s", History[5 * (page - 1) + (StartLine - 6)]);
					}
				}

				printf("\033[%d;%dH", 11, 22);//定位
				ChangeColor_Whilt_; printf("%d", page);
			}
			printf("\033[%d;%dH", 15, 17);
			printf("                   ");
			printf("\033[%d;%dH", 15, 17);
			ShowCursor;//移动并显示光标
			break;

		case 'C'://退出历史记录查看
			goto OutThe_while_1_Cycle;
		}
	} while (1);
OutThe_while_1_Cycle://跳出循环调到这里

	ChangeColor_Whilt_;
	ShowCursor;
	printf("\033[%d;%dH", 16, 0);
	return;
}

void History_CleanThePanel()
{//用于清空历史记录输出区域的函数
	for (int i = 6; i <= 10; i++)
	{
		printf("\033[%d;%dH", i, 0);
		for (int j = 1; j <= 60; j++)
			printf(" ");
	}
	return;
}

unistd.h头文件:

#ifndef _UNISTD_H
#define _UNISTD_H
#include <io.h>
#include <process.h>
#endif
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青が絶える(青绝悲)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值