湖大程序设计作业 控制台动画-切蛋糕

 

【题目描述】

    利用上次小班第五题的黑框绘制函数功能,绘制一张方布。方布上放着小明的正方形蛋糕,由不同的颜色和不同大小的方块组成。每次延时一秒后,绘制出分掉某块后的方布和蛋糕图形。最终在方布上显示一个数字,表示多少人分到了蛋糕。

【背景知识】

  1. <window.h>本题用到的头文件中一系列控制台操作函数

void setColor(unsigned short foreColor=15,unsigned short bgColor=0) 
{	//设置输出文本的前景色和背景色 
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleTextAttribute(hConsole,foreColor%16|bgColor%16*16);
}
 
void gotoXY(short x, short y)
{	//设置光标位置,坐标x:0~79,y:0~299;只要有一个超限就回到(0,0)
    COORD position = {x, y};
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(hConsole, position);
}

SetConsoleCursorPosition光标的位置控制 以及 控制台字体颜色控制 

(20条消息) SetConsoleCursorPosition光标的位置控制 以及 控制台字体颜色控制_aaqian1的博客-CSDN博客 

  结构体 COORD

typedef struct _COORD {
   SHORT X; // horizontal coordinate
   SHORT Y; // vertical coordinate
} COORD;


//一个保存横纵坐标的结构体,声明和赋值如下:
COORD pos;   //声明一个COORD结构 pos
pos.X = 1;   //把坐标(1,2)赋值给 pos
pos.Y = 2;   //可三行合并,写成一行: COORD pos = {1,2};
 
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hConsole, pos);

什么是HANDLE? 

从广义上,能够从一个数值拎起一大堆数据的东西都可以叫做句柄。句柄的英文是"Handle",本义就是"柄",只是在计算机科学中,被特别地翻译成"句柄",其实还是个"柄"。从一个小东西拎起一大堆东西,这难道不像是个"柄"吗?

然后,指针其实也是一种"句柄",只是由于指针同时拥有更特殊的含义——实实在在地对应内存里地一个地址——所以,通常不把指针说成是"句柄"。但指针也有着能从一个32位的值引用到一大堆数据的作用,这不是句柄又是什么?

Windows系统中有许多内核对象(这里的对象不完全等价于"面向对象程序设计"一词中的"对象",虽然实质上还真差不多),比如打开的文件,创建的线程,程序的窗口,等等。这些重要的对象肯定不是4个字节或者8个字节足以完全描述的,他们拥有大量的属性。为了保存这样一个"对象"的状态,往往需要上百甚至上千字节的内存空间,那么怎么在程序间或程序内部的子过程(函数)之间传递这些数据呢?拖着这成百上千的字节拷贝来拷贝去吗?显然会浪费效率。那么怎么办?当然传递这些对象的首地址是一个办法,但这至少有两个缺点:

1.暴露了内核对象本身,使得程序(而不是操作系统内核)也可以任意地修改对象地内部状态(首地址都知道了,还有什么不能改的?),这显然是操作系统内核所不允许的;
2.操作系统有定期整理内存的责任,如果一些内存整理过一次后,对象被搬走了怎么办?

所以,Windows操作系统就采用进一步的间接:在进程的地址空间中设一张表,表里头专门保存一些编号和由这个编号对应一个地址,而由那个地址去引用实际的对象,这个编号跟那个地址在数值上没有任何规律性的联系,纯粹是个映射而已。
————————————————
版权声明:本文为CSDN博主「Hann Yang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/boysoft2002/article/details/113457253

 笔者对句柄的理解来自于某篇文章下评论的启发。

如果将整个系统看作一本书,每个部件当成一张纸,句柄就是每一页的页码,获取了句柄就可以对该对象进行操作。

引用来自 Hann Yang更多进阶操作请移步——>引用来自 Hann Yang

【代码设计】

1.setColor(unsigned short foreColor=15,unsigned short bgColor=0) 函数

