三.代码编制:
前面已经完成了类设计,那么剩下来的就是应该是系统逻辑部分的实现了,对于系统整体来说,应该有一个事件侦测体系,用来对系统每个乘客和电梯的状态的侦测,以便发送或者修改必要的信息,该侦测体系的周期定为1秒钟(可以用定时器实现),然后用串行的方式来模拟并行的。如果把思路总结一下,应该是跟动画片的原理是一样的:将多个固定和静止的画面定时、按顺序地放映出来,就变成了活动的画面。所以,可以在程序中定义一个主循环,在该循环外进行必要的初始化,进入后每秒钟执行一次,以遍历方式一一激励当前已经产生的对象,由它们根据自己的当前状态和相关的状态变化规则,决定是否需要改变、改变成什么样的状态,以及按照上述行为特征的设计展示必要的对象状态。
根据上面叙述的思想,下面列举主要列出"事件侦测体系"的代码:
(应该在另外一个函数来触发次函数,即调用SetTimer(1,1000,NULL)即可)
void CLiftsimulationView::OnTimer(UINT nIDEvent) //主要在这里处理所有得逻辑 { int i=1; int j=1; int a; int flag1=0; CString str1,str2; CString showtime,sen,m,h; DWORD dwTime; if (nIDEvent==1) //整个系统来驱动,这个是最小得时间单位 {if (this->m_elevator.bStart =true) //电梯在仿真 { //对所有乘客循环查询,类似于消息循环,这是电梯核心程序得入口 for(i=1;i<=this->n;i++) {if (this->m_passenger[i].bInLift ==false && this->m_passenger[i].bStart ==true && this->m_elevator.bStop==true && this->m_elevator.bIsEmptyOperation==true) { //轮询各个乘客得请求 //只有当电梯停止而且乘客在楼层上得时候,才能进行发信号 if (this->m_passenger[i].bSignal ==true) {//初始化乘客 srand(::GetTickCount()); a =rand()%10+1; //产生一个1到10得随机数 this->m_passenger[i].iToFloor =a; //该乘客要去得层数 if (a==this->m_passenger[i].iAtFloor) //楼层一样得话就放弃此次信号 if (a ==10) this->m_passenger[i].iAtFloor=a-1; else this->m_passenger[i].iAtFloor=a+1; str1.Format("%d",this->m_passenger[i].iToFloor); str2.Format("%d",this->m_passenger[i].number ); this->m_passenger[i].flag =str2+"--"+str1; this->m_passenger[i].bSignal =false; //关闭她得信号标志,给别得乘客一个机会 this->m_passenger[i].bInLift=true; //进入电梯了(虚拟) //初始化电梯,为空载运行作准备 this->m_elevator.iToFloor =this->m_passenger[i].iAtFloor; this->m_elevator.iPassengers =1; this->m_elevator.m_passengers.Add(this->m_passenger[i]); this->m_elevator.bStop =false; //表明电梯再运行 this->iEmptySrcFloor =this->m_elevator.iAtFloor; this->iEmptyDesFloor =this->m_elevator.iToFloor ; this->SetDlgItemText(IDC_STATIC18,(LPCTSTR)(str2+"--"+str1)); //完成空载任务 this->itimes[4]++; if (this->itimes[4]==1) SetTimer(4,2000,0); //电梯空载去接乘客 break; //每次接一个 } } } //判断是否结束仿真 for(i=1;i<=this->n;i++) { if (this->m_passenger[i].bStart ==true) flag1=1; } if (flag1==0) //结束仿真 { KillTimer(1); this->m_elevator.bStart =false; return; } //防止没有乘客发信号,系统进入死循环 for(i=1;i<=this->n;i++) { if (this->m_passenger[i].bInLift ==false && this->m_elevator.bStop ==true && this->m_elevator.bStart ==true) { this->m_passenger[i].bSignal =true; //应该是随机 break; } } } else { KillTimer(1); //如果电梯运行标志为false,则停止仿真 } dwTime=::GetTickCount() -this->ElapseTime ; dwTime=dwTime/1000; sen.Format("%d",dwTime%60); h.Format("%d",dwTime/3600); m.Format("%d",(dwTime/60)%60); showtime=h+" : "+m+" : "+sen; this->SetDlgItemText(IDC_STATIC16,showtime); } else if (nIDEvent==4) //电梯空载运行(去接乘客) { if (this->iEmptySrcFloor ==this->iEmptyDesFloor ) //到达目的地了 { if (this->iEmptySrcFloor !=1 && this->iEmptySrcFloor !=10 ) { this->DrawColor(iEmptySrcFloor,1); this->DrawColor(iEmptySrcFloor,-1); } //因为到站了,所以要把电梯设置为接收信号状态 this->m_elevator.bStop =true; //电梯不运行了 this->m_elevator.bIsEmptyOperation =false; //为满载作准备 this->m_elevator.iAtFloor =this->m_elevator.iToFloor ; this->m_elevator.iToFloor=this->m_elevator.m_passengers[0].iToFloor; KillTimer(4); this->itimes[4]=0; this->iSrcFloor =this->m_elevator.iAtFloor; this->iDesFloor =this->m_elevator.iToFloor ; this->m_elevator.bStop =false; //电梯启动 this->itimes[2]++; if (this->itimes[2]==1) SetTimer(2,2000 ,0); //启动乘客上电梯 } if (iEmptySrcFloor <iEmptyDesFloor) { this->DrawColor(iEmptySrcFloor,1); iEmptySrcFloor++; } else { this->DrawColor(iEmptySrcFloor,-1); iEmptySrcFloor--; } } else if(nIDEvent==2) //电梯每隔3秒,电梯是载客运行,还有一种情况是无客运行 {if (iSrcFloor <iDesFloor) { this->DrawColor(iSrcFloor,1); iSrcFloor++; } else if (iSrcFloor >iDesFloor) { this->DrawColor(iSrcFloor,-1); iSrcFloor--; } if (iSrcFloor ==iDesFloor) //到达目的地了 { this->DrawColor(iSrcFloor,1); this->DrawColor(iSrcFloor,-1); //因为到站了,所以要把电梯设置为接收信号状态 this->m_elevator.bStop =true; this->m_elevator.iAtFloor =this->m_elevator.iToFloor ; //进行卸载乘客得操作 srand(::GetTickCount()); a =rand()%10+1; //产生一个1到10得随机数 this->m_elevator.m_passengers[0].iAtFloor =this->m_elevator.m_passengers[0].iToFloor ; this->m_elevator.m_passengers[0].iToFloor = a; //该乘客要去得层数 this->m_elevator.m_passengers[0].iLifts++; if (this->m_elevator.m_passengers[0].iLifts ==this->l ) this->m_elevator.m_passengers[0].bStart =false; this->m_elevator.m_passengers[0].bInLift =false; //电梯外面了 this->m_elevator.m_passengers.RemoveAll(); this->m_elevator.iPassengers --; //为下一次空载作准备 this->m_elevator.bStop =true; this->m_elevator.bIsEmptyOperation =true; KillTimer(2); this->itimes[2]=0; } } CFormView::OnTimer(nIDEvent); } |
四.结论:
至此,全部的设计过程完毕,上面所有代码已经在VC6.0+Win2000平台下调试成功。从上面的分析可以看出,实际上运用OOP的思想进行设计的时候,关键是类设计,类设计一定要通过对系统对象域的划分来进行,而关于类里面的具体成员就必须由系统各个部分的功能来进行确定了。总之,类设计不是一天两天的功夫,需要长期的实践才可能达到熟练的程度。 |