Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Tree: ee5711ea29
Fetching contributors…

Cannot retrieve contributors at this time

344 lines (294 sloc) 10.617 kB
#include "../Headers/qt/emulator.h"
#include "../Headers/PoissRand.h"
#include "../Headers/internlib.h"
#include "../Headers/controller.h"
#include "../Headers/passenger.h"
#include <QPushButton>
#include <QApplication>
#include <QGridLayout>
#include <QPainter>
#include <QKeyEvent>
#include <QSound>
/* 构造函数:构造 Qt 界面 */
Emulator::Emulator(QWidget* parent) : QWidget(parent) {
START = 0;
QLabel* labelP;
labelP = new QLabel("Elevator:", this);
int bias = 20 + 150;
labelP->move(40 + bias, 530);
nEle = new QLabel("0 ", this);
nEle->move(100 + bias, 530);
labelP = new QLabel("Passenger:", this);
labelP->move(150 + bias, 530);
nPas = new QLabel("0 ", this);
nPas->move(220 + bias, 530);
labelP = new QLabel("Average wait:", this);
labelP->move(260 + bias, 530);
avWt = new QLabel("0 ", this);
avWt ->move(345 + bias, 530);
labelP = new QLabel("Max wait:", this);
labelP->move(405 + bias, 530);
mxWt = new QLabel("0 ", this);
mxWt->move(470 + bias, 530);
labelP = new QLabel("Average duration:", this);
labelP->move(40 + bias, 550);
avDur = new QLabel("0 ", this);
avDur->move(160 + bias, 550);
labelP = new QLabel("Max duration:", this);
labelP->move(210 + bias, 550);
mxDur = new QLabel("0 ", this);
mxDur->move(305 + bias, 550);
labelP = new QLabel("Min duration:", this);
labelP->move(365 + bias, 550);
mnDur = new QLabel("0 ", this);
mnDur->move(465 + bias, 550);
labelP = new QLabel("Average throughput:", this);
labelP->move(40 + bias, 570);
avThr = new QLabel("0 ", this);
avThr->move(bias + 180, 570);
start = new QPushButton("START", this);
start->setGeometry(720, 550, 60, 20);
QPushButton *quit = new QPushButton("Quit ", this);
quit->setGeometry(720, 570, 60, 20);
fcfs = new QPushButton("FCFS", this);
fcfs->setGeometry(800, 550, 60, 20);
scan = new QPushButton("SCAN", this);
scan->setGeometry(800, 570, 60, 20);
costflow = new QPushButton("COSTFLOW", this);
costflow->setGeometry(860, 550, 80, 20);
pickup = new QPushButton("PICKUP", this);
pickup->setGeometry(860, 570, 80, 20);
connect(quit, SIGNAL(clicked()), qApp, SLOT(quit()));
connect(start, SIGNAL(clicked()), this, SLOT(startEmulationSlots()));
connect(fcfs, SIGNAL(clicked()), this, SLOT(useFcfs()));
connect(scan, SIGNAL(clicked()), this, SLOT(useScan()));
connect(costflow, SIGNAL(clicked()), this, SLOT(useCostflow()));
connect(pickup, SIGNAL(clicked()), this, SLOT(usePickup()));
timer = 0;
// QSound *sound = new QSound("../../Muisc/style.mp3", this);
// sound->play();
QSound *style = new QSound("style.mp3", this);
style->play();
startTimer(10);
}
/* 开始/暂停游戏 slots */
void Emulator::startEmulationSlots() {
startEmulator();
}
/* 开始/暂停模拟 */
void Emulator::startEmulator()
{
START = !START;
if (START == 0) {
start->setText(QString("START"));
} else {
start->setText(QString("PAUSE"));
}
}
/* 每计数器刷新事件,详见函数内注释 */
void Emulator::timerEvent(QTimerEvent *event)
{
if (START) {
timer = (timer + 1) % 100;
}
Q_UNUSED(event);
if(START) {
if (timer == 0) {
Control(); /* 调用调度算法 */
Update(); /* 更新统计数据 */
}
Born(); /* 产生乘客,电梯请求 */
Move(); /* 电梯依据指令或默认逻辑移动 */
repaint();
} else {
// Do nothing
}
}
/* Qt::绘制图形界面 */
void Emulator::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
int bias = 150;
QPainter painter(this);
QFont font("Courier", 40);
painter.setFont(font);
painter.setBrush(QBrush("#c56c00"));
int i = 0;
/* 绘制电梯 */
for(EleIter iter = elevators.begin(); iter != elevators.end(); iter++) {
i++;
painter.drawRect(bias + 150 + i * 50, height() - (128 + (*iter)->Get_fpos() * 50), 40, 40);
painter.setPen(Qt::white);
painter.drawText(bias + 150 + i * 50, height() - (95 + (*iter)->Get_fpos() * 50), QString::number((*iter)->Get_nPassenger()));//QString::number((*iter)->Get_inst()->size() ));
painter.setPen(QColor(Qt::black));
}
/* 绘制乘客 */
for (i = 0; i < nFloor; i++) {
list<Passenger*>::iterator iter;
for (iter = floors[i].inPassengers.begin(); iter != floors[i].inPassengers.end(); iter++) {
painter.setBrush(QColor(Qt::gray));
painter.drawRect(bias - 100 + 13*(*iter)->Get_fpos(), height() - (120 + i * 50), 10, 10);
}
for (iter = floors[i].outPassengers.begin(); iter != floors[i].outPassengers.end(); iter++) {
painter.setBrush(QColor(Qt::gray));
painter.drawRect(bias + 550 + 13*(*iter)->Get_fpos(), height() - (120 + i * 50), 10, 10);
}
}
painter.setBrush(QBrush("#c56c00"));
/* 绘制楼层 */
for (i = 0; i < nFloor; i++) {
painter.drawRect(bias + 60, height() - (84 + i * 50), 110, 4);
painter.setPen(QColor(Qt::gray));
painter.drawText(bias + 105, height() - (90 + i * 50), QString::number(floors[i].Get_nPassenger()));
painter.setPen(QColor(Qt::red));
if (floors[i].UpOrdered())
painter.drawText(bias + 145, height() - (90 + i * 50) - 10, "*");
else {
painter.setPen(Qt::gray);
painter.drawText(bias + 145, height() - (90 + i * 50) - 10, "*");
painter.setPen(Qt::red);
}
if (floors[i].DownOrdered()) {
painter.drawText(bias + 145, height() - (90 + i * 50) + 10, "*");
} else {
painter.setPen(Qt::gray);
painter.drawText(bias + 145, height() - (90 + i * 50) + 10, "*");
painter.setPen(Qt::red);
}
painter.setPen(QColor(Qt::black));
}
QPen pen(Qt::gray, 2, Qt::DashDotLine);
painter.setPen(pen);
/* 绘制楼层分界 */
for (i = 0; i < nFloor; i++) {
painter.drawLine(bias + 180, 67 + i * 50, 700 + bias, 67 + i * 50);
}
/* 打印统计数据 */
nEle->setText (QString::number(nElevator));
nPas->setText (QString::number(Passenger::Total()));
avWt->setText (QString::number(Passenger::AverWaitTime()) + "s");
avDur->setText(QString::number(Passenger::AverDuration()) + "s");
mxWt->setText (QString::number(Passenger::MaxWaitTime()) + "s");
mxDur->setText(QString::number(Passenger::MaxDuration()) + "s");
mnDur->setText(QString::number(Passenger::MinDuration()) + "s");
avThr->setText(QString::number(Elevator::AverThrput()) + "/h");
}
/* Qt::键盘响应事件映射 */
void Emulator::keyPressEvent(QKeyEvent* event)
{
switch (event->key()) {
case Qt::Key_Space: /* Space: 开始/暂停模拟 */
startEmulator();
break;
case Qt::Key_Escape: /* Esc: 退出程序 */
qApp->exit();
break;
default:
QWidget::keyPressEvent(event);
break;
}
}
/* 产生新的乘客,新的请求 */
void Emulator::Born() {
for(int i = 0; i < nFloor; i++) {
int nPassenger = PoissRand(lambda);
for(int j = 0; j < nPassenger; j++) {
Passenger *pass = new Passenger(i);
floors[i].PushPassenger(pass);
}
}
}
/* 依据算法调度 */
void Emulator::Control() {
if (elevatorType == "fcfs") {
Controller::Fcfs();
} else if (elevatorType == "costflow") {
Controller::CostFLow();
} else if (elevatorType == "pickup") {
Controller::PickUp();
} else if (elevatorType == "scan") {
Controller::Scan();
}
}
struct fpos_lt
{
int pos;
fpos_lt(double pos_) : pos(pos_){};
bool operator () (Passenger *p) {
return p->Get_fpos() >= pos;
}
};
/* 电梯依据指令或默认逻辑移动,乘客移动 */
void Emulator::Move() {
EleIter iter;
list<Passenger*>::iterator pass_iter;
list<Passenger*> toDelete;
/* 电梯移动 */
for (iter = elevators.begin(); iter != elevators.end(); iter++) {
(*iter)->Move();
}
/* 乘客移动 */
for (int i = 0; i < nFloor; i++) {
for (pass_iter = floors[i].inPassengers.begin(); pass_iter != floors[i].inPassengers.end(); pass_iter++) {
if ((*pass_iter)->Move()) {
(*pass_iter)->Set_status(2);
floors[i].passengers.push_back(*pass_iter);
(*pass_iter)->MakeAnOrder();
}
}
floors[i].inPassengers.remove_if(fpos_lt(10));
for (pass_iter = floors[i].outPassengers.begin(); pass_iter != floors[i].outPassengers.end(); pass_iter++) {
(*pass_iter)->Move();
}
floors[i].outPassengers.remove_if(fpos_lt(20));
}
}
/* 更新统计数据 */
void Emulator::Update() {
EleIter iter;
for (int i = 0; i < nFloor; i++) {
floors[i].LetThemWait();
}
for (iter = elevators.begin(); iter != elevators.end(); iter++) {
(*iter)->LetThemMove();
}
dual++;
}
void Emulator::Reset() {
dual = timer = 0;
EleIter iter;
for (iter = elevators.begin(); iter != elevators.end(); iter++) {
(*iter)->passengers.clear();
(*iter)->fpos = 0;
(*iter)->pos = 0;
(*iter)->dir = '-';
(*iter)->instructions.clear();
}
Elevator::throughput = 0;
for (int i = 0; i < nFloor; i++) {
floors[i].passengers.clear();
floors[i].inPassengers.clear();
floors[i].upOrder = floors[i].downOrder = NULL;
}
Passenger::maxDuration = Passenger::maxWaitTime = Passenger::nCompleteDuration = Passenger::total = Passenger::totalWaitTime =
Passenger::totalDuration = 0;
Passenger::minDuration = INT_MAX;
Passenger::minWaitTime = INT_MAX;
orders.clear();
}
void Emulator::useFcfs() {
Reset();
elevatorType = "fcfs";
}
void Emulator::useScan() {
Reset();
elevatorType = "scan";
}
void Emulator::useCostflow() {
Reset();
elevatorType = "costflow";
}
void Emulator::usePickup() {
Reset();
elevatorType = "pickup";
}
Jump to Line
Something went wrong with that request. Please try again.