2.利用SetConsoleTextAttribute()函数初始化平时颜色,同时将十六进制转化为十进制输入颜色

3.void gotoXY(unsigned short x, unsigned short y)函数 利用COORD 获取光标位置

4.利用SetConsoleCursorPosition()函数移动光标位置

5.void builtCake(int Cakewidth,int Cakecolor) 简单for循环buile cake(可以改进制造多层蛋糕)

6.void cutCake(int people,int Cakewidth)函数 光标重定位,使用空白空格消去蛋糕,达到切蛋糕的效果 

【代码实现】 

#include <iostream>
#include <ctime>
#include <iomanip>
#include <windows.h> 
using namespace std;
const int X1=25,Y1=10;
void setColor(unsigned short foreColor=15,unsigned short bgColor=0) 
{	//设置输出文本的前景色和背景色 
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);//句柄 
	SetConsoleTextAttribute(hConsole, (foreColor%16)|((bgColor%16)*16));
}
 
void gotoXY(unsigned short x, unsigned short y)
{	//设置光标位置,坐标从左上角(0,0)起始 
    COORD position;
    position.X = x;
    position.Y = y;
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(hConsole, position);
}
void builtCake(int Cakewidth,int Cakecolor){
	for(int i=0;i<Cakewidth;i++){
	gotoXY(X1,i+Y1);
		for(int j=0;j<Cakewidth;j++){
			setColor(15,Cakecolor); 
			cout<<"  ";
			//Sleep(1);
		}
		cout<<endl;
	}	
	for(int i=0;i<Cakewidth/2;i++){
		gotoXY(X1+Cakewidth/2,i+Y1+Cakewidth/3);
		for(int j=0;j<Cakewidth/2;j++){
			setColor(15,Cakecolor+1); 
			cout<<"  ";
			Sleep(1);
		}
	}
	
}

void cutCake(int people,int Cakewidth){
	for(int i=0;i<people/2;i++){
		for(int j=0;j<Cakewidth*2/people;j++){
			gotoXY(X1,Y1+i*2*Cakewidth/people+j);
			for(int k=0;k<Cakewidth/2;k++){
				cout<<"  ";
			}	
		}
		Sleep(1000);
	}
	for(int i=0;i<people/2;i++){
		for(int j=0;j<=Cakewidth*2/people;j++){
			gotoXY(X1+Cakewidth/2,Y1+i*2*Cakewidth/people+j);
			for(int k=0;k<=Cakewidth;k++){
				cout<<"  ";
			}	
		}
		Sleep(1000);
	}
}
bool Modpeople(int people,int Cakewidth){
	for(int i=0;i<Cakewidth;i+=2){
		if(Cakewidth%people==0)
		return true;
	}
	return false;
}
int main()
{
	SetConsoleTitle("分蛋糕啦");  //相当于system("程序执行时控制台的标题"); 
	int Cakewidth,Cakecolor;
	cout<<"请输入蛋糕的大小:";
	cin>>Cakewidth;
	cout<<endl<<"请输入蛋糕的颜色:";
	cin>>Cakecolor;
	builtCake(Cakewidth,Cakecolor);
	gotoXY(0,3);
	setColor();
	cout<<"要分给几个人(请输入蛋糕大小的公因数且为偶数):";
	int people;
	while(cin>>people){
		if(people%2==0&&Modpeople(people,Cakewidth))
		break;
		else 
		cout<<"请重新输入\a"; 
	}
	cutCake(people,Cakewidth);
	system("cls");
	cout<<"happy birthday!";
	setColor();
	gotoXY(X1,Y1);
	cout<<people;
 	return 0;
}

【效果】

 

 【问题与总结】

1.可以通过字符画的格式引入更加真实的蛋糕

2.可以利用递归的方式使蛋糕层数更多

3.切蛋糕只对蛋糕大小的公因数运行,对于非因子与奇数会出现错误

4.光标重定向代码复杂,代码简洁性不好

希望大佬批评指正

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值