C语言模拟漏斗
朋友分享了一个有趣的题目——控制台模拟漏斗!
最先想到的思路是每隔一段时间刷新一次控制台,每每循环在后面加上system("cls")即可。
代码如下:
#include<stdio.h> #include<windows.h> #include<stdlib.h> int a, h; //a为宽度(a不小于3且a为奇数),h为高度(h不小于6且h为偶数) void box(int t) { int i, j; //上板 for(i = 0; i < a; i++) { printf("%c ", '@'); } printf("\n"); //上漏斗 for(i = 1; i < h / 2; i++) { printf("%*c", 2 * i, '@'); //沙子 if(i > t) { for(j = 0; j < 2 * a - 4 * i - 1; j++) { printf("%c", '*'); } printf("%c\n", '@'); } else { printf("%*c\n", 2 * a - 4 * i, '@'); } } //下漏斗 for(i = h / 2 - 1; i >= 1; i--) { printf("%*c", 2 * i, '@'); //沙子 if(i <= t) { for(j = 0; j < 2 * a - 4 * i - 1; j++) { printf("%c", '*'); } printf("%c\n", '@'); } else { printf("%*c", a - 2 * i, '*'); printf("%*c\n", a - 2 * i, '@'); } } //下板 for(i = 0; i < a; i++) { printf("%c ", '@'); } printf("\n"); } int main() { scanf("%d%d", &a, &h); system("cls"); //清屏 box(0); int t = 1; while(t < h / 2){ system("cls"); box(t); Sleep(1000); t++; } getchar(); return 0; }
但是有个问题,就是控制台在每次刷新的时候闪烁得很厉害,看着很不爽。
如何解决呢,网上搜了些类似的问题,提到了局部更新和全部更新的区别。
嗯,那就应该用局部更新的方法啊,漏斗什么的都是固定的,变的是沙子的位置。
这里就要用到windows API了,加上windows.h头文件,主要是涉及到光标定位和光标隐藏啦~
下面是改进后的程序:
//涉及windows编程,用到windows API #include<stdio.h> #include<windows.h> #include<stdlib.h> int a, h; //a为宽度(a不小于3且a为奇数),h为高度(h不小于6且h为偶数) //光标定位 void gotoxy(int x, int y) { COORD cursorPosition; cursorPosition.X = x; cursorPosition.Y = y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cursorPosition); } //隐藏光标 void HideCursor() { CONSOLE_CURSOR_INFO cursor_info = {1, 0}; SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info); } void init() { int i, j; //上板 for(i = 0; i < a; i++) { printf("%c ", '@'); } printf("\n"); //上漏斗 for(i = 1; i < h / 2; i++) { printf("%*c", 2 * i, '@'); //沙子 for(j = 0; j < 2 * a - 4 * i - 1; j++) { printf("%c", '*'); } printf("%c\n", '@'); } //下漏斗 for(i = h / 2 - 1; i >= 1; i--) { printf("%*c", 2 * i, '@'); printf("%*c", a - 2 * i, '*'); printf("%*c\n", a - 2 * i, '@'); } //下板 for(i = 0; i < a; i++) { printf("%c ", '@'); } printf("\n"); } void box(int t) { gotoxy(2 * t, t); printf("%*c", 2 * a - 1 - 4 * t, ' '); gotoxy(2 * t, h - t - 1); for(int i = 0; i < 2 * a - 1 - 4* t; i++) printf("%c", '*'); } int main() { int time = 1000; scanf("%d%d", &a, &h); system("cls"); //清屏 HideCursor(); init(); getchar(); int t = 1; while(t < h / 2) { box(t); Sleep(time); time -= 200 / t; //速度逐渐变快 t++; } getchar(); return 0; }