为了帮助新人学习C++,为了保证既直观,又具有一定的灵活度,电梯算法是一个不错的切入点。写了个小电梯作为demo。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <vector>
#include <curses.h>
class Elevator {
public:
Elevator() : init_floor_(1), park_floor_(1)
{
// empty
}
// 按下某个楼层
void add_target_floor(int floor)
{
if (floor > 0 && floor <= MAX_FLOOR) {
seq_.push_back(floor);
}
}
// 初始楼层
void set_init_floor(int init_floor)
{
init_floor = init_floor_;
}
// 停机楼层
void set_park_floor(int park_floor)
{
park_floor_ = park_floor;
}
void pause()
{
// TODO: xiaochu.yh
}
int run()
{
int ret = 0;
if (init_floor_ <= 0 || park_floor_ <=0 || init_floor_ > MAX_FLOOR || park_floor_ > MAX_FLOOR) {
ret = -1;
} else {
int last_floor = init_floor_;
if (seq_.size() > 0) {
for (int i = 0; i < seq_.size(); ++i) {
runTo(last_floor, seq_[i]);
last_floor = seq_[i];
}
}
runTo(last_floor, park_floor_);
}
return ret;
}
private:
void clearLine()
{
printf("\r");
for (int i = 0; i < MAX_FLOOR; ++i) {
printf(" ");
}
printf("\r");
}
void printStatus(int floor, bool arrived = false)
{
clearLine();
for (int i = 0; i < floor - 1; ++i) {
printf(".");
}
printf(arrived ? "*" : "#");
fflush(stdout);
sleep();
}
void runTo(int from, int to)
{
// down stairs
while (from > to) {
printStatus(from);
--from;
}
// up stairs
while (from < to) {
printStatus(from);
++from;
}
// 到达后停一下
beep();
printStatus(from, true);
sleep();
}
void sleep()
{
usleep(100000);
}
void beep()
{
printf("\a");
}
private:
static const int MAX_FLOOR = 80;
int init_floor_;
int park_floor_;
std::vector<int> seq_;
};
int main()
{
Elevator ele;
ele.set_park_floor(80);
ele.set_init_floor(1);
ele.add_target_floor(3);
ele.add_target_floor(9);
ele.add_target_floor(1);
ele.add_target_floor(12);
ele.add_target_floor(23);
ele.add_target_floor(54);
ele.run();
printf("\r\n");
}
代码编译运行方法:代码保存为main.cpp,然后调用:
g++ main.cpp
./a.out
如果你是一个C++老手,请指出上面代码中不合适的地方。有很多哦!他们非常严重地影响了Elevator类的可移植性,随着开发的深入,这个类一定会越来越多地被修改,不符合Close For Modification的原理。
上面是作业的第一步,这里采用了FIFO的算法,这个题目可以往下面几个方向扩展:
1. 功能扩展:调整电梯的一些功能,比如停顿时间,运行速度(变速),增加门铃功能,增加多人入梯模拟功能,程序是否能支持交互,运行过程中接受用户输入楼层?等等
2. 算法扩展:能否让电梯支持多种调度算法?FIFO,最省时算法,最节能算法,最满意算法,等等。如何保证增加算法时不需要修改过多源码。
3. 1和2的综合扩展:如果是多台电梯,代码该如何写?
4. 界面扩展:如果将来可能不采用命令行界面,而是采用图形界面,甚至直接用到实际的电梯芯片里面去,代码该如何设计才能保证修改量更小?
5. 代码规划:学习如何规划代码,学习写Makefile,不要把所有功能放到一个文件中,采取模块化的方式组织代码。
小小的电梯,还是很考验同学们设计程序的能力滴哦~
如果你深入动手实践本题,一定会对MVC有更深刻的理解。