?
【题目描述】
?? ?利用上次小班第五题的黑框绘制函数功能,绘制一张方布。方布上放着小明的正方形蛋糕,由不同的颜色和不同大小的方块组成。每次延时一秒后,绘制出分掉某块后的方布和蛋糕图形。最终在方布上显示一个数字,表示多少人分到了蛋糕。
【背景知识】
-
<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.光标重定向代码复杂,代码简洁性不好
希望大佬批评指正
|