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;
}

 

posted @ 2016-04-28 19:50  Nagihiko  阅读(863)  评论(0编辑  收藏  举报