《自动售货机仿真》
《自動(dòng)售貨機(jī)仿真》實(shí)驗(yàn)報(bào)告
一、問題描述
– ① 有一種自動(dòng)售貨機(jī)VM,可售三種商品:可樂(每聽0.25),咖啡(每聽0.25),咖啡(每聽0.30),餐巾紙(每包0.05)。每種商品的示意圖形下方都有一個(gè)按鈕。一臺VM中最多能夠容納NC聽可樂、NF聽咖啡、NT包餐巾紙。–②顧客使用VM購買商品時(shí),先從投幣口投入硬幣(共有三種硬幣:0.05)。每種商品的示意圖形下方都有一個(gè)按鈕。一臺VM中最多能夠容納NC聽可樂、NF聽咖啡、NT包餐巾紙。–②顧客使用VM購買商品時(shí),先從投幣口投入硬幣(共有三種硬幣:0.05;0.10;0.10;0.25),在投入的硬幣總值達(dá)到或超過其欲購商品之價(jià)格后,再按下對應(yīng)商品的按鈕,VM即從出貨口自動(dòng)吐出一件商品,并從找?guī)趴谡伊恪?
– ③ 如果顧客在其投入的硬幣總值沒有達(dá)到其欲購商品之價(jià)格時(shí)就按下了對應(yīng)商品的按鈕,或者最近一次投幣30秒后既不繼續(xù)投幣,也不按下商品按鈕,VM均從找?guī)趴谕鲁雠c該顧客已投入的硬幣總值等值的硬幣,但不吐出商品。
– ④ 如果顧客欲購之商品已經(jīng)售完,則在顧客按下該商品的按鈕后,VM從找?guī)趴谕鲁雠c該顧客已投入的硬幣總值等值的硬幣。
– ⑤ 當(dāng)某種商品還剩NL聽/包時(shí),VM即自動(dòng)發(fā)出短信,將VM的代號和缺貨的商品名稱通知管理人員。管理人員將在時(shí)間TM后收到短信,再用時(shí)間TS到達(dá)VM,并使VM的所有商品存貨都達(dá)到最大容納量,取走VM中的硬幣,并留有找零的硬幣:0.05、0.05、0.10、$0.25分別留C5、C10、C25枚。
須仿真的活動(dòng)及開發(fā)結(jié)果的行為特征
– 1、開始仿真時(shí),應(yīng)隨機(jī)產(chǎn)生VM中三種商品的存貨量(不能超過其最大容納量)和VM中三種硬幣的數(shù)量(分別不小于C5、C10、C25枚)。
– 2、仿真中,應(yīng)隨機(jī)產(chǎn)生前來購物的顧客,隨機(jī)產(chǎn)生其欲購買的商品種類,隨機(jī)產(chǎn)生顧客的投幣行為(包括③描述的行為),按問題域概述給出的要求進(jìn)行VM自動(dòng)售貨活動(dòng)的仿真。
– 3、NC、NF、NT、NL、C5、C10、C25的值應(yīng)在運(yùn)行仿真程序時(shí)用命令行給出,或者在開始仿真時(shí)從界面輸入。
– 4、實(shí)時(shí)顯示各種商品的當(dāng)前存貨量。
– 5、出現(xiàn)情況⑤時(shí),應(yīng)顯示所發(fā)的短信內(nèi)容,并隨機(jī)決定TM和TS的值。在管理人員到達(dá)VM之前,應(yīng)照常進(jìn)行顧客購物的仿真。管理人員加貨和取款的持續(xù)時(shí)間可忽略不計(jì)。
– 6、仿真開始后,應(yīng)自動(dòng)記銷售流水帳。該流水帳的每一行對應(yīng)著一次售貨,記錄著所售出的商品名稱和售出時(shí)間。
– 7、仿真結(jié)束時(shí),應(yīng)自動(dòng)產(chǎn)生銷售報(bào)表。該報(bào)表應(yīng)給出本次模擬過程中:每種商品的銷售總量與價(jià)值合計(jì);所有售出商品的價(jià)值總計(jì);每種商品的庫存量;模擬開始、結(jié)束時(shí)各自的庫存金額;管理人員每次加貨的時(shí)間、各商品加貨量、取走的硬幣總額。
二、程序設(shè)計(jì)過程
1. 從實(shí)際問題中抽象類
仿真過程關(guān)注的事物有:VM,商品(Goods),顧客(Customer),管理員(Administrator)。
程序設(shè)計(jì)過程中考慮過以下問題:
① 管理員類建立的必要性。若不設(shè)計(jì)管理員類,而是在VM類中設(shè)兩變量TS,TM,VM自動(dòng)計(jì)時(shí),到時(shí)間后自動(dòng)加貨,可實(shí)現(xiàn)同樣輸出。從程序外觀上看管理員類的建立與否沒有影響。而考慮到自動(dòng)加貨并不是VM的本身屬性,而是通過與管理員通信完成的,故建立管理員類。在VM中建立響應(yīng)管理員加貨的方法,而管理員的內(nèi)部實(shí)現(xiàn)也正是調(diào)用了VM的此方法。
② 商品基類建立的必要性。曾考慮過將Goods類設(shè)計(jì)為虛基類,提供所有商品的共有接口,再從這個(gè)虛基類派生處各具體商品,最后運(yùn)用多態(tài)性原理設(shè)計(jì)實(shí)現(xiàn)細(xì)節(jié)。考慮到這個(gè)問題中各商品所不同的地方只是商品名,價(jià)格等數(shù)據(jù)成員不同,類內(nèi)部方法完全相同。且此程序中一個(gè)Goods對象代表一組同種商品,即找不到一個(gè)個(gè)單獨(dú)的商品。在電梯程序中每個(gè)乘客有不同的屬性:起始與終止樓層,而這正是程序關(guān)系的特征,故建立了一個(gè)個(gè)具體的乘客對象。此問題中我們關(guān)系的只是商品的數(shù)量,故沒有一個(gè)個(gè)單獨(dú)的商品對象。
2. 三個(gè)類之間的關(guān)系
此程序中關(guān)鍵是要處理各對象之間的通信。采用以下方法解決:
① VM與顧客之間的通信:顧客有兩種操作,即投幣與按按鈕。在VM中建立響應(yīng)這兩種操作的函數(shù),顧客類中的兩種操作內(nèi)部實(shí)質(zhì)是調(diào)用VM中的響應(yīng)函數(shù)。只需向顧客的操作函數(shù)中傳遞一VM的指針即可實(shí)現(xiàn)兩者之間的通信。
② VM與管理員的通信:因VM管理員之間的通信存在時(shí)間差,即VM發(fā)出的信息需經(jīng)TM后才能傳遞到管理員,故①中方法不再適用。采用一全局變量(CallAdmTimeLeft)來記錄信息還需多長時(shí)間才能到達(dá)管理員,其值為-1表示VM為發(fā)出請求或上一個(gè)請求已被處理,值為0則通知管理員。這樣便可通過主函數(shù)完成消息的傳遞。
4.類的設(shè)計(jì)
1) “Pbulic,h”中聲明定義了各類共享的一些數(shù)據(jù)類型及運(yùn)行時(shí)需要的一些參數(shù)。
類型:
enum Coin{FIVE=5,TEN=10,TWFIVE=25}:硬幣的種類
typedef unsigned int ID:VM編號的類型
typedef int PRICE:價(jià)格,現(xiàn)金的類型,單位為美分
typedef int TIME:時(shí)間的類型
運(yùn)行時(shí)所需的參數(shù),集中放置方便修改
const int COINKINDS:硬幣種類數(shù)目
const int COINMAX:產(chǎn)生顧客時(shí),其擁有的硬幣數(shù)目的最大值
const int WAITTIME:顧客兩次操作間最長時(shí)間間隔
const int CREATEMAX:一次交易結(jié)束后產(chǎn)生下一顧客的最大間隔時(shí)間
const int TMMAX:TM的最大值
const int TSMAX=5:TS的最大值
const int THEID:VM的編號
const int RUNTIME:運(yùn)行的最大時(shí)間
2) 商品(Goods)類的設(shè)計(jì)
變量/函數(shù) 成員 作用
私有 string name 標(biāo)示商品名稱
PRICE price 標(biāo)示商品價(jià)格
int maxNum 售貨機(jī)中該商品的最大容量
int leftNum 記錄售貨機(jī)中該商品的剩余量
int allSold 記錄該商品的銷售量
Goods(const Goods&) 防止按值傳遞
const Goods& operator=(const Goods&) 防止按值傳遞
公有 Goods(string ,PRICE ,int ,int ) 構(gòu)造函數(shù)
getName() 返回商品名稱
getPrice() 返回商品價(jià)格
getLeftNum() 返回剩余數(shù)量
getAllSold() 返回銷售量
setMax() 將商品數(shù)量沖至最大值
sellOne() 銷售一件商品時(shí)應(yīng)執(zhí)行的操作
3) 顧客(Customer)類的設(shè)計(jì)
變量/函數(shù) 成員
作用
私有 string goodsWanted 標(biāo)示所需商品
vector money 投幣順序,建立對象時(shí)初始化
PRICE alreadyInsert 已投的金額,用于與商品價(jià)格比較,判斷是否按按鈕
PRICE moneyLeft 記錄當(dāng)前剩余金額
int timeleft 記錄產(chǎn)生下一投幣動(dòng)作或按按鈕動(dòng)作還剩的時(shí)間
Customer(const Customer&) 防止按值傳遞
const Customer& operator=(const Customer&) 防止按值傳遞
setTimeLeft() 設(shè)置產(chǎn)生下一投幣動(dòng)作或按按鈕動(dòng)作還剩的時(shí)間
setMoneyLeft() 及時(shí)更新moneyLeft
公有 Customer(vector) 構(gòu)造函數(shù)
insert(VM*) 處理投幣行為
pressButton(VM*) 處理按按鈕行為
oneSecondPast(VM* ) 程序每運(yùn)行一秒顧客的更新,返回是否交易結(jié)束
Insert函數(shù)和pressButton函數(shù)的實(shí)現(xiàn)主要是調(diào)用VM的相應(yīng)相應(yīng)函數(shù)。
onSecondPast函數(shù)實(shí)現(xiàn)如下:
4) 管理員(Administrator)類的設(shè)計(jì)
變量/函數(shù) 成員 作用
私有 TIME timeLeft 到達(dá)VM剩余的時(shí)間,值為-1表示還未收到信息,空閑
VM* pVM 目標(biāo)VM
公有 Administrator() 構(gòu)造函數(shù)
onCall(VM* theVM) 收到請求時(shí)的操作
setMax() 為VM補(bǔ)充貨物
oneSecondPast() 程序每運(yùn)行一秒管理員的更新
5)VM類的設(shè)計(jì)
變量/函數(shù) 成員 作用
私有 ID id 編號
vector
總結(jié)
- 上一篇: gpt linux双系统安装win7系统
- 下一篇: 虚幻引擎图文笔记:游戏运行时如何显示鼠标